Compare commits
425 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
27c62bba99 | ||
|
|
93e053a122 | ||
|
|
eb022f4cc1 | ||
|
|
83542034dd | ||
|
|
627382f702 | ||
|
|
2eb563b3bb | ||
|
|
54a23f14d5 | ||
|
|
e8059b74f8 | ||
|
|
075909520a | ||
|
|
808bf12cd5 | ||
|
|
0f39f41317 | ||
|
|
f23b7ae3e9 | ||
|
|
5e4b09fc22 | ||
|
|
25ab7841b7 | ||
|
|
0c0e575379 | ||
|
|
68946bffae | ||
|
|
2fc461d9ab | ||
|
|
59a48d9ebb | ||
|
|
533d1ea20c | ||
|
|
dca1ca1d07 | ||
|
|
20a3907e86 | ||
|
|
7358e5748d | ||
|
|
a1b64db942 | ||
|
|
4d44f2d248 | ||
|
|
67abbcf269 | ||
|
|
6b819a9032 | ||
|
|
2021a8aedb | ||
|
|
58dc175ae3 | ||
|
|
4ad6763956 | ||
|
|
702826b850 | ||
|
|
8d30a1f74b | ||
|
|
1a988ba835 | ||
|
|
c422f852a6 | ||
|
|
bcacdb3352 | ||
|
|
cd61567de8 | ||
|
|
5c48c3c57a | ||
|
|
7692ccc0cc | ||
|
|
17cc7e85e2 | ||
|
|
96b3e1d0fa | ||
|
|
dc3cfcbe69 | ||
|
|
1ca1f80eac | ||
|
|
afe2b437bc | ||
|
|
dff71c1aa9 | ||
|
|
7f9a025e30 | ||
|
|
a0ac284a11 | ||
|
|
5341036261 | ||
|
|
46a6cab307 | ||
|
|
edb17d1aac | ||
|
|
dd05e96066 | ||
|
|
ed0878ca23 | ||
|
|
54c222be26 | ||
|
|
80d139297a | ||
|
|
8e6459f616 | ||
|
|
ba909cb692 | ||
|
|
96b964f7fa | ||
|
|
7bbab2f1d5 | ||
|
|
e5f3af4abe | ||
|
|
452538c6b0 | ||
|
|
5c828724f3 | ||
|
|
6538dd24bb | ||
|
|
996abe1ea5 | ||
|
|
f421e0c3d1 | ||
|
|
e4eaca5f9b | ||
|
|
ef5925fa18 | ||
|
|
bae48a9394 | ||
|
|
c813ed44d8 | ||
|
|
885bec68bd | ||
|
|
b553a05db3 | ||
|
|
5473c4f8cc | ||
|
|
0d73f81fb5 | ||
|
|
66c204b983 | ||
|
|
afb0600621 | ||
|
|
a13f2c6985 | ||
|
|
17c7ef06ba | ||
|
|
4933ce49b6 | ||
|
|
5cec1fa50a | ||
|
|
debd83b06a | ||
|
|
f01618ad1a | ||
|
|
cfc1dba99b | ||
|
|
529a3f2400 | ||
|
|
7c1abc5225 | ||
|
|
ca22b5e2f0 | ||
|
|
9ec74f2098 | ||
|
|
cb4ae39cb9 | ||
|
|
802488814f | ||
|
|
53aa48b42c | ||
|
|
b33801f854 | ||
|
|
fc88ce0615 | ||
|
|
28daec7f4e | ||
|
|
f25efa291d | ||
|
|
5ed0559cf2 | ||
|
|
8c1e549c12 | ||
|
|
796334c5ff | ||
|
|
2e1c2e1261 | ||
|
|
a896aac4bd | ||
|
|
80030d3f15 | ||
|
|
4eba4a37ed | ||
|
|
dd0858e204 | ||
|
|
25fa6ee699 | ||
|
|
84dfffe0aa | ||
|
|
aba803c447 | ||
|
|
79aae63aff | ||
|
|
59e93b8ee3 | ||
|
|
e0e63f312f | ||
|
|
d453372f4e | ||
|
|
0f5a77c5bd | ||
|
|
0c96d7ea5c | ||
|
|
4b947cd6d3 | ||
|
|
ca586ca809 | ||
|
|
880358f46b | ||
|
|
3393babb7d | ||
|
|
c3ae90c067 | ||
|
|
25983f20a0 | ||
|
|
1441758bc6 | ||
|
|
c7bbeb4490 | ||
|
|
6145f90423 | ||
|
|
2e397d1514 | ||
|
|
a5d0a29dd9 | ||
|
|
de843fd0a8 | ||
|
|
ced4eeddcf | ||
|
|
093910e90e | ||
|
|
37685ec1b4 | ||
|
|
ccd7d35b3f | ||
|
|
de7e0d7e52 | ||
|
|
89ee03a24d | ||
|
|
79d1d3ca55 | ||
|
|
675c208c7e | ||
|
|
b3307850ab | ||
|
|
eaa840dbd9 | ||
|
|
f64089fa6c | ||
|
|
5157d2023d | ||
|
|
2cd927bb14 | ||
|
|
2889961622 | ||
|
|
232f59749e | ||
|
|
d368a10cc7 | ||
|
|
139b848774 | ||
|
|
74a5226af5 | ||
|
|
c7ddc7a633 | ||
|
|
265707d21c | ||
|
|
eb39d1c4d4 | ||
|
|
1197d48fc7 | ||
|
|
23e1a55ed5 | ||
|
|
ba2a539603 | ||
|
|
8a8093d8dd | ||
|
|
3fb0103452 | ||
|
|
aeefdaedc7 | ||
|
|
756d1f917f | ||
|
|
6fa3dffad2 | ||
|
|
123e781cb3 | ||
|
|
ed9bf5b0c6 | ||
|
|
dd4e39ca1d | ||
|
|
5a551b074b | ||
|
|
c1a9355865 | ||
|
|
3ea6c25fb6 | ||
|
|
2d3135448c | ||
|
|
36a99af37c | ||
|
|
2aefd15913 | ||
|
|
6bc55b1086 | ||
|
|
7058ce2c70 | ||
|
|
8e111e9018 | ||
|
|
d8bd7ca436 | ||
|
|
392f73a000 | ||
|
|
67efbaf33b | ||
|
|
0d06740148 | ||
|
|
eda6947a22 | ||
|
|
f331173145 | ||
|
|
a666cd9e1f | ||
|
|
2657aa6987 | ||
|
|
6610cd2332 | ||
|
|
0c8b44d514 | ||
|
|
ec46ff4445 | ||
|
|
db891880e6 | ||
|
|
9c433e8c50 | ||
|
|
5141863ae3 | ||
|
|
d23550dea5 | ||
|
|
c3b12510ae | ||
|
|
b2685e3671 | ||
|
|
601d2ddbf3 | ||
|
|
a5e8fe70af | ||
|
|
9b3a96aa81 | ||
|
|
d674e815bd | ||
|
|
c2e696d686 | ||
|
|
411dbb8df4 | ||
|
|
b22dfbbf15 | ||
|
|
4c39a3fdbf | ||
|
|
f3eb366f24 | ||
|
|
a20d1b8f6b | ||
|
|
0a51289332 | ||
|
|
97ebfb00b4 | ||
|
|
c7d664f9d0 | ||
|
|
c2fbaaa95d | ||
|
|
84d4b390f1 | ||
|
|
54e59099b7 | ||
|
|
d9585ba37e | ||
|
|
45c617b5c3 | ||
|
|
4b0c78c64f | ||
|
|
dd36e23a62 | ||
|
|
e2dade05d9 | ||
|
|
fbd61106cb | ||
|
|
67e66a2d34 | ||
|
|
59911963ca | ||
|
|
dc2a4a6ccd | ||
|
|
81fb0b4f07 | ||
|
|
a06c8fb7b2 | ||
|
|
05e70f76a9 | ||
|
|
b9f4836d3e | ||
|
|
ef77dc932b | ||
|
|
bd5b1d4d48 | ||
|
|
5c2ffa260c | ||
|
|
23d04fa25c | ||
|
|
67dbce4512 | ||
|
|
46170fd0d8 | ||
|
|
f85a453dc8 | ||
|
|
bcfe48e05b | ||
|
|
722ca250ea | ||
|
|
f4df128e52 | ||
|
|
8cc5322b39 | ||
|
|
1480845597 | ||
|
|
c877e73463 | ||
|
|
3ce5e8eb6c | ||
|
|
e6b12e1f9d | ||
|
|
bfbbd4ccba | ||
|
|
fec7016665 | ||
|
|
47fe6170b2 | ||
|
|
24b5fb8523 | ||
|
|
e8cd9688ce | ||
|
|
fa952f6d35 | ||
|
|
df55fd69af | ||
|
|
019fc4c1f2 | ||
|
|
22ea441feb | ||
|
|
9f5b33e52e | ||
|
|
92837c4f89 | ||
|
|
68ce06f40f | ||
|
|
279b31c75b | ||
|
|
3117b3cd88 | ||
|
|
9b547f76e7 | ||
|
|
3d6675784a | ||
|
|
26f50eadd1 | ||
|
|
6e8496ffc5 | ||
|
|
88d6c4ec0e | ||
|
|
135eeb45d6 | ||
|
|
54ee59c0bb | ||
|
|
4a5c61a33d | ||
|
|
179c0f5f56 | ||
|
|
4dbf937707 | ||
|
|
9edb57e5e9 | ||
|
|
4d15ad63bf | ||
|
|
4021709371 | ||
|
|
3c13f5c3aa | ||
|
|
381517b451 | ||
|
|
6ecf36d49c | ||
|
|
64eb4b8408 | ||
|
|
318da3fdcd | ||
|
|
50c99fcda6 | ||
|
|
321de1f263 | ||
|
|
fa30ace67d | ||
|
|
92baa79253 | ||
|
|
e861b45313 | ||
|
|
cf91ac68b6 | ||
|
|
d4aba13526 | ||
|
|
d36c7c3782 | ||
|
|
4385fcdeae | ||
|
|
04eb170624 | ||
|
|
4803686078 | ||
|
|
20b0fda3bb | ||
|
|
4e5f823595 | ||
|
|
a74408d1d2 | ||
|
|
8206537efd | ||
|
|
a9a77bb3ab | ||
|
|
6390de689d | ||
|
|
41ce19836b | ||
|
|
883a4f6fff | ||
|
|
5f1da80fc1 | ||
|
|
64217d67f6 | ||
|
|
b01c79354c | ||
|
|
9ecbcb787c | ||
|
|
e17e376b04 | ||
|
|
1b4ea4f178 | ||
|
|
1de29fb362 | ||
|
|
7e4bd492fd | ||
|
|
588d56503d | ||
|
|
e9602656f8 | ||
|
|
0116d418f0 | ||
|
|
9992974c66 | ||
|
|
ba27d8a389 | ||
|
|
f96e985763 | ||
|
|
5b9eaae50d | ||
|
|
74a13f7e3b | ||
|
|
3e88fc8aad | ||
|
|
881740d702 | ||
|
|
9a643a1bb9 | ||
|
|
a5488650ff | ||
|
|
a275127a65 | ||
|
|
02db31db6a | ||
|
|
8bd813e6fc | ||
|
|
09ff121654 | ||
|
|
0434758a0d | ||
|
|
8bb0a71083 | ||
|
|
d7651a389e | ||
|
|
824318a0c1 | ||
|
|
5e9ed22e84 | ||
|
|
a6c611e7c9 | ||
|
|
72b325f8b5 | ||
|
|
54d0514b13 | ||
|
|
58b1c3cec0 | ||
|
|
71641523a3 | ||
|
|
94c5e25c3b | ||
|
|
20bad0aa6c | ||
|
|
e7f23a6218 | ||
|
|
25c29db8b6 | ||
|
|
1750fba9ce | ||
|
|
b18e410586 | ||
|
|
38d5e1fab3 | ||
|
|
4180c32eb1 | ||
|
|
5115229fdf | ||
|
|
e8f2d814e7 | ||
|
|
1fda8c5a86 | ||
|
|
6b77b55d40 | ||
|
|
82cdb08c1f | ||
|
|
b48b0b1e58 | ||
|
|
f9066e7d86 | ||
|
|
dafcb3bcd7 | ||
|
|
7b5e42c744 | ||
|
|
bafef292f4 | ||
|
|
9e6ffe7798 | ||
|
|
84735b644c | ||
|
|
f67f37074f | ||
|
|
fe229f10e6 | ||
|
|
0b9f4d7e74 | ||
|
|
f034958bdc | ||
|
|
90ea00a109 | ||
|
|
9ed4245d9e | ||
|
|
1dfc990264 | ||
|
|
5d31267185 | ||
|
|
cf9b3e7708 | ||
|
|
1c533eb520 | ||
|
|
5397a6d4c6 | ||
|
|
76f411147d | ||
|
|
15ce73caca | ||
|
|
a27e5a9c95 | ||
|
|
daee2eda93 | ||
|
|
a15b00d3ef | ||
|
|
1b906ef2ad | ||
|
|
68a4ef5ef6 | ||
|
|
90dc5f47e7 | ||
|
|
19d271d3fc | ||
|
|
3259b1d1e0 | ||
|
|
4a329098e8 | ||
|
|
512910a51f | ||
|
|
99b9c1a9d5 | ||
|
|
fdda57cf10 | ||
|
|
ec8e34950d | ||
|
|
93964ef3a4 | ||
|
|
5c8af6a136 | ||
|
|
1c3ee5d1ce | ||
|
|
b489c85226 | ||
|
|
dcea23906b | ||
|
|
20c65ac438 | ||
|
|
4d0c8aca05 | ||
|
|
8fc16ece96 | ||
|
|
fcbb375e8f | ||
|
|
49c65279fa | ||
|
|
86e8a56fe1 | ||
|
|
b199330682 | ||
|
|
7a7ebaebd1 | ||
|
|
164ae0b24b | ||
|
|
bcb9577495 | ||
|
|
d22715126c | ||
|
|
a114367b9b | ||
|
|
7156545fca | ||
|
|
2ffc055f7e | ||
|
|
14e9bf894c | ||
|
|
f4cd35322f | ||
|
|
7bdcf9eb26 | ||
|
|
9846a1e56e | ||
|
|
4cc97df8f3 | ||
|
|
0ef64fbe03 | ||
|
|
fbccff4994 | ||
|
|
84184708de | ||
|
|
8f8b478d36 | ||
|
|
b817c337dc | ||
|
|
d03e878d53 | ||
|
|
b313d16493 | ||
|
|
784263f5e3 | ||
|
|
6baa13ab7a | ||
|
|
0e16e0fb6a | ||
|
|
ba98d6fffe | ||
|
|
73a5abf4d9 | ||
|
|
630c8dc828 | ||
|
|
972f73ed2b | ||
|
|
6de89246c2 | ||
|
|
c5ff37bf3e | ||
|
|
6b867773a8 | ||
|
|
96973a5778 | ||
|
|
912aac3447 | ||
|
|
4486b7d8e8 | ||
|
|
1267094a51 | ||
|
|
2b842958cc | ||
|
|
80ec2ac167 | ||
|
|
df960d5767 | ||
|
|
c0760f9f91 | ||
|
|
c906128191 | ||
|
|
96843f2b17 | ||
|
|
f574d3c8fc | ||
|
|
ebe5e1731d | ||
|
|
2ebb421331 | ||
|
|
a9e8bd59a3 | ||
|
|
4589ce61bc | ||
|
|
33e66107be | ||
|
|
db90dea9bd | ||
|
|
04544b4510 | ||
|
|
0b17a66e68 | ||
|
|
04986bbb15 | ||
|
|
b0d02adeee | ||
|
|
48b962c401 | ||
|
|
04a195266b | ||
|
|
21393af631 | ||
|
|
189c67db95 | ||
|
|
b92b9228ef | ||
|
|
f49897a419 | ||
|
|
aab30f5e67 | ||
|
|
e7fd732209 | ||
|
|
8a36f54cf4 | ||
|
|
1a14e660d2 | ||
|
|
2502aae5db |
@@ -2,13 +2,37 @@
|
||||
<!-- please leave the top comment for us emacs folks -->
|
||||
<property name="nunitcmd" value="nunit-console" />
|
||||
|
||||
<!-- For safety/laziness sake, we're going to take the approach of deleting known extraneous files here rather than
|
||||
trying to copy across only the essential ones -->
|
||||
<property name="distbindir" value="distbin" />
|
||||
<target name="distbin">
|
||||
<!-- This target produces a source distribution of OpenSimulator -->
|
||||
<!-- TODO: A few parameters still need to be tweaked after running this - need to do this automatically with sed or similar -->
|
||||
<target name="distsrc">
|
||||
<copy file="bin/OpenSim.ini.example" tofile="bin/OpenSim.ini"/>
|
||||
<copy file="bin/config-include/StandaloneCommon.ini.example" tofile="bin/config-include/StandaloneCommon.ini"/>
|
||||
<copy file="bin/config-include/FlotsamCache.ini.example" tofile="bin/config-include/FlotsamCache.ini"/>
|
||||
<!-- delete files generated by runprebuild.sh which had to be run in order to generate the build file for this target-->
|
||||
<delete>
|
||||
<fileset basedir="OpenSim">
|
||||
<include name="**/*.build"/>
|
||||
<include name="**/*.csproj*"/>
|
||||
<include name="**/*.dll.build"/>
|
||||
<include name="**/*.pidb"/>
|
||||
<exclude name="Tools/OpenSim.32BitLaunch/**"/>
|
||||
<exclude name="Tools/Robust.32BitLaunch/**"/>
|
||||
<exclude name="Tools/LaunchSLClient/**"/>
|
||||
</fileset>
|
||||
</delete>
|
||||
<delete>
|
||||
<fileset>
|
||||
<include name="OpenSim.build"/>
|
||||
<include name="OpenSim.sln"/>
|
||||
</fileset>
|
||||
</delete>
|
||||
</target>
|
||||
|
||||
<property name="distbindir" value="distbin" />
|
||||
<!-- This target produces a binary directory called distbin/ in OpenSim/bin which contains everything needed for binary distribution -->
|
||||
<!-- For safety/laziness sake, we're going to take the approach of deleting known extraneous files here rather than
|
||||
trying to copy across only the essential ones -->
|
||||
<target name="distbin">
|
||||
<delete dir="${distbindir}"/>
|
||||
<copy todir="${distbindir}">
|
||||
<fileset>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
The following people have contributed to OpenSim (Thank you
|
||||
<<<>>>>The following people have contributed to OpenSim (Thank you
|
||||
for your effort!)
|
||||
|
||||
= Current OpenSim Developers (in very rough order of appearance) =
|
||||
@@ -139,6 +139,9 @@ what it is today.
|
||||
* SignpostMarv
|
||||
* SpotOn3D
|
||||
* Strawberry Fride
|
||||
* Talun
|
||||
* TechplexEngineer (Blake Bourque)
|
||||
* TBG Renfold
|
||||
* tglion
|
||||
* tlaukkan/Tommil (Tommi S. E. Laukkanen, Bubble Cloud)
|
||||
* tyre
|
||||
|
||||
@@ -63,7 +63,8 @@ namespace OpenSim.Capabilities.Handlers
|
||||
|
||||
FetchInventory2Handler fiHandler = new FetchInventory2Handler(m_InventoryService);
|
||||
IRequestHandler reqHandler
|
||||
= new RestStreamHandler("POST", "/CAPS/FetchInventory/", fiHandler.FetchInventoryRequest);
|
||||
= new RestStreamHandler(
|
||||
"POST", "/CAPS/FetchInventory/", fiHandler.FetchInventoryRequest, "FetchInventory", null);
|
||||
server.AddStreamHandler(reqHandler);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,13 +66,14 @@ namespace OpenSim.Capabilities.Handlers
|
||||
throw new Exception(String.Format("Failed to load AssetService from {0}; config is {1}", assetService, m_ConfigName));
|
||||
|
||||
GetMeshHandler gmeshHandler = new GetMeshHandler(m_AssetService);
|
||||
IRequestHandler reqHandler = new RestHTTPHandler("GET", "/CAPS/" + UUID.Random(),
|
||||
delegate(Hashtable m_dhttpMethod)
|
||||
{
|
||||
return gmeshHandler.ProcessGetMesh(m_dhttpMethod, UUID.Zero, null);
|
||||
});
|
||||
IRequestHandler reqHandler
|
||||
= new RestHTTPHandler(
|
||||
"GET",
|
||||
"/CAPS/" + UUID.Random(),
|
||||
httpMethod => gmeshHandler.ProcessGetMesh(httpMethod, UUID.Zero, null),
|
||||
"GetMesh",
|
||||
null);
|
||||
server.AddStreamHandler(reqHandler);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -58,8 +58,8 @@ namespace OpenSim.Capabilities.Handlers
|
||||
// TODO: Change this to a config option
|
||||
const string REDIRECT_URL = null;
|
||||
|
||||
public GetTextureHandler(string path, IAssetService assService) :
|
||||
base("GET", path)
|
||||
public GetTextureHandler(string path, IAssetService assService, string name, string description)
|
||||
: base("GET", path, name, description)
|
||||
{
|
||||
m_assetService = assService;
|
||||
}
|
||||
|
||||
@@ -62,8 +62,8 @@ namespace OpenSim.Capabilities.Handlers
|
||||
if (m_AssetService == null)
|
||||
throw new Exception(String.Format("Failed to load AssetService from {0}; config is {1}", assetService, m_ConfigName));
|
||||
|
||||
server.AddStreamHandler(new GetTextureHandler("/CAPS/GetTexture/" /*+ UUID.Random() */, m_AssetService));
|
||||
server.AddStreamHandler(
|
||||
new GetTextureHandler("/CAPS/GetTexture/" /*+ UUID.Random() */, m_AssetService, "GetTexture", null));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -50,9 +50,9 @@ namespace OpenSim.Capabilities.Handlers.GetTexture.Tests
|
||||
TestHelpers.InMethod();
|
||||
|
||||
// Overkill - we only really need the asset service, not a whole scene.
|
||||
Scene scene = SceneHelpers.SetupScene();
|
||||
Scene scene = new SceneHelpers().SetupScene();
|
||||
|
||||
GetTextureHandler handler = new GetTextureHandler(null, scene.AssetService);
|
||||
GetTextureHandler handler = new GetTextureHandler(null, scene.AssetService, "TestGetTexture", null);
|
||||
TestOSHttpRequest req = new TestOSHttpRequest();
|
||||
TestOSHttpResponse resp = new TestOSHttpResponse();
|
||||
req.Url = new Uri("http://localhost/?texture_id=00000000-0000-1111-9999-000000000012");
|
||||
|
||||
@@ -85,8 +85,8 @@ namespace OpenSim.Capabilities.Handlers
|
||||
uploader.OnUpLoad += BakedTextureUploaded;
|
||||
|
||||
m_HostCapsObj.HttpListener.AddStreamHandler(
|
||||
new BinaryStreamHandler("POST", capsBase + uploaderPath,
|
||||
uploader.uploaderCaps));
|
||||
new BinaryStreamHandler(
|
||||
"POST", capsBase + uploaderPath, uploader.uploaderCaps, "UploadBakedTexture", null));
|
||||
|
||||
string protocol = "http://";
|
||||
|
||||
|
||||
@@ -68,7 +68,13 @@ namespace OpenSim.Capabilities.Handlers
|
||||
ServerUtils.LoadPlugin<ILibraryService>(libService, args);
|
||||
|
||||
WebFetchInvDescHandler webFetchHandler = new WebFetchInvDescHandler(m_InventoryService, m_LibraryService);
|
||||
IRequestHandler reqHandler = new RestStreamHandler("POST", "/CAPS/WebFetchInvDesc/" /*+ UUID.Random()*/, webFetchHandler.FetchInventoryDescendentsRequest);
|
||||
IRequestHandler reqHandler
|
||||
= new RestStreamHandler(
|
||||
"POST",
|
||||
"/CAPS/WebFetchInvDesc/" /*+ UUID.Random()*/,
|
||||
webFetchHandler.FetchInventoryDescendentsRequest,
|
||||
"WebFetchInvDesc",
|
||||
null);
|
||||
server.AddStreamHandler(reqHandler);
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,11 @@ namespace OpenSim.Framework.Capabilities
|
||||
private LLSDMethod<TRequest, TResponse> m_method;
|
||||
|
||||
public LLSDStreamhandler(string httpMethod, string path, LLSDMethod<TRequest, TResponse> method)
|
||||
: base(httpMethod, path)
|
||||
: this(httpMethod, path, method, null, null) {}
|
||||
|
||||
public LLSDStreamhandler(
|
||||
string httpMethod, string path, LLSDMethod<TRequest, TResponse> method, string name, string description)
|
||||
: base(httpMethod, path, name, description)
|
||||
{
|
||||
m_method = method;
|
||||
}
|
||||
|
||||
@@ -89,5 +89,11 @@ namespace OpenSim.Data.MSSQL
|
||||
return DoQuery(cmd);
|
||||
}
|
||||
}
|
||||
|
||||
public FriendsData[] GetFriends(Guid principalID)
|
||||
{
|
||||
return GetFriends(principalID.ToString());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -813,7 +813,7 @@ namespace OpenSim.Data.MSSQL
|
||||
{
|
||||
try
|
||||
{
|
||||
using (SqlCommand command = new SqlCommand("DELETE FROM inventoryfolders WHERE folderID=@folderID", connection))
|
||||
using (SqlCommand command = new SqlCommand("DELETE FROM inventoryfolders WHERE folderID=@folderID and type=-1", connection))
|
||||
{
|
||||
command.Parameters.Add(database.CreateParameter("folderID", folderID));
|
||||
|
||||
|
||||
@@ -675,7 +675,7 @@ VALUES
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
sql = "INSERT INTO [landaccesslist] ([LandUUID],[AccessUUID],[Flags]) VALUES (@LandUUID,@AccessUUID,@Flags)";
|
||||
sql = "INSERT INTO [landaccesslist] ([LandUUID],[AccessUUID],[Flags],[Expires]) VALUES (@LandUUID,@AccessUUID,@Flags,@Expires)";
|
||||
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
@@ -1215,6 +1215,8 @@ VALUES
|
||||
//Store new values
|
||||
StoreNewRegionSettings(regionSettings);
|
||||
|
||||
LoadSpawnPoints(regionSettings);
|
||||
|
||||
return regionSettings;
|
||||
}
|
||||
|
||||
@@ -1252,7 +1254,7 @@ VALUES
|
||||
,[elevation_1_ne] = @elevation_1_ne ,[elevation_2_ne] = @elevation_2_ne ,[elevation_1_se] = @elevation_1_se ,[elevation_2_se] = @elevation_2_se
|
||||
,[elevation_1_sw] = @elevation_1_sw ,[elevation_2_sw] = @elevation_2_sw ,[water_height] = @water_height ,[terrain_raise_limit] = @terrain_raise_limit
|
||||
,[terrain_lower_limit] = @terrain_lower_limit ,[use_estate_sun] = @use_estate_sun ,[fixed_sun] = @fixed_sun ,[sun_position] = @sun_position
|
||||
,[covenant] = @covenant ,[covenant_datetime] = @covenant_datetime, [sunvectorx] = @sunvectorx, [sunvectory] = @sunvectory, [sunvectorz] = @sunvectorz, [Sandbox] = @Sandbox, [loaded_creation_datetime] = @loaded_creation_datetime, [loaded_creation_id] = @loaded_creation_id
|
||||
,[covenant] = @covenant ,[covenant_datetime] = @covenant_datetime, [sunvectorx] = @sunvectorx, [sunvectory] = @sunvectory, [sunvectorz] = @sunvectorz, [Sandbox] = @Sandbox, [loaded_creation_datetime] = @loaded_creation_datetime, [loaded_creation_id] = @loaded_creation_id, [map_tile_id] = @TerrainImageID, [telehubobject] = @telehubobject, [parcel_tile_id] = @ParcelImageID
|
||||
WHERE [regionUUID] = @regionUUID";
|
||||
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
@@ -1263,6 +1265,7 @@ VALUES
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
SaveSpawnPoints(regionSettings);
|
||||
}
|
||||
|
||||
public void Shutdown()
|
||||
@@ -1383,6 +1386,11 @@ VALUES
|
||||
newSettings.LoadedCreationID = "";
|
||||
else
|
||||
newSettings.LoadedCreationID = (String)row["loaded_creation_id"];
|
||||
|
||||
newSettings.TerrainImageID = new UUID((string)row["map_tile_ID"]);
|
||||
newSettings.ParcelImageID = new UUID((Guid)row["parcel_tile_ID"]);
|
||||
newSettings.TelehubObject = new UUID((Guid)row["TelehubObject"]);
|
||||
|
||||
return newSettings;
|
||||
}
|
||||
|
||||
@@ -1454,6 +1462,13 @@ VALUES
|
||||
}
|
||||
|
||||
newData.ParcelAccessList = new List<LandAccessEntry>();
|
||||
newData.MediaDescription = (string)row["MediaDescription"];
|
||||
newData.MediaType = (string)row["MediaType"];
|
||||
newData.MediaWidth = Convert.ToInt32((((string)row["MediaSize"]).Split(','))[0]);
|
||||
newData.MediaHeight = Convert.ToInt32((((string)row["MediaSize"]).Split(','))[1]);
|
||||
newData.MediaLoop = Convert.ToBoolean(row["MediaLoop"]);
|
||||
newData.ObscureMusic = Convert.ToBoolean(row["ObscureMusic"]);
|
||||
newData.ObscureMedia = Convert.ToBoolean(row["ObscureMedia"]);
|
||||
|
||||
return newData;
|
||||
}
|
||||
@@ -1468,7 +1483,7 @@ VALUES
|
||||
LandAccessEntry entry = new LandAccessEntry();
|
||||
entry.AgentID = new UUID((Guid)row["AccessUUID"]);
|
||||
entry.Flags = (AccessList)Convert.ToInt32(row["Flags"]);
|
||||
entry.Expires = 0;
|
||||
entry.Expires = Convert.ToInt32(row["Expires"]);
|
||||
return entry;
|
||||
}
|
||||
|
||||
@@ -1497,7 +1512,8 @@ VALUES
|
||||
prim.TouchName = (string)primRow["TouchName"];
|
||||
// permissions
|
||||
prim.Flags = (PrimFlags)Convert.ToUInt32(primRow["ObjectFlags"]);
|
||||
prim.CreatorID = new UUID((Guid)primRow["CreatorID"]);
|
||||
//prim.CreatorID = new UUID((Guid)primRow["CreatorID"]);
|
||||
prim.CreatorIdentification = (string)primRow["CreatorID"];
|
||||
prim.OwnerID = new UUID((Guid)primRow["OwnerID"]);
|
||||
prim.GroupID = new UUID((Guid)primRow["GroupID"]);
|
||||
prim.LastOwnerID = new UUID((Guid)primRow["LastOwnerID"]);
|
||||
@@ -1691,7 +1707,8 @@ VALUES
|
||||
taskItem.Name = (string)inventoryRow["name"];
|
||||
taskItem.Description = (string)inventoryRow["description"];
|
||||
taskItem.CreationDate = Convert.ToUInt32(inventoryRow["creationDate"]);
|
||||
taskItem.CreatorID = new UUID((Guid)inventoryRow["creatorID"]);
|
||||
//taskItem.CreatorID = new UUID((Guid)inventoryRow["creatorID"]);
|
||||
taskItem.CreatorIdentification = (string)inventoryRow["creatorID"];
|
||||
taskItem.OwnerID = new UUID((Guid)inventoryRow["ownerID"]);
|
||||
taskItem.LastOwnerID = new UUID((Guid)inventoryRow["lastOwnerID"]);
|
||||
taskItem.GroupID = new UUID((Guid)inventoryRow["groupID"]);
|
||||
@@ -1792,6 +1809,9 @@ VALUES
|
||||
parameters.Add(_Database.CreateParameter("covenant_datetime", settings.CovenantChangedDateTime));
|
||||
parameters.Add(_Database.CreateParameter("Loaded_Creation_DateTime", settings.LoadedCreationDateTime));
|
||||
parameters.Add(_Database.CreateParameter("Loaded_Creation_ID", settings.LoadedCreationID));
|
||||
parameters.Add(_Database.CreateParameter("TerrainImageID", settings.TerrainImageID));
|
||||
parameters.Add(_Database.CreateParameter("ParcelImageID", settings.ParcelImageID));
|
||||
parameters.Add(_Database.CreateParameter("TelehubObject", settings.TelehubObject));
|
||||
|
||||
return parameters.ToArray();
|
||||
}
|
||||
@@ -1859,6 +1879,7 @@ VALUES
|
||||
parameters.Add(_Database.CreateParameter("LandUUID", parcelID));
|
||||
parameters.Add(_Database.CreateParameter("AccessUUID", parcelAccessEntry.AgentID));
|
||||
parameters.Add(_Database.CreateParameter("Flags", parcelAccessEntry.Flags));
|
||||
parameters.Add(_Database.CreateParameter("Expires", parcelAccessEntry.Expires));
|
||||
|
||||
return parameters.ToArray();
|
||||
}
|
||||
@@ -2063,5 +2084,57 @@ VALUES
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
private void LoadSpawnPoints(RegionSettings rs)
|
||||
{
|
||||
rs.ClearSpawnPoints();
|
||||
|
||||
string sql = "SELECT Yaw, Pitch, Distance FROM spawn_points WHERE RegionUUID = @RegionUUID";
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", rs.RegionUUID.ToString()));
|
||||
conn.Open();
|
||||
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
if (reader.Read())
|
||||
{
|
||||
SpawnPoint sp = new SpawnPoint();
|
||||
|
||||
sp.Yaw = (float)reader["Yaw"];
|
||||
sp.Pitch = (float)reader["Pitch"];
|
||||
sp.Distance = (float)reader["Distance"];
|
||||
|
||||
rs.AddSpawnPoint(sp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SaveSpawnPoints(RegionSettings rs)
|
||||
{
|
||||
string sql = "DELETE FROM spawn_points WHERE RegionUUID = @RegionUUID";
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", rs.RegionUUID));
|
||||
conn.Open();
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
foreach (SpawnPoint p in rs.SpawnPoints())
|
||||
{
|
||||
sql = "INSERT INTO spawn_points (RegionUUID, Yaw, Pitch, Distance) VALUES (@RegionUUID, @Yaw, @Pitch, @Distance)";
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", rs.RegionUUID));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("@Yaw", p.Yaw));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("@Pitch", p.Pitch));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("@Distance", p.Distance));
|
||||
conn.Open();
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -235,4 +235,11 @@ CREATE NONCLUSTERED INDEX IX_regions_name ON dbo.regions
|
||||
regionName
|
||||
) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
|
||||
|
||||
COMMIT
|
||||
COMMIT
|
||||
|
||||
:VERSION 9
|
||||
|
||||
BEGIN TRANSACTION
|
||||
ALTER TABLE regions ADD parcelMapTexture uniqueidentifier NULL;
|
||||
|
||||
COMMIT
|
||||
|
||||
@@ -1044,10 +1044,93 @@ ALTER TABLE primitems ALTER COLUMN CreatorID uniqueidentifier NOT NULL
|
||||
|
||||
COMMIT
|
||||
|
||||
:VERSION 29 #---------------------
|
||||
:VERSION 29 #----------------- Region Covenant changed time
|
||||
|
||||
BEGIN TRANSACTION
|
||||
|
||||
ALTER TABLE regionsettings ADD covenant_datetime int NOT NULL default 0
|
||||
|
||||
COMMIT
|
||||
|
||||
:VERSION 30 #------------------Migrate creatorID storage to varchars instead of UUIDs for HG support
|
||||
|
||||
BEGIN TRANSACTION
|
||||
|
||||
EXECUTE sp_rename N'dbo.prims.creatorid', N'creatoridold', 'COLUMN'
|
||||
EXECUTE sp_rename N'dbo.primitems.creatorid', N'creatoridold', 'COLUMN'
|
||||
|
||||
COMMIT
|
||||
|
||||
:VERSION 31 #---------------------
|
||||
|
||||
BEGIN TRANSACTION
|
||||
|
||||
ALTER TABLE prims ADD CreatorID varchar(255)
|
||||
ALTER TABLE primitems ADD CreatorID varchar(255)
|
||||
|
||||
COMMIT
|
||||
|
||||
:VERSION 32 #---------------------
|
||||
|
||||
BEGIN TRANSACTION
|
||||
|
||||
UPDATE prims SET prims.CreatorID = CONVERT(varchar(255), creatoridold)
|
||||
UPDATE primitems SET primitems.CreatorID = CONVERT(varchar(255), creatoridold)
|
||||
|
||||
COMMIT
|
||||
|
||||
:VERSION 33 #---------------------
|
||||
|
||||
BEGIN TRANSACTION
|
||||
|
||||
ALTER TABLE prims
|
||||
ADD CONSTRAINT DF_prims_CreatorIDNew
|
||||
DEFAULT '00000000-0000-0000-0000-000000000000'
|
||||
FOR CreatorID
|
||||
|
||||
ALTER TABLE prims ALTER COLUMN CreatorID varchar(255) NOT NULL
|
||||
|
||||
ALTER TABLE primitems
|
||||
ADD CONSTRAINT DF_primitems_CreatorIDNew
|
||||
DEFAULT '00000000-0000-0000-0000-000000000000'
|
||||
FOR CreatorID
|
||||
|
||||
ALTER TABLE primitems ALTER COLUMN CreatorID varchar(255) NOT NULL
|
||||
|
||||
COMMIT
|
||||
|
||||
:VERSION 34 #--------------- Telehub support
|
||||
|
||||
BEGIN TRANSACTION
|
||||
|
||||
CREATE TABLE [dbo].[Spawn_Points](
|
||||
[RegionUUID] [uniqueidentifier] NOT NULL,
|
||||
[Yaw] [float] NOT NULL,
|
||||
[Pitch] [float] NOT NULL,
|
||||
[Distance] [float] NOT NULL,
|
||||
PRIMARY KEY CLUSTERED
|
||||
(
|
||||
[RegionUUID] ASC
|
||||
)WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
|
||||
) ON [PRIMARY]
|
||||
|
||||
ALTER TABLE regionsettings ADD TelehubObject uniqueidentifier NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000';
|
||||
|
||||
COMMIT
|
||||
|
||||
:VERSION 35 #---------------- Parcels for sale
|
||||
|
||||
BEGIN TRANSACTION
|
||||
|
||||
ALTER TABLE regionsettings ADD parcel_tile_ID uniqueidentifier NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000';
|
||||
|
||||
COMMIT
|
||||
|
||||
:VERSION 36 #---------------- Timed bans/access
|
||||
|
||||
BEGIN TRANSACTION
|
||||
|
||||
ALTER TABLE landaccesslist ADD Expires integer NOT NULL DEFAULT 0;
|
||||
|
||||
COMMIT
|
||||
|
||||
|
||||
@@ -28,6 +28,9 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using log4net;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Data;
|
||||
@@ -36,12 +39,26 @@ namespace OpenSim.Data.Null
|
||||
{
|
||||
public class NullFriendsData : IFriendsData
|
||||
{
|
||||
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private static List<FriendsData> m_Data = new List<FriendsData>();
|
||||
|
||||
public NullFriendsData(string connectionString, string realm)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clear all friends data
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is required by unit tests to clear the static data between test runs.
|
||||
/// </remarks>
|
||||
public static void Clear()
|
||||
{
|
||||
lock (m_Data)
|
||||
m_Data.Clear();
|
||||
}
|
||||
|
||||
public FriendsData[] GetFriends(UUID principalID)
|
||||
{
|
||||
return GetFriends(principalID.ToString());
|
||||
@@ -56,20 +73,30 @@ namespace OpenSim.Data.Null
|
||||
/// <returns></returns>
|
||||
public FriendsData[] GetFriends(string userID)
|
||||
{
|
||||
List<FriendsData> lst = m_Data.FindAll(fdata =>
|
||||
lock (m_Data)
|
||||
{
|
||||
return fdata.PrincipalID == userID.ToString();
|
||||
});
|
||||
|
||||
if (lst != null)
|
||||
{
|
||||
lst.ForEach(f =>
|
||||
List<FriendsData> lst = m_Data.FindAll(fdata =>
|
||||
{
|
||||
FriendsData f2 = m_Data.Find(candidateF2 => f.Friend == candidateF2.PrincipalID);
|
||||
if (f2 != null) { f.Data["TheirFlags"] = f2.Data["Flags"]; }
|
||||
return fdata.PrincipalID == userID.ToString();
|
||||
});
|
||||
|
||||
return lst.ToArray();
|
||||
|
||||
if (lst != null)
|
||||
{
|
||||
lst.ForEach(f =>
|
||||
{
|
||||
FriendsData f2 = m_Data.Find(candidateF2 => f.Friend == candidateF2.PrincipalID);
|
||||
if (f2 != null)
|
||||
f.Data["TheirFlags"] = f2.Data["Flags"];
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[NULL FRIENDS DATA]: Got {0} {1} {2} for {3}",
|
||||
// f.Friend, f.Data["Flags"], f2 != null ? f.Data["TheirFlags"] : "not found!", f.PrincipalID);
|
||||
});
|
||||
|
||||
// m_log.DebugFormat("[NULL FRIENDS DATA]: Got {0} friends for {1}", lst.Count, userID);
|
||||
|
||||
return lst.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
return new FriendsData[0];
|
||||
@@ -80,7 +107,11 @@ namespace OpenSim.Data.Null
|
||||
if (data == null)
|
||||
return false;
|
||||
|
||||
m_Data.Add(data);
|
||||
// m_log.DebugFormat(
|
||||
// "[NULL FRIENDS DATA]: Storing {0} {1} {2}", data.PrincipalID, data.Friend, data.Data["Flags"]);
|
||||
|
||||
lock (m_Data)
|
||||
m_Data.Add(data);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -92,14 +123,21 @@ namespace OpenSim.Data.Null
|
||||
|
||||
public bool Delete(string userID, string friendID)
|
||||
{
|
||||
List<FriendsData> lst = m_Data.FindAll(delegate(FriendsData fdata) { return fdata.PrincipalID == userID.ToString(); });
|
||||
if (lst != null)
|
||||
lock (m_Data)
|
||||
{
|
||||
FriendsData friend = lst.Find(delegate(FriendsData fdata) { return fdata.Friend == friendID; });
|
||||
if (friendID != null)
|
||||
List<FriendsData> lst = m_Data.FindAll(delegate(FriendsData fdata) { return fdata.PrincipalID == userID.ToString(); });
|
||||
if (lst != null)
|
||||
{
|
||||
m_Data.Remove(friend);
|
||||
return true;
|
||||
FriendsData friend = lst.Find(delegate(FriendsData fdata) { return fdata.Friend == friendID; });
|
||||
if (friendID != null)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[NULL FRIENDS DATA]: Deleting friend {0} {1} for {2}",
|
||||
// friend.Friend, friend.Data["Flags"], friend.PrincipalID);
|
||||
|
||||
m_Data.Remove(friend);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -110,7 +110,6 @@ namespace OpenSim.Data.Null
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public PresenceData[] Get(string field, string data)
|
||||
{
|
||||
if (Instance != this)
|
||||
|
||||
@@ -472,3 +472,95 @@ COMMIT;
|
||||
BEGIN;
|
||||
ALTER TABLE regionsettings ADD COLUMN covenant_datetime INTEGER NOT NULL default 0;
|
||||
COMMIT;
|
||||
|
||||
:VERSION 23
|
||||
BEGIN;
|
||||
CREATE TABLE regionwindlight (
|
||||
region_id VARCHAR(36) NOT NULL DEFAULT '000000-0000-0000-0000-000000000000' PRIMARY KEY,
|
||||
water_color_r FLOAT NOT NULL DEFAULT '4.000000',
|
||||
water_color_g FLOAT NOT NULL DEFAULT '38.000000',
|
||||
water_color_b FLOAT NOT NULL DEFAULT '64.000000',
|
||||
water_color_i FLOAT NOT NULL DEFAULT '1.000000',
|
||||
water_fog_density_exponent FLOAT NOT NULL DEFAULT '4.0',
|
||||
underwater_fog_modifier FLOAT NOT NULL DEFAULT '0.25',
|
||||
reflection_wavelet_scale_1 FLOAT NOT NULL DEFAULT '2.0',
|
||||
reflection_wavelet_scale_2 FLOAT NOT NULL DEFAULT '2.0',
|
||||
reflection_wavelet_scale_3 FLOAT NOT NULL DEFAULT '2.0',
|
||||
fresnel_scale FLOAT NOT NULL DEFAULT '0.40',
|
||||
fresnel_offset FLOAT NOT NULL DEFAULT '0.50',
|
||||
refract_scale_above FLOAT NOT NULL DEFAULT '0.03',
|
||||
refract_scale_below FLOAT NOT NULL DEFAULT '0.20',
|
||||
blur_multiplier FLOAT NOT NULL DEFAULT '0.040',
|
||||
big_wave_direction_x FLOAT NOT NULL DEFAULT '1.05',
|
||||
big_wave_direction_y FLOAT NOT NULL DEFAULT '-0.42',
|
||||
little_wave_direction_x FLOAT NOT NULL DEFAULT '1.11',
|
||||
little_wave_direction_y FLOAT NOT NULL DEFAULT '-1.16',
|
||||
normal_map_texture VARCHAR(36) NOT NULL DEFAULT '822ded49-9a6c-f61c-cb89-6df54f42cdf4',
|
||||
horizon_r FLOAT NOT NULL DEFAULT '0.25',
|
||||
horizon_g FLOAT NOT NULL DEFAULT '0.25',
|
||||
horizon_b FLOAT NOT NULL DEFAULT '0.32',
|
||||
horizon_i FLOAT NOT NULL DEFAULT '0.32',
|
||||
haze_horizon FLOAT NOT NULL DEFAULT '0.19',
|
||||
blue_density_r FLOAT NOT NULL DEFAULT '0.12',
|
||||
blue_density_g FLOAT NOT NULL DEFAULT '0.22',
|
||||
blue_density_b FLOAT NOT NULL DEFAULT '0.38',
|
||||
blue_density_i FLOAT NOT NULL DEFAULT '0.38',
|
||||
haze_density FLOAT NOT NULL DEFAULT '0.70',
|
||||
density_multiplier FLOAT NOT NULL DEFAULT '0.18',
|
||||
distance_multiplier FLOAT NOT NULL DEFAULT '0.8',
|
||||
max_altitude INTEGER NOT NULL DEFAULT '1605',
|
||||
sun_moon_color_r FLOAT NOT NULL DEFAULT '0.24',
|
||||
sun_moon_color_g FLOAT NOT NULL DEFAULT '0.26',
|
||||
sun_moon_color_b FLOAT NOT NULL DEFAULT '0.30',
|
||||
sun_moon_color_i FLOAT NOT NULL DEFAULT '0.30',
|
||||
sun_moon_position FLOAT NOT NULL DEFAULT '0.317',
|
||||
ambient_r FLOAT NOT NULL DEFAULT '0.35',
|
||||
ambient_g FLOAT NOT NULL DEFAULT '0.35',
|
||||
ambient_b FLOAT NOT NULL DEFAULT '0.35',
|
||||
ambient_i FLOAT NOT NULL DEFAULT '0.35',
|
||||
east_angle FLOAT NOT NULL DEFAULT '0.00',
|
||||
sun_glow_focus FLOAT NOT NULL DEFAULT '0.10',
|
||||
sun_glow_size FLOAT NOT NULL DEFAULT '1.75',
|
||||
scene_gamma FLOAT NOT NULL DEFAULT '1.00',
|
||||
star_brightness FLOAT NOT NULL DEFAULT '0.00',
|
||||
cloud_color_r FLOAT NOT NULL DEFAULT '0.41',
|
||||
cloud_color_g FLOAT NOT NULL DEFAULT '0.41',
|
||||
cloud_color_b FLOAT NOT NULL DEFAULT '0.41',
|
||||
cloud_color_i FLOAT NOT NULL DEFAULT '0.41',
|
||||
cloud_x FLOAT NOT NULL DEFAULT '1.00',
|
||||
cloud_y FLOAT NOT NULL DEFAULT '0.53',
|
||||
cloud_density FLOAT NOT NULL DEFAULT '1.00',
|
||||
cloud_coverage FLOAT NOT NULL DEFAULT '0.27',
|
||||
cloud_scale FLOAT NOT NULL DEFAULT '0.42',
|
||||
cloud_detail_x FLOAT NOT NULL DEFAULT '1.00',
|
||||
cloud_detail_y FLOAT NOT NULL DEFAULT '0.53',
|
||||
cloud_detail_density FLOAT NOT NULL DEFAULT '0.12',
|
||||
cloud_scroll_x FLOAT NOT NULL DEFAULT '0.20',
|
||||
cloud_scroll_x_lock INTEGER NOT NULL DEFAULT '0',
|
||||
cloud_scroll_y FLOAT NOT NULL DEFAULT '0.01',
|
||||
cloud_scroll_y_lock INTEGER NOT NULL DEFAULT '0',
|
||||
draw_classic_clouds INTEGER NOT NULL DEFAULT '1');
|
||||
|
||||
COMMIT;
|
||||
|
||||
|
||||
:VERSION 24
|
||||
|
||||
BEGIN;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `spawn_points` (
|
||||
`RegionID` varchar(36) NOT NULL DEFAULT '000000-0000-0000-0000-000000000000',
|
||||
`Yaw` float NOT NULL,
|
||||
`Pitch` float NOT NULL,
|
||||
`Distance` float NOT NULL
|
||||
);
|
||||
|
||||
ALTER TABLE `regionsettings` ADD COLUMN `TelehubObject` varchar(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000';
|
||||
|
||||
COMMIT;
|
||||
|
||||
:VERSION 25
|
||||
|
||||
BEGIN;
|
||||
ALTER TABLE `regionsettings` ADD COLUMN `parcel_tile_ID` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000';
|
||||
COMMIT;
|
||||
|
||||
@@ -81,6 +81,9 @@ namespace OpenSim.Data.SQLite
|
||||
/// <param name="dbconnect">connect string</param>
|
||||
override public void Initialise(string dbconnect)
|
||||
{
|
||||
if (Util.IsWindows())
|
||||
Util.LoadArchSpecificWindowsDll("sqlite3.dll");
|
||||
|
||||
if (dbconnect == string.Empty)
|
||||
{
|
||||
dbconnect = "URI=file:Asset.db,version=3";
|
||||
|
||||
@@ -65,6 +65,9 @@ namespace OpenSim.Data.SQLite
|
||||
|
||||
if (!m_initialized)
|
||||
{
|
||||
if (Util.IsWindows())
|
||||
Util.LoadArchSpecificWindowsDll("sqlite3.dll");
|
||||
|
||||
m_Connection = new SqliteConnection(connectionString);
|
||||
m_Connection.Open();
|
||||
|
||||
|
||||
@@ -69,6 +69,9 @@ namespace OpenSim.Data.SQLite
|
||||
|
||||
public void Initialise(string connectionString)
|
||||
{
|
||||
if (Util.IsWindows())
|
||||
Util.LoadArchSpecificWindowsDll("sqlite3.dll");
|
||||
|
||||
m_connectionString = connectionString;
|
||||
|
||||
m_log.Info("[ESTATE DB]: Sqlite - connecting: "+m_connectionString);
|
||||
|
||||
@@ -48,6 +48,8 @@ namespace OpenSim.Data.SQLite
|
||||
|
||||
protected SQLiteFramework(string connectionString)
|
||||
{
|
||||
if (Util.IsWindows())
|
||||
Util.LoadArchSpecificWindowsDll("sqlite3.dll");
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -77,6 +77,9 @@ namespace OpenSim.Data.SQLite
|
||||
{
|
||||
m_Initialized = true;
|
||||
|
||||
if (Util.IsWindows())
|
||||
Util.LoadArchSpecificWindowsDll("sqlite3.dll");
|
||||
|
||||
if (dbconnect == string.Empty)
|
||||
{
|
||||
dbconnect = "URI=file:inventoryStore.db,version=3";
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -52,6 +52,9 @@ namespace OpenSim.Data.SQLite
|
||||
|
||||
public SQLiteXInventoryData(string conn, string realm)
|
||||
{
|
||||
if (Util.IsWindows())
|
||||
Util.LoadArchSpecificWindowsDll("sqlite3.dll");
|
||||
|
||||
m_Folders = new SQLiteGenericTableHandler<XInventoryFolder>(
|
||||
conn, "inventoryfolders", "XInventoryStore");
|
||||
m_Items = new SqliteItemHandler(
|
||||
|
||||
@@ -25,34 +25,16 @@
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
|
||||
// Information about this assembly is defined by the following
|
||||
// attributes.
|
||||
//
|
||||
// change them to the information which is associated with the assembly
|
||||
// you compile.
|
||||
|
||||
[assembly : AssemblyTitle("RealPhysXplugin")]
|
||||
[assembly : AssemblyDescription("")]
|
||||
[assembly : AssemblyConfiguration("")]
|
||||
[assembly : AssemblyCompany("http://opensimulator.org")]
|
||||
[assembly : AssemblyProduct("RealPhysXplugin")]
|
||||
[assembly : AssemblyCopyright("Copyright (c) OpenSimulator.org Developers 2007-2009")]
|
||||
[assembly : AssemblyTrademark("")]
|
||||
[assembly : AssemblyCulture("")]
|
||||
|
||||
// This sets the default COM visibility of types in the assembly to invisible.
|
||||
// If you need to expose a type to COM, use [ComVisible(true)] on that type.
|
||||
|
||||
[assembly : ComVisible(false)]
|
||||
|
||||
// The assembly version has following format :
|
||||
//
|
||||
// Major.Minor.Build.Revision
|
||||
//
|
||||
// You can specify all values by your own or you can build default build and revision
|
||||
// numbers with the '*' character (the default):
|
||||
|
||||
[assembly : AssemblyVersion("0.6.5.*")]
|
||||
namespace OpenSim.Framework.Client
|
||||
{
|
||||
public interface IClientInventory
|
||||
{
|
||||
void SendRemoveInventoryFolders(UUID[] folders);
|
||||
void SendRemoveInventoryItems(UUID[] folders);
|
||||
void SendBulkUpdateInventory(InventoryFolderBase[] folders, InventoryItemBase[] items);
|
||||
}
|
||||
}
|
||||
@@ -29,6 +29,7 @@ using System;
|
||||
using System.Xml;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
@@ -40,6 +41,8 @@ namespace OpenSim.Framework.Console
|
||||
{
|
||||
public class Commands : ICommands
|
||||
{
|
||||
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
/// <summary>
|
||||
/// Encapsulates a command that can be invoked from the console
|
||||
/// </summary>
|
||||
@@ -76,12 +79,23 @@ namespace OpenSim.Framework.Console
|
||||
public List<CommandDelegate> fn;
|
||||
}
|
||||
|
||||
public const string GeneralHelpText
|
||||
= "To enter an argument that contains spaces, surround the argument with double quotes.\nFor example, show object name \"My long object name\"\n";
|
||||
|
||||
public const string ItemHelpText
|
||||
= "For more information, type 'help <item>' where <item> is one of the following:";
|
||||
|
||||
/// <value>
|
||||
/// Commands organized by keyword in a tree
|
||||
/// </value>
|
||||
private Dictionary<string, object> tree =
|
||||
new Dictionary<string, object>();
|
||||
|
||||
/// <summary>
|
||||
/// Commands organized by module
|
||||
/// </summary>
|
||||
private Dictionary<string, List<CommandInfo>> m_modulesCommands = new Dictionary<string, List<CommandInfo>>();
|
||||
|
||||
/// <summary>
|
||||
/// Get help for the given help string
|
||||
/// </summary>
|
||||
@@ -98,8 +112,10 @@ namespace OpenSim.Framework.Console
|
||||
// General help
|
||||
if (helpParts.Count == 0)
|
||||
{
|
||||
help.AddRange(CollectHelp(tree));
|
||||
help.Sort();
|
||||
help.Add(""); // Will become a newline.
|
||||
help.Add(GeneralHelpText);
|
||||
help.Add(ItemHelpText);
|
||||
help.AddRange(CollectModulesHelp(tree));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -118,6 +134,13 @@ namespace OpenSim.Framework.Console
|
||||
{
|
||||
string originalHelpRequest = string.Join(" ", helpParts.ToArray());
|
||||
List<string> help = new List<string>();
|
||||
|
||||
// Check modules first to see if we just need to display a list of those commands
|
||||
if (TryCollectModuleHelp(originalHelpRequest, help))
|
||||
{
|
||||
help.Insert(0, ItemHelpText);
|
||||
return help;
|
||||
}
|
||||
|
||||
Dictionary<string, object> dict = tree;
|
||||
while (helpParts.Count > 0)
|
||||
@@ -161,25 +184,63 @@ namespace OpenSim.Framework.Console
|
||||
return help;
|
||||
}
|
||||
|
||||
private List<string> CollectHelp(Dictionary<string, object> dict)
|
||||
/// <summary>
|
||||
/// Try to collect help for the given module if that module exists.
|
||||
/// </summary>
|
||||
/// <param name="moduleName"></param>
|
||||
/// <param name="helpText">/param>
|
||||
/// <returns>true if there was the module existed, false otherwise.</returns>
|
||||
private bool TryCollectModuleHelp(string moduleName, List<string> helpText)
|
||||
{
|
||||
List<string> result = new List<string>();
|
||||
|
||||
foreach (KeyValuePair<string, object> kvp in dict)
|
||||
lock (m_modulesCommands)
|
||||
{
|
||||
if (kvp.Value is Dictionary<string, Object>)
|
||||
foreach (string key in m_modulesCommands.Keys)
|
||||
{
|
||||
result.AddRange(CollectHelp((Dictionary<string, Object>)kvp.Value));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (((CommandInfo)kvp.Value).long_help != String.Empty)
|
||||
result.Add(((CommandInfo)kvp.Value).help_text+" - "+
|
||||
((CommandInfo)kvp.Value).long_help);
|
||||
// Allow topic help requests to succeed whether they are upper or lowercase.
|
||||
if (moduleName.ToLower() == key.ToLower())
|
||||
{
|
||||
List<CommandInfo> commands = m_modulesCommands[key];
|
||||
var ourHelpText = commands.ConvertAll(c => string.Format("{0} - {1}", c.help_text, c.long_help));
|
||||
ourHelpText.Sort();
|
||||
helpText.AddRange(ourHelpText);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<string> CollectModulesHelp(Dictionary<string, object> dict)
|
||||
{
|
||||
lock (m_modulesCommands)
|
||||
{
|
||||
List<string> helpText = new List<string>(m_modulesCommands.Keys);
|
||||
helpText.Sort();
|
||||
return helpText;
|
||||
}
|
||||
}
|
||||
|
||||
// private List<string> CollectHelp(Dictionary<string, object> dict)
|
||||
// {
|
||||
// List<string> result = new List<string>();
|
||||
//
|
||||
// foreach (KeyValuePair<string, object> kvp in dict)
|
||||
// {
|
||||
// if (kvp.Value is Dictionary<string, Object>)
|
||||
// {
|
||||
// result.AddRange(CollectHelp((Dictionary<string, Object>)kvp.Value));
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// if (((CommandInfo)kvp.Value).long_help != String.Empty)
|
||||
// result.Add(((CommandInfo)kvp.Value).help_text+" - "+
|
||||
// ((CommandInfo)kvp.Value).long_help);
|
||||
// }
|
||||
// }
|
||||
// return result;
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// Add a command to those which can be invoked from the console.
|
||||
@@ -212,21 +273,19 @@ namespace OpenSim.Framework.Console
|
||||
|
||||
Dictionary<string, Object> current = tree;
|
||||
|
||||
foreach (string s in parts)
|
||||
foreach (string part in parts)
|
||||
{
|
||||
if (current.ContainsKey(s))
|
||||
if (current.ContainsKey(part))
|
||||
{
|
||||
if (current[s] is Dictionary<string, Object>)
|
||||
{
|
||||
current = (Dictionary<string, Object>)current[s];
|
||||
}
|
||||
if (current[part] is Dictionary<string, Object>)
|
||||
current = (Dictionary<string, Object>)current[part];
|
||||
else
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
current[s] = new Dictionary<string, Object>();
|
||||
current = (Dictionary<string, Object>)current[s];
|
||||
current[part] = new Dictionary<string, Object>();
|
||||
current = (Dictionary<string, Object>)current[part];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -250,6 +309,24 @@ namespace OpenSim.Framework.Console
|
||||
info.fn = new List<CommandDelegate>();
|
||||
info.fn.Add(fn);
|
||||
current[String.Empty] = info;
|
||||
|
||||
// Now add command to modules dictionary
|
||||
lock (m_modulesCommands)
|
||||
{
|
||||
List<CommandInfo> commands;
|
||||
if (m_modulesCommands.ContainsKey(module))
|
||||
{
|
||||
commands = m_modulesCommands[module];
|
||||
}
|
||||
else
|
||||
{
|
||||
commands = new List<CommandInfo>();
|
||||
m_modulesCommands[module] = commands;
|
||||
}
|
||||
|
||||
// m_log.DebugFormat("[COMMAND CONSOLE]: Adding to category {0} command {1}", module, command);
|
||||
commands.Add(info);
|
||||
}
|
||||
}
|
||||
|
||||
public string[] FindNextOption(string[] cmd, bool term)
|
||||
@@ -607,8 +684,9 @@ namespace OpenSim.Framework.Console
|
||||
{
|
||||
Commands = new Commands();
|
||||
|
||||
Commands.AddCommand("console", false, "help", "help [<command>]",
|
||||
"Get general command list or more detailed help on a specific command", Help);
|
||||
Commands.AddCommand(
|
||||
"Help", false, "help", "help [<item>]",
|
||||
"Display help on a particular command or on a list of commands in a category", Help);
|
||||
}
|
||||
|
||||
private void Help(string module, string[] cmd)
|
||||
|
||||
112
OpenSim/Framework/Console/ConsoleDisplayList.cs
Normal file
112
OpenSim/Framework/Console/ConsoleDisplayList.cs
Normal file
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace OpenSim.Framework.Console
|
||||
{
|
||||
/// <summary>
|
||||
/// Used to generated a formatted table for the console.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Currently subject to change. If you use this, be prepared to change your code when this class changes.
|
||||
/// </remarks>
|
||||
public class ConsoleDisplayList
|
||||
{
|
||||
/// <summary>
|
||||
/// The default divider between key and value for a list item.
|
||||
/// </summary>
|
||||
public const string DefaultKeyValueDivider = " : ";
|
||||
|
||||
/// <summary>
|
||||
/// The divider used between key and value for a list item.
|
||||
/// </summary>
|
||||
public string KeyValueDivider { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Table rows
|
||||
/// </summary>
|
||||
public List<KeyValuePair<string, string>> Rows { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Number of spaces to indent the list.
|
||||
/// </summary>
|
||||
public int Indent { get; set; }
|
||||
|
||||
public ConsoleDisplayList()
|
||||
{
|
||||
Rows = new List<KeyValuePair<string, string>>();
|
||||
KeyValueDivider = DefaultKeyValueDivider;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
AddToStringBuilder(sb);
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public void AddToStringBuilder(StringBuilder sb)
|
||||
{
|
||||
string formatString = GetFormatString();
|
||||
// System.Console.WriteLine("FORMAT STRING [{0}]", formatString);
|
||||
|
||||
// rows
|
||||
foreach (KeyValuePair<string, string> row in Rows)
|
||||
sb.AppendFormat(formatString, row.Key, row.Value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the format string for the table.
|
||||
/// </summary>
|
||||
private string GetFormatString()
|
||||
{
|
||||
StringBuilder formatSb = new StringBuilder();
|
||||
|
||||
int longestKey = -1;
|
||||
|
||||
foreach (KeyValuePair<string, string> row in Rows)
|
||||
if (row.Key.Length > longestKey)
|
||||
longestKey = row.Key.Length;
|
||||
|
||||
formatSb.Append(' ', Indent);
|
||||
|
||||
// Can only do left formatting for now
|
||||
formatSb.AppendFormat("{{0,-{0}}}{1}{{1}}\n", longestKey, KeyValueDivider);
|
||||
|
||||
return formatSb.ToString();
|
||||
}
|
||||
|
||||
public void AddRow(object key, object value)
|
||||
{
|
||||
Rows.Add(new KeyValuePair<string, string>(key.ToString(), value.ToString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
139
OpenSim/Framework/Console/ConsoleDisplayTable.cs
Normal file
139
OpenSim/Framework/Console/ConsoleDisplayTable.cs
Normal file
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace OpenSim.Framework.Console
|
||||
{
|
||||
/// <summary>
|
||||
/// Used to generated a formatted table for the console.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Currently subject to change. If you use this, be prepared to change your code when this class changes.
|
||||
/// </remarks>
|
||||
public class ConsoleDisplayTable
|
||||
{
|
||||
/// <summary>
|
||||
/// Default number of spaces between table columns.
|
||||
/// </summary>
|
||||
public const int DefaultTableSpacing = 2;
|
||||
|
||||
/// <summary>
|
||||
/// Table columns.
|
||||
/// </summary>
|
||||
public List<ConsoleDisplayTableColumn> Columns { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Table rows
|
||||
/// </summary>
|
||||
public List<ConsoleDisplayTableRow> Rows { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Number of spaces to indent the table.
|
||||
/// </summary>
|
||||
public int Indent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Spacing between table columns
|
||||
/// </summary>
|
||||
public int TableSpacing { get; set; }
|
||||
|
||||
public ConsoleDisplayTable()
|
||||
{
|
||||
TableSpacing = DefaultTableSpacing;
|
||||
Columns = new List<ConsoleDisplayTableColumn>();
|
||||
Rows = new List<ConsoleDisplayTableRow>();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
AddToStringBuilder(sb);
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public void AddToStringBuilder(StringBuilder sb)
|
||||
{
|
||||
string formatString = GetFormatString();
|
||||
// System.Console.WriteLine("FORMAT STRING [{0}]", formatString);
|
||||
|
||||
// columns
|
||||
sb.AppendFormat(formatString, Columns.ConvertAll(c => c.Header).ToArray());
|
||||
|
||||
// rows
|
||||
foreach (ConsoleDisplayTableRow row in Rows)
|
||||
sb.AppendFormat(formatString, row.Cells.ToArray());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the format string for the table.
|
||||
/// </summary>
|
||||
private string GetFormatString()
|
||||
{
|
||||
StringBuilder formatSb = new StringBuilder();
|
||||
|
||||
formatSb.Append(' ', Indent);
|
||||
|
||||
for (int i = 0; i < Columns.Count; i++)
|
||||
{
|
||||
formatSb.Append(' ', TableSpacing);
|
||||
|
||||
// Can only do left formatting for now
|
||||
formatSb.AppendFormat("{{{0},-{1}}}", i, Columns[i].Width);
|
||||
}
|
||||
|
||||
formatSb.Append('\n');
|
||||
|
||||
return formatSb.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public struct ConsoleDisplayTableColumn
|
||||
{
|
||||
public string Header { get; set; }
|
||||
public int Width { get; set; }
|
||||
|
||||
public ConsoleDisplayTableColumn(string header, int width) : this()
|
||||
{
|
||||
Header = header;
|
||||
Width = width;
|
||||
}
|
||||
}
|
||||
|
||||
public struct ConsoleDisplayTableRow
|
||||
{
|
||||
public List<string> Cells { get; private set; }
|
||||
|
||||
public ConsoleDisplayTableRow(List<string> cells) : this()
|
||||
{
|
||||
Cells = cells;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -29,6 +29,7 @@ using System;
|
||||
using System.Threading;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
|
||||
namespace OpenSim.Framework.Console
|
||||
{
|
||||
@@ -37,28 +38,42 @@ namespace OpenSim.Framework.Console
|
||||
/// Don't use this except for Unit Testing or you're in for a world of hurt when the
|
||||
/// sim gets to ReadLine
|
||||
/// </summary>
|
||||
public class MockConsole : CommandConsole
|
||||
public class MockConsole : ICommandConsole
|
||||
{
|
||||
public MockConsole(string defaultPrompt) : base(defaultPrompt)
|
||||
{
|
||||
}
|
||||
public override void Output(string text)
|
||||
{
|
||||
}
|
||||
public override void Output(string text, string level)
|
||||
{
|
||||
}
|
||||
private MockCommands m_commands = new MockCommands();
|
||||
|
||||
public override string ReadLine(string p, bool isCommand, bool e)
|
||||
{
|
||||
//Thread.CurrentThread.Join(1000);
|
||||
return string.Empty;
|
||||
}
|
||||
public override void UnlockOutput()
|
||||
{
|
||||
}
|
||||
public override void LockOutput()
|
||||
{
|
||||
}
|
||||
public ICommands Commands { get { return m_commands; } }
|
||||
|
||||
public void Prompt() {}
|
||||
|
||||
public void RunCommand(string cmd) {}
|
||||
|
||||
public string ReadLine(string p, bool isCommand, bool e) { return ""; }
|
||||
|
||||
public object ConsoleScene { get { return null; } }
|
||||
|
||||
public void Output(string text, string level) {}
|
||||
public void Output(string text) {}
|
||||
public void OutputFormat(string format, params object[] components) {}
|
||||
|
||||
public string CmdPrompt(string p) { return ""; }
|
||||
public string CmdPrompt(string p, string def) { return ""; }
|
||||
public string CmdPrompt(string p, List<char> excludedCharacters) { return ""; }
|
||||
public string CmdPrompt(string p, string def, List<char> excludedCharacters) { return ""; }
|
||||
|
||||
public string CmdPrompt(string prompt, string defaultresponse, List<string> options) { return ""; }
|
||||
|
||||
public string PasswdPrompt(string p) { return ""; }
|
||||
}
|
||||
}
|
||||
|
||||
public class MockCommands : ICommands
|
||||
{
|
||||
public void FromXml(XmlElement root, CommandDelegate fn) {}
|
||||
public List<string> GetHelp(string[] cmd) { return null; }
|
||||
public void AddCommand(string module, bool shared, string command, string help, string longhelp, CommandDelegate fn) {}
|
||||
public void AddCommand(string module, bool shared, string command, string help, string longhelp, string descriptivehelp, CommandDelegate fn) {}
|
||||
public string[] FindNextOption(string[] cmd, bool term) { return null; }
|
||||
public string[] Resolve(string[] cmd) { return null; }
|
||||
public XmlElement GetXml(XmlDocument doc) { return null; }
|
||||
}
|
||||
}
|
||||
@@ -26,51 +26,37 @@
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Nini.Config;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Physics.Manager;
|
||||
using PhysXWrapper;
|
||||
using Quaternion=OpenMetaverse.Quaternion;
|
||||
using System.Reflection;
|
||||
using log4net;
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace OpenSim.Region.Physics.PhysXPlugin
|
||||
public class GcNotify
|
||||
{
|
||||
/// <summary>
|
||||
/// Will be the PhysX plugin but for now will be a very basic physics engine
|
||||
/// </summary>
|
||||
public class PhysXPlugin : IPhysicsPlugin
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
public static bool Enabled
|
||||
{
|
||||
//private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
private PhysXScene _mScene;
|
||||
|
||||
public PhysXPlugin()
|
||||
get { return s_initialized; }
|
||||
set
|
||||
{
|
||||
}
|
||||
if (!s_initialized && value)
|
||||
new GcNotify();
|
||||
|
||||
public bool Init()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public PhysicsScene GetScene(string sceneIdentifier)
|
||||
{
|
||||
if (_mScene == null)
|
||||
{
|
||||
_mScene = new PhysXScene(sceneIdentifier);
|
||||
}
|
||||
return (_mScene);
|
||||
}
|
||||
|
||||
public string GetName()
|
||||
{
|
||||
return ("RealPhysX");
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
s_initialized = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static bool s_initialized = false;
|
||||
|
||||
private GcNotify() {}
|
||||
|
||||
~GcNotify()
|
||||
{
|
||||
if (!Environment.HasShutdownStarted && !AppDomain.CurrentDomain.IsFinalizingForUnload())
|
||||
{
|
||||
m_log.DebugFormat("[GC NOTIFY]: Garbage collection triggered.");
|
||||
|
||||
if (Enabled)
|
||||
new GcNotify();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -296,9 +296,9 @@ namespace OpenSim.Framework
|
||||
public delegate void ConfirmXfer(IClientAPI remoteClient, ulong xferID, uint packetID);
|
||||
|
||||
public delegate void FriendActionDelegate(
|
||||
IClientAPI remoteClient, UUID agentID, UUID transactionID, List<UUID> callingCardFolders);
|
||||
IClientAPI remoteClient, UUID transactionID, List<UUID> callingCardFolders);
|
||||
|
||||
public delegate void FriendshipTermination(IClientAPI remoteClient, UUID agentID, UUID ExID);
|
||||
public delegate void FriendshipTermination(IClientAPI remoteClient, UUID ExID);
|
||||
|
||||
public delegate void MoneyTransferRequest(
|
||||
UUID sourceID, UUID destID, int amount, int transactionType, string description);
|
||||
@@ -458,7 +458,7 @@ namespace OpenSim.Framework
|
||||
public delegate void AvatarNotesUpdate(IClientAPI client, UUID targetID, string notes);
|
||||
public delegate void MuteListRequest(IClientAPI client, uint muteCRC);
|
||||
public delegate void AvatarInterestUpdate(IClientAPI client, uint wantmask, string wanttext, uint skillsmask, string skillstext, string languages);
|
||||
public delegate void GrantUserFriendRights(IClientAPI client, UUID requester, UUID target, int rights);
|
||||
public delegate void GrantUserFriendRights(IClientAPI client, UUID target, int rights);
|
||||
public delegate void PlacesQuery(UUID QueryID, UUID TransactionID, string QueryText, uint QueryFlags, byte Category, string SimName, IClientAPI client);
|
||||
|
||||
public delegate void AgentFOV(IClientAPI client, float verticalAngle);
|
||||
@@ -710,7 +710,7 @@ namespace OpenSim.Framework
|
||||
/// The scene agent for this client. This will only be set if the client has an agent in a scene (i.e. if it
|
||||
/// is connected).
|
||||
/// </summary>
|
||||
ISceneAgent SceneAgent { get; }
|
||||
ISceneAgent SceneAgent { get; set; }
|
||||
|
||||
UUID SessionId { get; }
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace OpenSim.Framework
|
||||
/// <summary>
|
||||
/// Get help for the given help string
|
||||
/// </summary>
|
||||
/// <param name="helpParts">Parsed parts of the help string. If empty then general help is returned.</param>
|
||||
/// <param name="cmd">Parsed parts of the help string. If empty then general help is returned.</param>
|
||||
/// <returns></returns>
|
||||
List<string> GetHelp(string[] cmd);
|
||||
|
||||
|
||||
@@ -71,6 +71,7 @@ namespace OpenSim.Framework
|
||||
bool IsEitherBannedOrRestricted(UUID avatar);
|
||||
bool IsBannedFromLand(UUID avatar);
|
||||
bool IsRestrictedFromLand(UUID avatar);
|
||||
bool IsInLandAccessList(UUID avatar);
|
||||
void SendLandUpdateToClient(IClientAPI remote_client);
|
||||
void SendLandUpdateToClient(bool snap_selection, IClientAPI remote_client);
|
||||
List<LandAccessEntry> CreateAccessListArrayByFlag(AccessList flag);
|
||||
|
||||
@@ -69,7 +69,7 @@ namespace OpenSim.Framework
|
||||
(uint) ParcelFlags.AllowAPrimitiveEntry |
|
||||
(uint) ParcelFlags.AllowDeedToGroup | (uint) ParcelFlags.AllowTerraform |
|
||||
(uint) ParcelFlags.CreateObjects | (uint) ParcelFlags.AllowOtherScripts |
|
||||
(uint) ParcelFlags.SoundLocal;
|
||||
(uint) ParcelFlags.SoundLocal | (uint) ParcelFlags.AllowVoiceChat;
|
||||
|
||||
private byte _landingType = 0;
|
||||
private string _name = "Your Parcel";
|
||||
|
||||
@@ -49,15 +49,16 @@ namespace OpenSim.Framework.Serialization.External
|
||||
/// <param name="nodeToFill"></param>
|
||||
/// <param name="processors">/param>
|
||||
/// <param name="xtr"></param>
|
||||
public static void ExecuteReadProcessors<NodeType>(
|
||||
/// <returns>true on successful, false if there were any processing failures</returns>
|
||||
public static bool ExecuteReadProcessors<NodeType>(
|
||||
NodeType nodeToFill, Dictionary<string, Action<NodeType, XmlTextReader>> processors, XmlTextReader xtr)
|
||||
{
|
||||
ExecuteReadProcessors(
|
||||
return ExecuteReadProcessors(
|
||||
nodeToFill,
|
||||
processors,
|
||||
xtr,
|
||||
(o, name, e)
|
||||
=> m_log.ErrorFormat(
|
||||
=> m_log.DebugFormat(
|
||||
"[ExternalRepresentationUtils]: Exception while parsing element {0}, continuing. Exception {1}{2}",
|
||||
name, e.Message, e.StackTrace));
|
||||
}
|
||||
@@ -71,12 +72,15 @@ namespace OpenSim.Framework.Serialization.External
|
||||
/// <param name="parseExceptionAction">
|
||||
/// Action to take if there is a parsing problem. This will usually just be to log the exception
|
||||
/// </param>
|
||||
public static void ExecuteReadProcessors<NodeType>(
|
||||
/// <returns>true on successful, false if there were any processing failures</returns>
|
||||
public static bool ExecuteReadProcessors<NodeType>(
|
||||
NodeType nodeToFill,
|
||||
Dictionary<string, Action<NodeType, XmlTextReader>> processors,
|
||||
XmlTextReader xtr,
|
||||
Action<NodeType, string, Exception> parseExceptionAction)
|
||||
{
|
||||
bool errors = false;
|
||||
|
||||
string nodeName = string.Empty;
|
||||
while (xtr.NodeType != XmlNodeType.EndElement)
|
||||
{
|
||||
@@ -95,6 +99,7 @@ namespace OpenSim.Framework.Serialization.External
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
errors = true;
|
||||
parseExceptionAction(nodeToFill, nodeName, e);
|
||||
|
||||
if (xtr.NodeType == XmlNodeType.EndElement)
|
||||
@@ -107,6 +112,8 @@ namespace OpenSim.Framework.Serialization.External
|
||||
xtr.ReadOuterXml(); // ignore
|
||||
}
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -140,6 +147,7 @@ namespace OpenSim.Framework.Serialization.External
|
||||
UUID.TryParse(node.InnerText, out uuid);
|
||||
creator = userService.GetUserAccount(scopeID, uuid);
|
||||
}
|
||||
|
||||
if (node.Name == "CreatorData" && node.InnerText != null && node.InnerText != string.Empty)
|
||||
hasCreatorData = true;
|
||||
|
||||
@@ -163,7 +171,6 @@ namespace OpenSim.Framework.Serialization.External
|
||||
doc.Save(wr);
|
||||
return wr.ToString();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -161,43 +161,43 @@ namespace OpenSim.Framework.Servers
|
||||
Notice(String.Format("Console log level is {0}", m_consoleAppender.Threshold));
|
||||
}
|
||||
|
||||
m_console.Commands.AddCommand("base", false, "quit",
|
||||
m_console.Commands.AddCommand("General", false, "quit",
|
||||
"quit",
|
||||
"Quit the application", HandleQuit);
|
||||
|
||||
m_console.Commands.AddCommand("base", false, "shutdown",
|
||||
m_console.Commands.AddCommand("General", false, "shutdown",
|
||||
"shutdown",
|
||||
"Quit the application", HandleQuit);
|
||||
|
||||
m_console.Commands.AddCommand("base", false, "set log level",
|
||||
m_console.Commands.AddCommand("General", false, "set log level",
|
||||
"set log level <level>",
|
||||
"Set the console logging level", HandleLogLevel);
|
||||
|
||||
m_console.Commands.AddCommand("base", false, "show info",
|
||||
m_console.Commands.AddCommand("General", false, "show info",
|
||||
"show info",
|
||||
"Show general information about the server", HandleShow);
|
||||
|
||||
m_console.Commands.AddCommand("base", false, "show stats",
|
||||
m_console.Commands.AddCommand("General", false, "show stats",
|
||||
"show stats",
|
||||
"Show statistics", HandleShow);
|
||||
|
||||
m_console.Commands.AddCommand("base", false, "show threads",
|
||||
m_console.Commands.AddCommand("General", false, "show threads",
|
||||
"show threads",
|
||||
"Show thread status", HandleShow);
|
||||
|
||||
m_console.Commands.AddCommand("base", false, "show uptime",
|
||||
m_console.Commands.AddCommand("General", false, "show uptime",
|
||||
"show uptime",
|
||||
"Show server uptime", HandleShow);
|
||||
|
||||
m_console.Commands.AddCommand("base", false, "show version",
|
||||
m_console.Commands.AddCommand("General", false, "show version",
|
||||
"show version",
|
||||
"Show server version", HandleShow);
|
||||
|
||||
m_console.Commands.AddCommand("base", false, "threads abort",
|
||||
m_console.Commands.AddCommand("General", false, "threads abort",
|
||||
"threads abort <thread-id>",
|
||||
"Abort a managed thread. Use \"show threads\" to find possible threads.", HandleThreadsAbort);
|
||||
|
||||
m_console.Commands.AddCommand("base", false, "threads show",
|
||||
m_console.Commands.AddCommand("General", false, "threads show",
|
||||
"threads show",
|
||||
"Show thread status. Synonym for \"show threads\"",
|
||||
(string module, string[] args) => Notice(GetThreadsReport()));
|
||||
@@ -247,7 +247,7 @@ namespace OpenSim.Framework.Servers
|
||||
string reportFormat = "{0,6} {1,35} {2,16} {3,13} {4,10} {5,30}";
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
Watchdog.ThreadWatchdogInfo[] threads = Watchdog.GetThreads();
|
||||
Watchdog.ThreadWatchdogInfo[] threads = Watchdog.GetThreadsInfo();
|
||||
|
||||
sb.Append(threads.Length + " threads are being tracked:" + Environment.NewLine);
|
||||
|
||||
@@ -269,15 +269,19 @@ namespace OpenSim.Framework.Servers
|
||||
t.Priority,
|
||||
t.ThreadState);
|
||||
|
||||
sb.Append(Environment.NewLine);
|
||||
sb.Append("\n");
|
||||
}
|
||||
|
||||
int workers = 0, ports = 0, maxWorkers = 0, maxPorts = 0;
|
||||
ThreadPool.GetAvailableThreads(out workers, out ports);
|
||||
ThreadPool.GetMaxThreads(out maxWorkers, out maxPorts);
|
||||
sb.Append("\n");
|
||||
|
||||
sb.Append(Environment.NewLine + "*** ThreadPool threads ***" + Environment.NewLine);
|
||||
sb.Append("workers: " + (maxWorkers - workers) + " (" + maxWorkers + "); ports: " + (maxPorts - ports) + " (" + maxPorts + ")" + Environment.NewLine);
|
||||
// For some reason mono 2.6.7 returns an empty threads set! Not going to confuse people by reporting
|
||||
// zero active threads.
|
||||
int totalThreads = Process.GetCurrentProcess().Threads.Count;
|
||||
if (totalThreads > 0)
|
||||
sb.AppendFormat("Total threads active: {0}\n\n", totalThreads);
|
||||
|
||||
sb.Append("Main threadpool (excluding script engine pools)\n");
|
||||
sb.Append(Util.GetThreadPoolReport());
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
@@ -308,7 +312,9 @@ namespace OpenSim.Framework.Servers
|
||||
// clr version potentially is more confusing than helpful, since it doesn't tell us if we're running under Mono/MS .NET and
|
||||
// the clr version number doesn't match the project version number under Mono.
|
||||
//m_log.Info("[STARTUP]: Virtual machine runtime version: " + Environment.Version + Environment.NewLine);
|
||||
m_log.Info("[STARTUP]: Operating system version: " + Environment.OSVersion + Environment.NewLine);
|
||||
m_log.InfoFormat(
|
||||
"[STARTUP]: Operating system version: {0}, .NET platform {1}, {2}-bit\n",
|
||||
Environment.OSVersion, Environment.OSVersion.Platform, Util.Is64BitProcess() ? "64" : "32");
|
||||
|
||||
StartupSpecific();
|
||||
|
||||
|
||||
@@ -33,9 +33,9 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
{
|
||||
public abstract Hashtable Handle(string path, Hashtable Request);
|
||||
|
||||
protected BaseHTTPHandler(string httpMethod, string path)
|
||||
: base(httpMethod, path)
|
||||
{
|
||||
}
|
||||
protected BaseHTTPHandler(string httpMethod, string path) : this(httpMethod, path, null, null) {}
|
||||
|
||||
protected BaseHTTPHandler(string httpMethod, string path, string name, string description)
|
||||
: base(httpMethod, path, name, description) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -156,7 +156,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
}
|
||||
}
|
||||
|
||||
public List<string> GetStreamHandlerKeys()
|
||||
public List<string> GetStreamHandlerKeys()
|
||||
{
|
||||
lock (m_streamHandlers)
|
||||
return new List<string>(m_streamHandlers.Keys);
|
||||
@@ -356,7 +356,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat("[BASE HTTP SERVER]: OnRequest() failed with {0}{1}", e.Message, e.StackTrace);
|
||||
m_log.Error(String.Format("[BASE HTTP SERVER]: OnRequest() failed: {0} ", e.Message), e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -410,6 +410,8 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
// string reqnum = "unknown";
|
||||
int tickstart = Environment.TickCount;
|
||||
|
||||
IRequestHandler requestHandler = null;
|
||||
|
||||
try
|
||||
{
|
||||
// OpenSim.Framework.WebUtil.OSHeaderRequestID
|
||||
@@ -438,8 +440,6 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
//response.KeepAlive = true;
|
||||
response.SendChunked = false;
|
||||
|
||||
IRequestHandler requestHandler;
|
||||
|
||||
string path = request.RawUrl;
|
||||
string handlerKey = GetHandlerKey(request.HttpMethod, path);
|
||||
|
||||
@@ -447,8 +447,8 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
{
|
||||
if (DebugLevel >= 1)
|
||||
m_log.DebugFormat(
|
||||
"[BASE HTTP SERVER]: Found stream handler for {0} {1}",
|
||||
request.HttpMethod, request.Url.PathAndQuery);
|
||||
"[BASE HTTP SERVER]: Found stream handler for {0} {1} {2} {3}",
|
||||
request.HttpMethod, request.Url.PathAndQuery, requestHandler.Name, requestHandler.Description);
|
||||
|
||||
// Okay, so this is bad, but should be considered temporary until everything is IStreamHandler.
|
||||
byte[] buffer = null;
|
||||
@@ -551,11 +551,11 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
catch (SocketException e)
|
||||
{
|
||||
// This has to be here to prevent a Linux/Mono crash
|
||||
m_log.WarnFormat("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e);
|
||||
m_log.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux. ", e.Message), e);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
m_log.Warn("[BASE HTTP SERVER]: XmlRpcRequest issue: " + e.Message);
|
||||
m_log.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0}. ", e.Message), e);
|
||||
}
|
||||
|
||||
return;
|
||||
@@ -658,15 +658,15 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
//
|
||||
// An alternative may be to turn off all response write exceptions on the HttpListener, but let's go
|
||||
// with the minimum first
|
||||
m_log.WarnFormat("[BASE HTTP SERVER]: HandleRequest threw {0}.\nNOTE: this may be spurious on Linux", e);
|
||||
m_log.Warn(String.Format("[BASE HTTP SERVER]: HandleRequest threw {0}.\nNOTE: this may be spurious on Linux ", e.Message), e);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
m_log.ErrorFormat("[BASE HTTP SERVER]: HandleRequest() threw ", e);
|
||||
m_log.Error(String.Format("[BASE HTTP SERVER]: HandleRequest() threw {0} ", e.Message), e);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat("[BASE HTTP SERVER]: HandleRequest() threw " + e.ToString());
|
||||
m_log.Error(String.Format("[BASE HTTP SERVER]: HandleRequest() threw {0} ", e.Message), e);
|
||||
SendHTML500(response);
|
||||
}
|
||||
finally
|
||||
@@ -675,8 +675,16 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
// since its just for reporting, tickdiff limit can be adjusted
|
||||
int tickdiff = Environment.TickCount - tickstart;
|
||||
if (tickdiff > 3000)
|
||||
{
|
||||
m_log.InfoFormat(
|
||||
"[BASE HTTP SERVER]: slow {0} request for {1} from {2} took {3} ms", requestMethod, uriString, request.RemoteIPEndPoint.ToString(), tickdiff);
|
||||
"[BASE HTTP SERVER]: Slow handling of {0} {1} {2} {3} from {4} took {5}ms",
|
||||
requestMethod,
|
||||
uriString,
|
||||
requestHandler != null ? requestHandler.Name : "",
|
||||
requestHandler != null ? requestHandler.Description : "",
|
||||
request.RemoteIPEndPoint.ToString(),
|
||||
tickdiff);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -925,11 +933,11 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
catch (SocketException e)
|
||||
{
|
||||
// This has to be here to prevent a Linux/Mono crash
|
||||
m_log.WarnFormat("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e);
|
||||
m_log.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux. ", e.Message), e);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
m_log.Warn("[BASE HTTP SERVER]: XmlRpcRequest issue: " + e.Message);
|
||||
m_log.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0} ", e.Message), e);
|
||||
}
|
||||
}
|
||||
return;
|
||||
@@ -962,11 +970,11 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
catch (SocketException e)
|
||||
{
|
||||
// This has to be here to prevent a Linux/Mono crash
|
||||
m_log.WarnFormat("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e);
|
||||
m_log.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux. ", e.Message), e);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
m_log.Warn("[BASE HTTP SERVER]: XmlRpcRequest issue: " + e.Message);
|
||||
m_log.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0} ", e.Message), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1077,12 +1085,12 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
m_log.WarnFormat("[BASE HTTP SERVER]: LLSD IOException {0}.", e);
|
||||
m_log.Warn(String.Format("[BASE HTTP SERVER]: LLSD IOException {0} ", e.Message), e);
|
||||
}
|
||||
catch (SocketException e)
|
||||
{
|
||||
// This has to be here to prevent a Linux/Mono crash
|
||||
m_log.WarnFormat("[BASE HTTP SERVER]: LLSD issue {0}.\nNOTE: this may be spurious on Linux.", e);
|
||||
m_log.Warn(String.Format("[BASE HTTP SERVER]: LLSD issue {0}.\nNOTE: this may be spurious on Linux. ", e.Message), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1334,8 +1342,8 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
catch (SocketException f)
|
||||
{
|
||||
// This has to be here to prevent a Linux/Mono crash
|
||||
m_log.WarnFormat(
|
||||
"[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", f);
|
||||
m_log.Warn(
|
||||
String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux. ", f.Message), f);
|
||||
}
|
||||
}
|
||||
catch(Exception)
|
||||
@@ -1630,11 +1638,11 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
catch (SocketException e)
|
||||
{
|
||||
// This has to be here to prevent a Linux/Mono crash
|
||||
m_log.WarnFormat("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e);
|
||||
m_log.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux. ", e.Message), e);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
m_log.Warn("[BASE HTTP SERVER]: XmlRpcRequest issue: " + e.Message);
|
||||
m_log.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0} ", e.Message), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1671,7 +1679,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
catch (SocketException e)
|
||||
{
|
||||
// This has to be here to prevent a Linux/Mono crash
|
||||
m_log.WarnFormat("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e);
|
||||
m_log.Warn(String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux. ", e.Message), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1707,7 +1715,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
catch (SocketException e)
|
||||
{
|
||||
// This has to be here to prevent a Linux/Mono crash
|
||||
m_log.WarnFormat("[BASE HTTP SERVER] XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e);
|
||||
m_log.Warn(String.Format("[BASE HTTP SERVER] XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux. ", e.Message), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1786,7 +1794,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
|
||||
public void httpServerException(object source, Exception exception)
|
||||
{
|
||||
m_log.ErrorFormat("[BASE HTTP SERVER]: {0} had an exception {1}", source.ToString(), exception.ToString());
|
||||
m_log.Error(String.Format("[BASE HTTP SERVER]: {0} had an exception: {1} ", source.ToString(), exception.Message), exception);
|
||||
/*
|
||||
if (HTTPDRunning)// && NotSocketErrors > 5)
|
||||
{
|
||||
|
||||
@@ -45,8 +45,16 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
|
||||
private readonly string m_path;
|
||||
|
||||
protected BaseRequestHandler(string httpMethod, string path)
|
||||
public string Name { get; private set; }
|
||||
|
||||
public string Description { get; private set; }
|
||||
|
||||
protected BaseRequestHandler(string httpMethod, string path) : this(httpMethod, path, null, null) {}
|
||||
|
||||
protected BaseRequestHandler(string httpMethod, string path, string name, string description)
|
||||
{
|
||||
Name = name;
|
||||
Description = description;
|
||||
m_httpMethod = httpMethod;
|
||||
m_path = path;
|
||||
}
|
||||
|
||||
@@ -34,8 +34,9 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
public abstract byte[] Handle(string path, Stream request,
|
||||
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse);
|
||||
|
||||
protected BaseStreamHandler(string httpMethod, string path) : base(httpMethod, path)
|
||||
{
|
||||
}
|
||||
protected BaseStreamHandler(string httpMethod, string path) : this(httpMethod, path, null, null) {}
|
||||
|
||||
protected BaseStreamHandler(string httpMethod, string path, string name, string description)
|
||||
: base(httpMethod, path, name, description) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -36,6 +36,15 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
{
|
||||
private BinaryMethod m_method;
|
||||
|
||||
public BinaryStreamHandler(string httpMethod, string path, BinaryMethod binaryMethod)
|
||||
: this(httpMethod, path, binaryMethod, null, null) {}
|
||||
|
||||
public BinaryStreamHandler(string httpMethod, string path, BinaryMethod binaryMethod, string name, string description)
|
||||
: base(httpMethod, path, name, description)
|
||||
{
|
||||
m_method = binaryMethod;
|
||||
}
|
||||
|
||||
public override byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
||||
{
|
||||
byte[] data = ReadFully(request);
|
||||
@@ -45,12 +54,6 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
return Encoding.UTF8.GetBytes(responseString);
|
||||
}
|
||||
|
||||
public BinaryStreamHandler(string httpMethod, string path, BinaryMethod binaryMethod)
|
||||
: base(httpMethod, path)
|
||||
{
|
||||
m_method = binaryMethod;
|
||||
}
|
||||
|
||||
private static byte[] ReadFully(Stream stream)
|
||||
{
|
||||
byte[] buffer = new byte[1024];
|
||||
@@ -70,4 +73,4 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -32,6 +32,25 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
{
|
||||
public interface IRequestHandler
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Name for this handler.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Used for diagnostics. The path doesn't always describe what the handler does. Can be null if none
|
||||
/// specified.
|
||||
/// </remarks>
|
||||
string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Description for this handler.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Used for diagnostics. The path doesn't always describe what the handler does. Can be null if none
|
||||
/// specified.
|
||||
/// </remarks>
|
||||
string Description { get; }
|
||||
|
||||
// Return response content type
|
||||
string ContentType { get; }
|
||||
|
||||
@@ -58,4 +77,4 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
{
|
||||
Hashtable Handle(string path, Hashtable request);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -65,6 +65,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
String.Format("PollServiceWorkerThread{0}", i),
|
||||
ThreadPriority.Normal,
|
||||
false,
|
||||
true,
|
||||
int.MaxValue);
|
||||
}
|
||||
|
||||
@@ -73,6 +74,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
"PollServiceWatcherThread",
|
||||
ThreadPriority.Normal,
|
||||
false,
|
||||
true,
|
||||
1000 * 60 * 10);
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,11 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
private RestDeserialiseMethod<TRequest, TResponse> m_method;
|
||||
|
||||
public RestDeserialiseHandler(string httpMethod, string path, RestDeserialiseMethod<TRequest, TResponse> method)
|
||||
: base(httpMethod, path)
|
||||
: this(httpMethod, path, method, null, null) {}
|
||||
|
||||
public RestDeserialiseHandler(
|
||||
string httpMethod, string path, RestDeserialiseMethod<TRequest, TResponse> method, string name, string description)
|
||||
: base(httpMethod, path, name, description)
|
||||
{
|
||||
m_method = method;
|
||||
}
|
||||
|
||||
@@ -38,19 +38,25 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
get { return m_dhttpMethod; }
|
||||
}
|
||||
|
||||
public override Hashtable Handle(string path, Hashtable request)
|
||||
{
|
||||
|
||||
string param = GetParam(path);
|
||||
request.Add("param", param);
|
||||
request.Add("path", path);
|
||||
return m_dhttpMethod(request);
|
||||
}
|
||||
|
||||
public RestHTTPHandler(string httpMethod, string path, GenericHTTPMethod dhttpMethod)
|
||||
: base(httpMethod, path)
|
||||
{
|
||||
m_dhttpMethod = dhttpMethod;
|
||||
}
|
||||
|
||||
public RestHTTPHandler(
|
||||
string httpMethod, string path, GenericHTTPMethod dhttpMethod, string name, string description)
|
||||
: base(httpMethod, path, name, description)
|
||||
{
|
||||
m_dhttpMethod = dhttpMethod;
|
||||
}
|
||||
|
||||
public override Hashtable Handle(string path, Hashtable request)
|
||||
{
|
||||
string param = GetParam(path);
|
||||
request.Add("param", param);
|
||||
request.Add("path", path);
|
||||
return m_dhttpMethod(request);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,6 +39,15 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
get { return m_restMethod; }
|
||||
}
|
||||
|
||||
public RestStreamHandler(string httpMethod, string path, RestMethod restMethod)
|
||||
: this(httpMethod, path, restMethod, null, null) {}
|
||||
|
||||
public RestStreamHandler(string httpMethod, string path, RestMethod restMethod, string name, string description)
|
||||
: base(httpMethod, path, name, description)
|
||||
{
|
||||
m_restMethod = restMethod;
|
||||
}
|
||||
|
||||
public override byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
||||
{
|
||||
Encoding encoding = Encoding.UTF8;
|
||||
@@ -52,10 +61,5 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
|
||||
return Encoding.UTF8.GetBytes(responseString);
|
||||
}
|
||||
|
||||
public RestStreamHandler(string httpMethod, string path, RestMethod restMethod) : base(httpMethod, path)
|
||||
{
|
||||
m_restMethod = restMethod;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace OpenSim
|
||||
public class VersionInfo
|
||||
{
|
||||
private const string VERSION_NUMBER = "0.7.3";
|
||||
private const Flavour VERSION_FLAVOUR = Flavour.Dev;
|
||||
private const Flavour VERSION_FLAVOUR = Flavour.Extended;
|
||||
|
||||
public enum Flavour
|
||||
{
|
||||
@@ -39,7 +39,8 @@ namespace OpenSim
|
||||
RC1,
|
||||
RC2,
|
||||
Release,
|
||||
Post_Fixes
|
||||
Post_Fixes,
|
||||
Extended
|
||||
}
|
||||
|
||||
public static string Version
|
||||
|
||||
@@ -26,8 +26,8 @@
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
|
||||
using OpenMetaverse;
|
||||
using OpenMetaverse.StructuredData;
|
||||
|
||||
@@ -46,8 +46,12 @@ namespace OpenSim.Framework.Statistics
|
||||
sb.Append(Environment.NewLine);
|
||||
sb.Append(
|
||||
string.Format(
|
||||
"Allocated to OpenSim : {0} MB" + Environment.NewLine,
|
||||
"Allocated to OpenSim objects: {0} MB\n",
|
||||
Math.Round(GC.GetTotalMemory(false) / 1024.0 / 1024.0)));
|
||||
sb.Append(
|
||||
string.Format(
|
||||
"Process memory : {0} MB\n",
|
||||
Math.Round(Process.GetCurrentProcess().WorkingSet64 / 1024.0 / 1024.0)));
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
@@ -35,7 +35,8 @@ using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Reflection;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Runtime.Serialization.Formatters.Binary;
|
||||
using System.Security.Cryptography;
|
||||
@@ -80,12 +81,15 @@ namespace OpenSim.Framework
|
||||
|
||||
private static uint nextXferID = 5000;
|
||||
private static Random randomClass = new Random();
|
||||
|
||||
// Get a list of invalid file characters (OS dependent)
|
||||
private static string regexInvalidFileChars = "[" + new String(Path.GetInvalidFileNameChars()) + "]";
|
||||
private static string regexInvalidPathChars = "[" + new String(Path.GetInvalidPathChars()) + "]";
|
||||
private static object XferLock = new object();
|
||||
/// <summary>Thread pool used for Util.FireAndForget if
|
||||
/// FireAndForgetMethod.SmartThreadPool is used</summary>
|
||||
|
||||
/// <summary>
|
||||
/// Thread pool used for Util.FireAndForget if FireAndForgetMethod.SmartThreadPool is used
|
||||
/// </summary>
|
||||
private static SmartThreadPool m_ThreadPool;
|
||||
|
||||
// Unix-epoch starts at January 1st 1970, 00:00:00 UTC. And all our times in the server are (or at least should be) in UTC.
|
||||
@@ -143,7 +147,6 @@ namespace OpenSim.Framework
|
||||
return lerp(y, lerp(x, a, b), lerp(x, c, d));
|
||||
}
|
||||
|
||||
|
||||
public static Encoding UTF8 = Encoding.UTF8;
|
||||
|
||||
/// <value>
|
||||
@@ -375,6 +378,50 @@ namespace OpenSim.Framework
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is the platform Windows?
|
||||
/// </summary>
|
||||
/// <returns>true if so, false otherwise</returns>
|
||||
public static bool IsWindows()
|
||||
{
|
||||
PlatformID platformId = Environment.OSVersion.Platform;
|
||||
|
||||
return (platformId == PlatformID.Win32NT
|
||||
|| platformId == PlatformID.Win32S
|
||||
|| platformId == PlatformID.Win32Windows
|
||||
|| platformId == PlatformID.WinCE);
|
||||
}
|
||||
|
||||
public static bool LoadArchSpecificWindowsDll(string libraryName)
|
||||
{
|
||||
// We do this so that OpenSimulator on Windows loads the correct native library depending on whether
|
||||
// it's running as a 32-bit process or a 64-bit one. By invoking LoadLibary here, later DLLImports
|
||||
// will find it already loaded later on.
|
||||
//
|
||||
// This isn't necessary for other platforms (e.g. Mac OSX and Linux) since the DLL used can be
|
||||
// controlled in config files.
|
||||
string nativeLibraryPath;
|
||||
|
||||
if (Util.Is64BitProcess())
|
||||
nativeLibraryPath = "lib64/" + libraryName;
|
||||
else
|
||||
nativeLibraryPath = "lib32/" + libraryName;
|
||||
|
||||
m_log.DebugFormat("[UTIL]: Loading native Windows library at {0}", nativeLibraryPath);
|
||||
|
||||
if (Util.LoadLibrary(nativeLibraryPath) == IntPtr.Zero)
|
||||
{
|
||||
m_log.ErrorFormat(
|
||||
"[UTIL]: Couldn't find native Windows library at {0}", nativeLibraryPath);
|
||||
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsEnvironmentSupported(ref string reason)
|
||||
@@ -1457,6 +1504,27 @@ namespace OpenSim.Framework
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to trigger an early library load on Windows systems.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Required to get 32-bit and 64-bit processes to automatically use the
|
||||
/// appropriate native library.
|
||||
/// </remarks>
|
||||
/// <param name="dllToLoad"></param>
|
||||
/// <returns></returns>
|
||||
[DllImport("kernel32.dll")]
|
||||
public static extern IntPtr LoadLibrary(string dllToLoad);
|
||||
|
||||
/// <summary>
|
||||
/// Determine whether the current process is 64 bit
|
||||
/// </summary>
|
||||
/// <returns>true if so, false if not</returns>
|
||||
public static bool Is64BitProcess()
|
||||
{
|
||||
return IntPtr.Size == 8;
|
||||
}
|
||||
|
||||
#region FireAndForget Threading Pattern
|
||||
@@ -1605,6 +1673,61 @@ namespace OpenSim.Framework
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a thread pool report.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static string GetThreadPoolReport()
|
||||
{
|
||||
string threadPoolUsed = null;
|
||||
int maxThreads = 0;
|
||||
int minThreads = 0;
|
||||
int allocatedThreads = 0;
|
||||
int inUseThreads = 0;
|
||||
int waitingCallbacks = 0;
|
||||
int completionPortThreads = 0;
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (FireAndForgetMethod == FireAndForgetMethod.SmartThreadPool)
|
||||
{
|
||||
threadPoolUsed = "SmartThreadPool";
|
||||
maxThreads = m_ThreadPool.MaxThreads;
|
||||
minThreads = m_ThreadPool.MinThreads;
|
||||
inUseThreads = m_ThreadPool.InUseThreads;
|
||||
allocatedThreads = m_ThreadPool.ActiveThreads;
|
||||
waitingCallbacks = m_ThreadPool.WaitingCallbacks;
|
||||
}
|
||||
else if (
|
||||
FireAndForgetMethod == FireAndForgetMethod.UnsafeQueueUserWorkItem
|
||||
|| FireAndForgetMethod == FireAndForgetMethod.UnsafeQueueUserWorkItem)
|
||||
{
|
||||
threadPoolUsed = "BuiltInThreadPool";
|
||||
ThreadPool.GetMaxThreads(out maxThreads, out completionPortThreads);
|
||||
ThreadPool.GetMinThreads(out minThreads, out completionPortThreads);
|
||||
int availableThreads;
|
||||
ThreadPool.GetAvailableThreads(out availableThreads, out completionPortThreads);
|
||||
inUseThreads = maxThreads - availableThreads;
|
||||
allocatedThreads = -1;
|
||||
waitingCallbacks = -1;
|
||||
}
|
||||
|
||||
if (threadPoolUsed != null)
|
||||
{
|
||||
sb.AppendFormat("Thread pool used : {0}\n", threadPoolUsed);
|
||||
sb.AppendFormat("Max threads : {0}\n", maxThreads);
|
||||
sb.AppendFormat("Min threads : {0}\n", minThreads);
|
||||
sb.AppendFormat("Allocated threads : {0}\n", allocatedThreads < 0 ? "not applicable" : allocatedThreads.ToString());
|
||||
sb.AppendFormat("In use threads : {0}\n", inUseThreads);
|
||||
sb.AppendFormat("Work items waiting : {0}\n", waitingCallbacks < 0 ? "not available" : waitingCallbacks.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.AppendFormat("Thread pool not used\n");
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static object SmartThreadPoolCallback(object o)
|
||||
{
|
||||
object[] array = (object[])o;
|
||||
@@ -1630,6 +1753,20 @@ namespace OpenSim.Framework
|
||||
}
|
||||
const Int32 EnvironmentTickCountMask = 0x3fffffff;
|
||||
|
||||
/// <summary>
|
||||
/// Environment.TickCount is an int but it counts all 32 bits so it goes positive
|
||||
/// and negative every 24.9 days. Subtracts the passed value (previously fetched by
|
||||
/// 'EnvironmentTickCount()') and accounts for any wrapping.
|
||||
/// </summary>
|
||||
/// <param name="newValue"></param>
|
||||
/// <param name="prevValue"></param>
|
||||
/// <returns>subtraction of passed prevValue from current Environment.TickCount</returns>
|
||||
public static Int32 EnvironmentTickCountSubtract(Int32 newValue, Int32 prevValue)
|
||||
{
|
||||
Int32 diff = newValue - prevValue;
|
||||
return (diff >= 0) ? diff : (diff + EnvironmentTickCountMask + 1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Environment.TickCount is an int but it counts all 32 bits so it goes positive
|
||||
/// and negative every 24.9 days. Subtracts the passed value (previously fetched by
|
||||
@@ -1638,8 +1775,7 @@ namespace OpenSim.Framework
|
||||
/// <returns>subtraction of passed prevValue from current Environment.TickCount</returns>
|
||||
public static Int32 EnvironmentTickCountSubtract(Int32 prevValue)
|
||||
{
|
||||
Int32 diff = EnvironmentTickCount() - prevValue;
|
||||
return (diff >= 0) ? diff : (diff + EnvironmentTickCountMask + 1);
|
||||
return EnvironmentTickCountSubtract(EnvironmentTickCount(), prevValue);
|
||||
}
|
||||
|
||||
// Returns value of Tick Count A - TickCount B accounting for wrapping of TickCount
|
||||
|
||||
@@ -72,6 +72,11 @@ namespace OpenSim.Framework
|
||||
/// </summary>
|
||||
public bool IsTimedOut { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Will this thread trigger the alarm function if it has timed out?
|
||||
/// </summary>
|
||||
public bool AlarmIfTimeout { get; set; }
|
||||
|
||||
public ThreadWatchdogInfo(Thread thread, int timeout)
|
||||
{
|
||||
Thread = thread;
|
||||
@@ -112,12 +117,13 @@ namespace OpenSim.Framework
|
||||
/// <param name="start">The method that will be executed in a new thread</param>
|
||||
/// <param name="name">A name to give to the new thread</param>
|
||||
/// <param name="priority">Priority to run the thread at</param>
|
||||
/// <param name="isBackground">True to run this thread as a background
|
||||
/// thread, otherwise false</param>
|
||||
/// <param name="isBackground">True to run this thread as a background thread, otherwise false</param>
|
||||
/// <param name="alarmIfTimeout">Trigger an alarm function is we have timed out</param>
|
||||
/// <returns>The newly created Thread object</returns>
|
||||
public static Thread StartThread(ThreadStart start, string name, ThreadPriority priority, bool isBackground)
|
||||
public static Thread StartThread(
|
||||
ThreadStart start, string name, ThreadPriority priority, bool isBackground, bool alarmIfTimeout)
|
||||
{
|
||||
return StartThread(start, name, priority, isBackground, WATCHDOG_TIMEOUT_MS);
|
||||
return StartThread(start, name, priority, isBackground, alarmIfTimeout, WATCHDOG_TIMEOUT_MS);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -128,21 +134,21 @@ namespace OpenSim.Framework
|
||||
/// <param name="priority">Priority to run the thread at</param>
|
||||
/// <param name="isBackground">True to run this thread as a background
|
||||
/// thread, otherwise false</param>
|
||||
/// <param name="timeout">
|
||||
/// Number of milliseconds to wait until we issue a warning about timeout.
|
||||
/// </para>
|
||||
/// <param name="alarmIfTimeout">Trigger an alarm function is we have timed out</param>
|
||||
/// <param name="timeout">Number of milliseconds to wait until we issue a warning about timeout.</param>
|
||||
/// <returns>The newly created Thread object</returns>
|
||||
public static Thread StartThread(
|
||||
ThreadStart start, string name, ThreadPriority priority, bool isBackground, int timeout)
|
||||
ThreadStart start, string name, ThreadPriority priority, bool isBackground, bool alarmIfTimeout, int timeout)
|
||||
{
|
||||
Thread thread = new Thread(start);
|
||||
thread.Name = name;
|
||||
thread.Priority = priority;
|
||||
thread.IsBackground = isBackground;
|
||||
|
||||
ThreadWatchdogInfo twi = new ThreadWatchdogInfo(thread, timeout);
|
||||
ThreadWatchdogInfo twi = new ThreadWatchdogInfo(thread, timeout) { AlarmIfTimeout = alarmIfTimeout };
|
||||
|
||||
m_log.Debug("[WATCHDOG]: Started tracking thread \"" + twi.Thread.Name + "\" (ID " + twi.Thread.ManagedThreadId + ")");
|
||||
m_log.DebugFormat(
|
||||
"[WATCHDOG]: Started tracking thread {0}, ID {1}", twi.Thread.Name, twi.Thread.ManagedThreadId);
|
||||
|
||||
lock (m_threads)
|
||||
m_threads.Add(twi.Thread.ManagedThreadId, twi);
|
||||
@@ -224,19 +230,39 @@ namespace OpenSim.Framework
|
||||
/// Get currently watched threads for diagnostic purposes
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static ThreadWatchdogInfo[] GetThreads()
|
||||
public static ThreadWatchdogInfo[] GetThreadsInfo()
|
||||
{
|
||||
lock (m_threads)
|
||||
return m_threads.Values.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the current thread's watchdog info.
|
||||
/// </summary>
|
||||
/// <returns>The watchdog info. null if the thread isn't being monitored.</returns>
|
||||
public static ThreadWatchdogInfo GetCurrentThreadInfo()
|
||||
{
|
||||
lock (m_threads)
|
||||
{
|
||||
if (m_threads.ContainsKey(Thread.CurrentThread.ManagedThreadId))
|
||||
return m_threads[Thread.CurrentThread.ManagedThreadId];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check watched threads. Fire alarm if appropriate.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private static void WatchdogTimerElapsed(object sender, System.Timers.ElapsedEventArgs e)
|
||||
{
|
||||
WatchdogTimeout callback = OnWatchdogTimeout;
|
||||
|
||||
if (callback != null)
|
||||
{
|
||||
ThreadWatchdogInfo timedOut = null;
|
||||
List<ThreadWatchdogInfo> callbackInfos = null;
|
||||
|
||||
lock (m_threads)
|
||||
{
|
||||
@@ -246,21 +272,31 @@ namespace OpenSim.Framework
|
||||
{
|
||||
if (threadInfo.Thread.ThreadState == ThreadState.Stopped)
|
||||
{
|
||||
timedOut = threadInfo;
|
||||
RemoveThread(threadInfo.Thread.ManagedThreadId);
|
||||
break;
|
||||
|
||||
if (callbackInfos == null)
|
||||
callbackInfos = new List<ThreadWatchdogInfo>();
|
||||
|
||||
callbackInfos.Add(threadInfo);
|
||||
}
|
||||
else if (!threadInfo.IsTimedOut && now - threadInfo.LastTick >= threadInfo.Timeout)
|
||||
{
|
||||
threadInfo.IsTimedOut = true;
|
||||
timedOut = threadInfo;
|
||||
break;
|
||||
|
||||
if (threadInfo.AlarmIfTimeout)
|
||||
{
|
||||
if (callbackInfos == null)
|
||||
callbackInfos = new List<ThreadWatchdogInfo>();
|
||||
|
||||
callbackInfos.Add(threadInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (timedOut != null)
|
||||
callback(timedOut.Thread, timedOut.LastTick);
|
||||
if (callbackInfos != null)
|
||||
foreach (ThreadWatchdogInfo callbackInfo in callbackInfos)
|
||||
callback(callbackInfo.Thread, callbackInfo.LastTick);
|
||||
}
|
||||
|
||||
m_watchdogTimer.Start();
|
||||
|
||||
@@ -53,45 +53,36 @@ namespace OpenSim.Framework
|
||||
LogManager.GetLogger(
|
||||
MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private static int m_requestNumber = 0;
|
||||
/// <summary>
|
||||
/// Request number for diagnostic purposes.
|
||||
/// </summary>
|
||||
public static int RequestNumber = 0;
|
||||
|
||||
// this is the header field used to communicate the local request id
|
||||
// used for performance and debugging
|
||||
/// <summary>
|
||||
/// this is the header field used to communicate the local request id
|
||||
/// used for performance and debugging
|
||||
/// </summary>
|
||||
public const string OSHeaderRequestID = "opensim-request-id";
|
||||
|
||||
// number of milliseconds a call can take before it is considered
|
||||
// a "long" call for warning & debugging purposes
|
||||
public const int LongCallTime = 500;
|
||||
/// <summary>
|
||||
/// Number of milliseconds a call can take before it is considered
|
||||
/// a "long" call for warning & debugging purposes
|
||||
/// </summary>
|
||||
public const int LongCallTime = 3000;
|
||||
|
||||
// /// <summary>
|
||||
// /// Send LLSD to an HTTP client in application/llsd+json form
|
||||
// /// </summary>
|
||||
// /// <param name="response">HTTP response to send the data in</param>
|
||||
// /// <param name="body">LLSD to send to the client</param>
|
||||
// public static void SendJSONResponse(OSHttpResponse response, OSDMap body)
|
||||
// {
|
||||
// byte[] responseData = Encoding.UTF8.GetBytes(OSDParser.SerializeJsonString(body));
|
||||
//
|
||||
// response.ContentEncoding = Encoding.UTF8;
|
||||
// response.ContentLength = responseData.Length;
|
||||
// response.ContentType = "application/llsd+json";
|
||||
// response.Body.Write(responseData, 0, responseData.Length);
|
||||
// }
|
||||
//
|
||||
// /// <summary>
|
||||
// /// Send LLSD to an HTTP client in application/llsd+xml form
|
||||
// /// </summary>
|
||||
// /// <param name="response">HTTP response to send the data in</param>
|
||||
// /// <param name="body">LLSD to send to the client</param>
|
||||
// public static void SendXMLResponse(OSHttpResponse response, OSDMap body)
|
||||
// {
|
||||
// byte[] responseData = OSDParser.SerializeLLSDXmlBytes(body);
|
||||
//
|
||||
// response.ContentEncoding = Encoding.UTF8;
|
||||
// response.ContentLength = responseData.Length;
|
||||
// response.ContentType = "application/llsd+xml";
|
||||
// response.Body.Write(responseData, 0, responseData.Length);
|
||||
// }
|
||||
/// <summary>
|
||||
/// The maximum length of any data logged because of a long request time.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is to truncate any really large post data, such as an asset. In theory, the first section should
|
||||
/// give us useful information about the call (which agent it relates to if applicable, etc.).
|
||||
/// </remarks>
|
||||
public const int MaxRequestDiagLength = 100;
|
||||
|
||||
/// <summary>
|
||||
/// Dictionary of end points
|
||||
/// </summary>
|
||||
private static Dictionary<string,object> m_endpointSerializer = new Dictionary<string,object>();
|
||||
|
||||
/// <summary>
|
||||
/// Make a GET or GET-like request to a web service that returns LLSD
|
||||
@@ -166,12 +157,14 @@ namespace OpenSim.Framework
|
||||
|
||||
public static OSDMap ServiceOSDRequest(string url, OSDMap data, string method, int timeout, bool compressed)
|
||||
{
|
||||
int reqnum = m_requestNumber++;
|
||||
int reqnum = RequestNumber++;
|
||||
|
||||
// m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method);
|
||||
|
||||
string errorMessage = "unknown error";
|
||||
int tickstart = Util.EnvironmentTickCount();
|
||||
int tickdata = 0;
|
||||
string strBuffer = null;
|
||||
|
||||
try
|
||||
{
|
||||
@@ -186,7 +179,7 @@ namespace OpenSim.Framework
|
||||
// If there is some input, write it into the request
|
||||
if (data != null)
|
||||
{
|
||||
string strBuffer = OSDParser.SerializeJsonString(data);
|
||||
strBuffer = OSDParser.SerializeJsonString(data);
|
||||
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(strBuffer);
|
||||
|
||||
if (compressed)
|
||||
@@ -246,14 +239,23 @@ namespace OpenSim.Framework
|
||||
}
|
||||
finally
|
||||
{
|
||||
// This just dumps a warning for any operation that takes more than 100 ms
|
||||
int tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
|
||||
if (tickdiff > LongCallTime)
|
||||
m_log.DebugFormat("[WEB UTIL]: osd request <{0}> (URI:{1}, METHOD:{2}) took {3}ms overall, {4}ms writing",
|
||||
reqnum,url,method,tickdiff,tickdata);
|
||||
m_log.InfoFormat(
|
||||
"[OSD REQUEST]: Slow request to <{0}> {1} {2} took {3}ms, {4}ms writing, {5}",
|
||||
reqnum,
|
||||
method,
|
||||
url,
|
||||
tickdiff,
|
||||
tickdata,
|
||||
strBuffer != null
|
||||
? (strBuffer.Length > MaxRequestDiagLength ? strBuffer.Remove(MaxRequestDiagLength) : strBuffer)
|
||||
: "");
|
||||
}
|
||||
|
||||
m_log.DebugFormat("[WEB UTIL]: <{0}> osd request for {1}, method {2} FAILED: {3}", reqnum, url, method, errorMessage);
|
||||
m_log.DebugFormat(
|
||||
"[WEB UTIL]: <{0}> osd request for {1}, method {2} FAILED: {3}", reqnum, url, method, errorMessage);
|
||||
|
||||
return ErrorResponseMap(errorMessage);
|
||||
}
|
||||
|
||||
@@ -314,17 +316,17 @@ namespace OpenSim.Framework
|
||||
|
||||
public static OSDMap ServiceFormRequest(string url, NameValueCollection data, int timeout)
|
||||
{
|
||||
int reqnum = m_requestNumber++;
|
||||
int reqnum = RequestNumber++;
|
||||
string method = (data != null && data["RequestMethod"] != null) ? data["RequestMethod"] : "unknown";
|
||||
// m_log.DebugFormat("[WEB UTIL]: <{0}> start form request for {1}, method {2}",reqnum,url,method);
|
||||
|
||||
string errorMessage = "unknown error";
|
||||
int tickstart = Util.EnvironmentTickCount();
|
||||
int tickdata = 0;
|
||||
string queryString = null;
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
|
||||
request.Method = "POST";
|
||||
request.Timeout = timeout;
|
||||
@@ -335,7 +337,7 @@ namespace OpenSim.Framework
|
||||
|
||||
if (data != null)
|
||||
{
|
||||
string queryString = BuildQueryString(data);
|
||||
queryString = BuildQueryString(data);
|
||||
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(queryString);
|
||||
|
||||
request.ContentLength = buffer.Length;
|
||||
@@ -378,11 +380,20 @@ namespace OpenSim.Framework
|
||||
{
|
||||
int tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
|
||||
if (tickdiff > LongCallTime)
|
||||
m_log.InfoFormat("[WEB UTIL]: form request <{0}> (URI:{1}, METHOD:{2}) took {3}ms overall, {4}ms writing",
|
||||
reqnum,url,method,tickdiff,tickdata);
|
||||
m_log.InfoFormat(
|
||||
"[SERVICE FORM]: Slow request to <{0}> {1} {2} took {3}ms, {4}ms writing, {5}",
|
||||
reqnum,
|
||||
method,
|
||||
url,
|
||||
tickdiff,
|
||||
tickdata,
|
||||
queryString != null
|
||||
? (queryString.Length > MaxRequestDiagLength) ? queryString.Remove(MaxRequestDiagLength) : queryString
|
||||
: "");
|
||||
}
|
||||
|
||||
m_log.WarnFormat("[WEB UTIL]: <{0}> form request failed: {1}",reqnum,errorMessage);
|
||||
m_log.WarnFormat("[SERVICE FORM]: <{0}> form request to {1} failed: {2}", reqnum, url, errorMessage);
|
||||
|
||||
return ErrorResponseMap(errorMessage);
|
||||
}
|
||||
|
||||
@@ -655,8 +666,6 @@ namespace OpenSim.Framework
|
||||
|
||||
return new string[0];
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static class AsynchronousRestObjectRequester
|
||||
@@ -679,6 +688,12 @@ namespace OpenSim.Framework
|
||||
public static void MakeRequest<TRequest, TResponse>(string verb,
|
||||
string requestUrl, TRequest obj, Action<TResponse> action)
|
||||
{
|
||||
int reqnum = WebUtil.RequestNumber++;
|
||||
// m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method);
|
||||
|
||||
int tickstart = Util.EnvironmentTickCount();
|
||||
int tickdata = 0;
|
||||
|
||||
// m_log.DebugFormat("[ASYNC REQUEST]: Starting {0} {1}", verb, requestUrl);
|
||||
|
||||
Type type = typeof(TRequest);
|
||||
@@ -689,12 +704,13 @@ namespace OpenSim.Framework
|
||||
XmlSerializer deserializer = new XmlSerializer(typeof(TResponse));
|
||||
|
||||
request.Method = verb;
|
||||
MemoryStream buffer = null;
|
||||
|
||||
if (verb == "POST")
|
||||
{
|
||||
request.ContentType = "text/xml";
|
||||
|
||||
MemoryStream buffer = new MemoryStream();
|
||||
buffer = new MemoryStream();
|
||||
|
||||
XmlWriterSettings settings = new XmlWriterSettings();
|
||||
settings.Encoding = Encoding.UTF8;
|
||||
@@ -716,6 +732,9 @@ namespace OpenSim.Framework
|
||||
requestStream.Write(buffer.ToArray(), 0, length);
|
||||
requestStream.Close();
|
||||
|
||||
// capture how much time was spent writing
|
||||
tickdata = Util.EnvironmentTickCountSubtract(tickstart);
|
||||
|
||||
request.BeginGetResponse(delegate(IAsyncResult ar)
|
||||
{
|
||||
response = request.EndGetResponse(ar);
|
||||
@@ -741,83 +760,108 @@ namespace OpenSim.Framework
|
||||
|
||||
}, null);
|
||||
}, null);
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
request.BeginGetResponse(delegate(IAsyncResult res2)
|
||||
else
|
||||
{
|
||||
try
|
||||
request.BeginGetResponse(delegate(IAsyncResult res2)
|
||||
{
|
||||
// If the server returns a 404, this appears to trigger a System.Net.WebException even though that isn't
|
||||
// documented in MSDN
|
||||
response = request.EndGetResponse(res2);
|
||||
|
||||
Stream respStream = null;
|
||||
try
|
||||
{
|
||||
respStream = response.GetResponseStream();
|
||||
deserial = (TResponse)deserializer.Deserialize(respStream);
|
||||
}
|
||||
catch (System.InvalidOperationException)
|
||||
{
|
||||
}
|
||||
finally
|
||||
{
|
||||
respStream.Close();
|
||||
response.Close();
|
||||
}
|
||||
}
|
||||
catch (WebException e)
|
||||
{
|
||||
if (e.Status == WebExceptionStatus.ProtocolError)
|
||||
{
|
||||
if (e.Response is HttpWebResponse)
|
||||
// If the server returns a 404, this appears to trigger a System.Net.WebException even though that isn't
|
||||
// documented in MSDN
|
||||
response = request.EndGetResponse(res2);
|
||||
|
||||
Stream respStream = null;
|
||||
try
|
||||
{
|
||||
HttpWebResponse httpResponse = (HttpWebResponse)e.Response;
|
||||
|
||||
if (httpResponse.StatusCode != HttpStatusCode.NotFound)
|
||||
{
|
||||
// We don't appear to be handling any other status codes, so log these feailures to that
|
||||
// people don't spend unnecessary hours hunting phantom bugs.
|
||||
m_log.DebugFormat(
|
||||
"[ASYNC REQUEST]: Request {0} {1} failed with unexpected status code {2}",
|
||||
verb, requestUrl, httpResponse.StatusCode);
|
||||
}
|
||||
respStream = response.GetResponseStream();
|
||||
deserial = (TResponse)deserializer.Deserialize(respStream);
|
||||
}
|
||||
catch (System.InvalidOperationException)
|
||||
{
|
||||
}
|
||||
finally
|
||||
{
|
||||
respStream.Close();
|
||||
response.Close();
|
||||
}
|
||||
}
|
||||
else
|
||||
catch (WebException e)
|
||||
{
|
||||
m_log.ErrorFormat("[ASYNC REQUEST]: Request {0} {1} failed with status {2} and message {3}", verb, requestUrl, e.Status, e.Message);
|
||||
if (e.Status == WebExceptionStatus.ProtocolError)
|
||||
{
|
||||
if (e.Response is HttpWebResponse)
|
||||
{
|
||||
HttpWebResponse httpResponse = (HttpWebResponse)e.Response;
|
||||
|
||||
if (httpResponse.StatusCode != HttpStatusCode.NotFound)
|
||||
{
|
||||
// We don't appear to be handling any other status codes, so log these feailures to that
|
||||
// people don't spend unnecessary hours hunting phantom bugs.
|
||||
m_log.DebugFormat(
|
||||
"[ASYNC REQUEST]: Request {0} {1} failed with unexpected status code {2}",
|
||||
verb, requestUrl, httpResponse.StatusCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.ErrorFormat(
|
||||
"[ASYNC REQUEST]: Request {0} {1} failed with status {2} and message {3}",
|
||||
verb, requestUrl, e.Status, e.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat(
|
||||
"[ASYNC REQUEST]: Request {0} {1} failed with exception {2}{3}",
|
||||
verb, requestUrl, e.Message, e.StackTrace);
|
||||
}
|
||||
|
||||
// m_log.DebugFormat("[ASYNC REQUEST]: Received {0}", deserial.ToString());
|
||||
|
||||
try
|
||||
{
|
||||
action(deserial);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat(
|
||||
"[ASYNC REQUEST]: Request {0} {1} callback failed with exception {2}{3}",
|
||||
verb, requestUrl, e.Message, e.StackTrace);
|
||||
}
|
||||
|
||||
}, null);
|
||||
}
|
||||
|
||||
int tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
|
||||
if (tickdiff > WebUtil.LongCallTime)
|
||||
{
|
||||
string originalRequest = null;
|
||||
|
||||
if (buffer != null)
|
||||
{
|
||||
m_log.ErrorFormat("[ASYNC REQUEST]: Request {0} {1} failed with exception {2}", verb, requestUrl, e);
|
||||
originalRequest = Encoding.UTF8.GetString(buffer.ToArray());
|
||||
|
||||
if (originalRequest.Length > WebUtil.MaxRequestDiagLength)
|
||||
originalRequest = originalRequest.Remove(WebUtil.MaxRequestDiagLength);
|
||||
}
|
||||
|
||||
// m_log.DebugFormat("[ASYNC REQUEST]: Received {0}", deserial.ToString());
|
||||
|
||||
try
|
||||
{
|
||||
action(deserial);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat(
|
||||
"[ASYNC REQUEST]: Request {0} {1} callback failed with exception {2}", verb, requestUrl, e);
|
||||
}
|
||||
|
||||
}, null);
|
||||
m_log.InfoFormat(
|
||||
"[ASYNC REQUEST]: Slow request to <{0}> {1} {2} took {3}ms, {4}ms writing, {5}",
|
||||
reqnum,
|
||||
verb,
|
||||
requestUrl,
|
||||
tickdiff,
|
||||
tickdata,
|
||||
originalRequest);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class SynchronousRestFormsRequester
|
||||
{
|
||||
private static readonly ILog m_log =
|
||||
LogManager.GetLogger(
|
||||
MethodBase.GetCurrentMethod().DeclaringType);
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
/// <summary>
|
||||
/// Perform a synchronous REST request.
|
||||
@@ -831,6 +875,12 @@ namespace OpenSim.Framework
|
||||
/// the request. You'll want to make sure you deal with this as they're not uncommon</exception>
|
||||
public static string MakeRequest(string verb, string requestUrl, string obj)
|
||||
{
|
||||
int reqnum = WebUtil.RequestNumber++;
|
||||
// m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method);
|
||||
|
||||
int tickstart = Util.EnvironmentTickCount();
|
||||
int tickdata = 0;
|
||||
|
||||
WebRequest request = WebRequest.Create(requestUrl);
|
||||
request.Method = verb;
|
||||
string respstring = String.Empty;
|
||||
@@ -859,12 +909,16 @@ namespace OpenSim.Framework
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[FORMS]: exception occured on sending request to {0}: " + e.ToString(), requestUrl);
|
||||
m_log.DebugFormat(
|
||||
"[FORMS]: exception occured {0} {1}: {2}{3}", verb, requestUrl, e.Message, e.StackTrace);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (requestStream != null)
|
||||
requestStream.Close();
|
||||
|
||||
// capture how much time was spent writing
|
||||
tickdata = Util.EnvironmentTickCountSubtract(tickstart);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -885,7 +939,9 @@ namespace OpenSim.Framework
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[FORMS]: exception occured on receiving reply " + e.ToString());
|
||||
m_log.DebugFormat(
|
||||
"[FORMS]: Exception occured on receiving {0} {1}: {2}{3}",
|
||||
verb, requestUrl, e.Message, e.StackTrace);
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -898,9 +954,21 @@ namespace OpenSim.Framework
|
||||
catch (System.InvalidOperationException)
|
||||
{
|
||||
// This is what happens when there is invalid XML
|
||||
m_log.DebugFormat("[FORMS]: InvalidOperationException on receiving request");
|
||||
m_log.DebugFormat("[FORMS]: InvalidOperationException on receiving {0} {1}", verb, requestUrl);
|
||||
}
|
||||
}
|
||||
|
||||
int tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
|
||||
if (tickdiff > WebUtil.LongCallTime)
|
||||
m_log.InfoFormat(
|
||||
"[FORMS]: Slow request to <{0}> {1} {2} took {3}ms, {4}ms writing, {5}",
|
||||
reqnum,
|
||||
verb,
|
||||
requestUrl,
|
||||
tickdiff,
|
||||
tickdata,
|
||||
obj.Length > WebUtil.MaxRequestDiagLength ? obj.Remove(WebUtil.MaxRequestDiagLength) : obj);
|
||||
|
||||
return respstring;
|
||||
}
|
||||
}
|
||||
@@ -923,17 +991,24 @@ namespace OpenSim.Framework
|
||||
/// the request. You'll want to make sure you deal with this as they're not uncommon</exception>
|
||||
public static TResponse MakeRequest<TRequest, TResponse>(string verb, string requestUrl, TRequest obj)
|
||||
{
|
||||
int reqnum = WebUtil.RequestNumber++;
|
||||
// m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method);
|
||||
|
||||
int tickstart = Util.EnvironmentTickCount();
|
||||
int tickdata = 0;
|
||||
|
||||
Type type = typeof(TRequest);
|
||||
TResponse deserial = default(TResponse);
|
||||
|
||||
WebRequest request = WebRequest.Create(requestUrl);
|
||||
request.Method = verb;
|
||||
MemoryStream buffer = null;
|
||||
|
||||
if ((verb == "POST") || (verb == "PUT"))
|
||||
{
|
||||
request.ContentType = "text/xml";
|
||||
|
||||
MemoryStream buffer = new MemoryStream();
|
||||
buffer = new MemoryStream();
|
||||
|
||||
XmlWriterSettings settings = new XmlWriterSettings();
|
||||
settings.Encoding = Encoding.UTF8;
|
||||
@@ -956,13 +1031,19 @@ namespace OpenSim.Framework
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[SynchronousRestObjectRequester]: exception in sending data to {0}: {1}", requestUrl, e);
|
||||
m_log.DebugFormat(
|
||||
"[SynchronousRestObjectRequester]: Exception in making request {0} {1}: {2}{3}",
|
||||
verb, requestUrl, e.Message, e.StackTrace);
|
||||
|
||||
return deserial;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (requestStream != null)
|
||||
requestStream.Close();
|
||||
|
||||
// capture how much time was spent writing
|
||||
tickdata = Util.EnvironmentTickCountSubtract(tickstart);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -978,7 +1059,11 @@ namespace OpenSim.Framework
|
||||
respStream.Close();
|
||||
}
|
||||
else
|
||||
m_log.DebugFormat("[SynchronousRestObjectRequester]: Oops! no content found in response stream from {0} {1}", requestUrl, verb);
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"[SynchronousRestObjectRequester]: Oops! no content found in response stream from {0} {1}",
|
||||
verb, requestUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (WebException e)
|
||||
@@ -989,17 +1074,44 @@ namespace OpenSim.Framework
|
||||
return deserial;
|
||||
else
|
||||
m_log.ErrorFormat(
|
||||
"[SynchronousRestObjectRequester]: WebException {0} {1} {2} {3}",
|
||||
requestUrl, typeof(TResponse).ToString(), e.Message, e.StackTrace);
|
||||
"[SynchronousRestObjectRequester]: WebException for {0} {1} {2}: {3} {4}",
|
||||
verb, requestUrl, typeof(TResponse).ToString(), e.Message, e.StackTrace);
|
||||
}
|
||||
catch (System.InvalidOperationException)
|
||||
{
|
||||
// This is what happens when there is invalid XML
|
||||
m_log.DebugFormat("[SynchronousRestObjectRequester]: Invalid XML {0} {1}", requestUrl, typeof(TResponse).ToString());
|
||||
m_log.DebugFormat(
|
||||
"[SynchronousRestObjectRequester]: Invalid XML from {0} {1} {2}",
|
||||
verb, requestUrl, typeof(TResponse).ToString());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[SynchronousRestObjectRequester]: Exception on response from {0} {1}", requestUrl, e);
|
||||
m_log.DebugFormat(
|
||||
"[SynchronousRestObjectRequester]: Exception on response from {0} {1}: {2}{3}",
|
||||
verb, requestUrl, e.Message, e.StackTrace);
|
||||
}
|
||||
|
||||
int tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
|
||||
if (tickdiff > WebUtil.LongCallTime)
|
||||
{
|
||||
string originalRequest = null;
|
||||
|
||||
if (buffer != null)
|
||||
{
|
||||
originalRequest = Encoding.UTF8.GetString(buffer.ToArray());
|
||||
|
||||
if (originalRequest.Length > WebUtil.MaxRequestDiagLength)
|
||||
originalRequest = originalRequest.Remove(WebUtil.MaxRequestDiagLength);
|
||||
}
|
||||
|
||||
m_log.InfoFormat(
|
||||
"[SynchronousRestObjectRequester]: Slow request to <{0}> {1} {2} took {3}ms, {4}ms writing, {5}",
|
||||
reqnum,
|
||||
verb,
|
||||
requestUrl,
|
||||
tickdiff,
|
||||
tickdata,
|
||||
originalRequest);
|
||||
}
|
||||
|
||||
return deserial;
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
@@ -138,7 +139,7 @@ namespace OpenSim
|
||||
m_log.Info("====================================================================");
|
||||
m_log.Info("========================= STARTING OPENSIM =========================");
|
||||
m_log.Info("====================================================================");
|
||||
|
||||
|
||||
//m_log.InfoFormat("[OPENSIM MAIN]: GC Is Server GC: {0}", GCSettings.IsServerGC.ToString());
|
||||
// http://msdn.microsoft.com/en-us/library/bb384202.aspx
|
||||
//GCSettings.LatencyMode = GCLatencyMode.Batch;
|
||||
@@ -225,12 +226,12 @@ namespace OpenSim
|
||||
/// </summary>
|
||||
private void RegisterConsoleCommands()
|
||||
{
|
||||
m_console.Commands.AddCommand("region", false, "force update",
|
||||
m_console.Commands.AddCommand("Objects", false, "force update",
|
||||
"force update",
|
||||
"Force the update of all objects on clients",
|
||||
HandleForceUpdate);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "debug packet",
|
||||
m_console.Commands.AddCommand("Comms", false, "debug packet",
|
||||
"debug packet <level> [<avatar-first-name> <avatar-last-name>]",
|
||||
"Turn on packet debugging",
|
||||
"If level > 255 then all incoming and outgoing packets are logged.\n"
|
||||
@@ -242,7 +243,7 @@ namespace OpenSim
|
||||
+ "If an avatar name is given then only packets from that avatar are logged",
|
||||
Debug);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "debug http",
|
||||
m_console.Commands.AddCommand("Comms", false, "debug http",
|
||||
"debug http <level>",
|
||||
"Turn on inbound http request debugging for everything except the event queue (see debug eq).",
|
||||
"If level >= 2 then the handler used to service the request is logged.\n"
|
||||
@@ -250,37 +251,37 @@ namespace OpenSim
|
||||
+ "If level <= 0 then no extra http logging is done.\n",
|
||||
Debug);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "debug teleport", "debug teleport", "Toggle teleport route debugging", Debug);
|
||||
m_console.Commands.AddCommand("Comms", false, "debug teleport", "debug teleport", "Toggle teleport route debugging", Debug);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "debug scene",
|
||||
m_console.Commands.AddCommand("Regions", false, "debug scene",
|
||||
"debug scene <scripting> <collisions> <physics>",
|
||||
"Turn on scene debugging", Debug);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "change region",
|
||||
m_console.Commands.AddCommand("General", false, "change region",
|
||||
"change region <region name>",
|
||||
"Change current console region", ChangeSelectedRegion);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "save xml",
|
||||
m_console.Commands.AddCommand("Archiving", false, "save xml",
|
||||
"save xml",
|
||||
"Save a region's data in XML format", SaveXml);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "save xml2",
|
||||
m_console.Commands.AddCommand("Archiving", false, "save xml2",
|
||||
"save xml2",
|
||||
"Save a region's data in XML2 format", SaveXml2);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "load xml",
|
||||
m_console.Commands.AddCommand("Archiving", false, "load xml",
|
||||
"load xml [-newIDs [<x> <y> <z>]]",
|
||||
"Load a region's data from XML format", LoadXml);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "load xml2",
|
||||
m_console.Commands.AddCommand("Archiving", false, "load xml2",
|
||||
"load xml2",
|
||||
"Load a region's data from XML2 format", LoadXml2);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "save prims xml2",
|
||||
m_console.Commands.AddCommand("Archiving", false, "save prims xml2",
|
||||
"save prims xml2 [<prim name> <file name>]",
|
||||
"Save named prim to XML2", SavePrimsXml2);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "load oar",
|
||||
m_console.Commands.AddCommand("Archiving", false, "load oar",
|
||||
"load oar [--merge] [--skip-assets] [<OAR path>]",
|
||||
"Load a region's data from an OAR archive.",
|
||||
"--merge will merge the OAR with the existing scene." + Environment.NewLine
|
||||
@@ -289,7 +290,7 @@ namespace OpenSim
|
||||
+ " If this is not given then the command looks for an OAR named region.oar in the current directory.",
|
||||
LoadOar);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "save oar",
|
||||
m_console.Commands.AddCommand("Archiving", false, "save oar",
|
||||
//"save oar [-v|--version=<N>] [-p|--profile=<url>] [<OAR path>]",
|
||||
"save oar [-h|--home=<url>] [--noassets] [--publish] [--perm=<permissions>] [<OAR path>]",
|
||||
"Save a region's data to an OAR archive.",
|
||||
@@ -306,54 +307,54 @@ namespace OpenSim
|
||||
+ " If this is not given then the oar is saved to region.oar in the current directory.",
|
||||
SaveOar);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "edit scale",
|
||||
m_console.Commands.AddCommand("Objects", false, "edit scale",
|
||||
"edit scale <name> <x> <y> <z>",
|
||||
"Change the scale of a named prim", HandleEditScale);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "kick user",
|
||||
m_console.Commands.AddCommand("Users", false, "kick user",
|
||||
"kick user <first> <last> [message]",
|
||||
"Kick a user off the simulator", KickUserCommand);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "show users",
|
||||
m_console.Commands.AddCommand("Users", false, "show users",
|
||||
"show users [full]",
|
||||
"Show user data for users currently on the region",
|
||||
"Without the 'full' option, only users actually on the region are shown."
|
||||
+ " With the 'full' option child agents of users in neighbouring regions are also shown.",
|
||||
HandleShow);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "show connections",
|
||||
m_console.Commands.AddCommand("Comms", false, "show connections",
|
||||
"show connections",
|
||||
"Show connection data", HandleShow);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "show circuits",
|
||||
m_console.Commands.AddCommand("Comms", false, "show circuits",
|
||||
"show circuits",
|
||||
"Show agent circuit data", HandleShow);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "show http-handlers",
|
||||
m_console.Commands.AddCommand("Comms", false, "show http-handlers",
|
||||
"show http-handlers",
|
||||
"Show all registered http handlers", HandleShow);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "show pending-objects",
|
||||
m_console.Commands.AddCommand("Comms", false, "show pending-objects",
|
||||
"show pending-objects",
|
||||
"Show # of objects on the pending queues of all scene viewers", HandleShow);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "show modules",
|
||||
m_console.Commands.AddCommand("General", false, "show modules",
|
||||
"show modules",
|
||||
"Show module data", HandleShow);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "show regions",
|
||||
m_console.Commands.AddCommand("Regions", false, "show regions",
|
||||
"show regions",
|
||||
"Show region data", HandleShow);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "show ratings",
|
||||
m_console.Commands.AddCommand("Regions", false, "show ratings",
|
||||
"show ratings",
|
||||
"Show rating data", HandleShow);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "backup",
|
||||
m_console.Commands.AddCommand("Objects", false, "backup",
|
||||
"backup",
|
||||
"Persist currently unsaved object changes immediately instead of waiting for the normal persistence call.", RunCommand);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "create region",
|
||||
m_console.Commands.AddCommand("Regions", false, "create region",
|
||||
"create region [\"region name\"] <region_file.ini>",
|
||||
"Create a new region.",
|
||||
"The settings for \"region name\" are read from <region_file.ini>. Paths specified with <region_file.ini> are relative to your Regions directory, unless an absolute path is given."
|
||||
@@ -362,62 +363,57 @@ namespace OpenSim
|
||||
+ "If <region_file.ini> does not exist, it will be created.",
|
||||
HandleCreateRegion);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "restart",
|
||||
m_console.Commands.AddCommand("Regions", false, "restart",
|
||||
"restart",
|
||||
"Restart all sims in this instance", RunCommand);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "config set",
|
||||
m_console.Commands.AddCommand("General", false, "config set",
|
||||
"config set <section> <key> <value>",
|
||||
"Set a config option. In most cases this is not useful since changed parameters are not dynamically reloaded. Neither do changed parameters persist - you will have to change a config file manually and restart.", HandleConfig);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "config get",
|
||||
m_console.Commands.AddCommand("General", false, "config get",
|
||||
"config get [<section>] [<key>]",
|
||||
"Synonym for config show",
|
||||
HandleConfig);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "config show",
|
||||
m_console.Commands.AddCommand("General", false, "config show",
|
||||
"config show [<section>] [<key>]",
|
||||
"Show config information",
|
||||
"If neither section nor field are specified, then the whole current configuration is printed." + Environment.NewLine
|
||||
+ "If a section is given but not a field, then all fields in that section are printed.",
|
||||
HandleConfig);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "config save",
|
||||
m_console.Commands.AddCommand("General", false, "config save",
|
||||
"config save <path>",
|
||||
"Save current configuration to a file at the given path", HandleConfig);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "command-script",
|
||||
m_console.Commands.AddCommand("General", false, "command-script",
|
||||
"command-script <script>",
|
||||
"Run a command script from file", RunCommand);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "remove-region",
|
||||
m_console.Commands.AddCommand("Regions", false, "remove-region",
|
||||
"remove-region <name>",
|
||||
"Remove a region from this simulator", RunCommand);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "delete-region",
|
||||
m_console.Commands.AddCommand("Regions", false, "delete-region",
|
||||
"delete-region <name>",
|
||||
"Delete a region from disk", RunCommand);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "modules list",
|
||||
m_console.Commands.AddCommand("General", false, "modules list",
|
||||
"modules list",
|
||||
"List modules", HandleModules);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "modules load",
|
||||
m_console.Commands.AddCommand("General", false, "modules load",
|
||||
"modules load <name>",
|
||||
"Load a module", HandleModules);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "modules unload",
|
||||
m_console.Commands.AddCommand("General", false, "modules unload",
|
||||
"modules unload <name>",
|
||||
"Unload a module", HandleModules);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "Add-InventoryHost",
|
||||
"Add-InventoryHost <host>",
|
||||
String.Empty, RunCommand);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "kill uuid",
|
||||
m_console.Commands.AddCommand("Objects", false, "kill uuid",
|
||||
"kill uuid <UUID>",
|
||||
"Kill an object by UUID", KillUUID);
|
||||
|
||||
}
|
||||
|
||||
public override void ShutdownSpecific()
|
||||
@@ -829,14 +825,6 @@ namespace OpenSim
|
||||
case "restart":
|
||||
m_sceneManager.RestartCurrentScene();
|
||||
break;
|
||||
|
||||
case "Add-InventoryHost":
|
||||
if (cmdparams.Length > 0)
|
||||
{
|
||||
MainConsole.Instance.Output("Not implemented.");
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -928,7 +916,7 @@ namespace OpenSim
|
||||
break;
|
||||
|
||||
case "scene":
|
||||
if (args.Length == 5)
|
||||
if (args.Length == 4)
|
||||
{
|
||||
if (m_sceneManager.CurrentScene == null)
|
||||
{
|
||||
@@ -936,39 +924,21 @@ namespace OpenSim
|
||||
}
|
||||
else
|
||||
{
|
||||
bool scriptingOn = !Convert.ToBoolean(args[2]);
|
||||
bool collisionsOn = !Convert.ToBoolean(args[3]);
|
||||
bool physicsOn = !Convert.ToBoolean(args[4]);
|
||||
m_sceneManager.CurrentScene.SetSceneCoreDebug(scriptingOn, collisionsOn, physicsOn);
|
||||
string key = args[2];
|
||||
string value = args[3];
|
||||
m_sceneManager.CurrentScene.SetSceneCoreDebug(
|
||||
new Dictionary<string, string>() { { key, value } });
|
||||
|
||||
MainConsole.Instance.Output(
|
||||
String.Format(
|
||||
"Set debug scene scripting = {0}, collisions = {1}, physics = {2}",
|
||||
!scriptingOn, !collisionsOn, !physicsOn));
|
||||
MainConsole.Instance.OutputFormat("Set debug scene {0} = {1}", key, value);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MainConsole.Instance.Output("Usage: debug scene <scripting> <collisions> <physics> (where inside <> is true/false)");
|
||||
MainConsole.Instance.Output("Usage: debug scene scripting|collisions|physics|teleport true|false");
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case "teleport":
|
||||
foreach(Scene s in m_sceneManager.Scenes)
|
||||
{
|
||||
if (s.DEBUG)
|
||||
{
|
||||
s.DEBUG = false;
|
||||
MainConsole.Instance.Output("Teleport debugging is disabled!");
|
||||
}
|
||||
else{
|
||||
s.DEBUG = true;
|
||||
MainConsole.Instance.Output("Teleport debugging is enabled!");
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
MainConsole.Instance.Output("Unknown debug command");
|
||||
break;
|
||||
|
||||
@@ -242,15 +242,18 @@ namespace OpenSim
|
||||
|
||||
foreach (string topic in topics)
|
||||
{
|
||||
m_console.Commands.AddCommand("plugin", false, "help " + topic,
|
||||
"help " + topic,
|
||||
string capitalizedTopic = char.ToUpper(topic[0]) + topic.Substring(1);
|
||||
|
||||
// This is a hack to allow the user to enter the help command in upper or lowercase. This will go
|
||||
// away at some point.
|
||||
m_console.Commands.AddCommand(capitalizedTopic, false, "help " + topic,
|
||||
"help " + capitalizedTopic,
|
||||
"Get help on plugin command '" + topic + "'",
|
||||
HandleCommanderHelp);
|
||||
m_console.Commands.AddCommand(capitalizedTopic, false, "help " + capitalizedTopic,
|
||||
"help " + capitalizedTopic,
|
||||
"Get help on plugin command '" + topic + "'",
|
||||
HandleCommanderHelp);
|
||||
|
||||
m_console.Commands.AddCommand("plugin", false, topic,
|
||||
topic,
|
||||
"Execute subcommand for plugin '" + topic + "'",
|
||||
null);
|
||||
|
||||
ICommander commander = null;
|
||||
|
||||
@@ -267,7 +270,7 @@ namespace OpenSim
|
||||
|
||||
foreach (string command in commander.Commands.Keys)
|
||||
{
|
||||
m_console.Commands.AddCommand(topic, false,
|
||||
m_console.Commands.AddCommand(capitalizedTopic, false,
|
||||
topic + " " + command,
|
||||
topic + " " + commander.Commands[command].ShortHelp(),
|
||||
String.Empty, HandleCommanderCommand);
|
||||
@@ -286,7 +289,7 @@ namespace OpenSim
|
||||
// Only safe for the interactive console, since it won't
|
||||
// let us come here unless both scene and commander exist
|
||||
//
|
||||
ICommander moduleCommander = SceneManager.CurrentOrFirstScene.GetCommander(cmd[1]);
|
||||
ICommander moduleCommander = SceneManager.CurrentOrFirstScene.GetCommander(cmd[1].ToLower());
|
||||
if (moduleCommander != null)
|
||||
m_console.Output(moduleCommander.Help);
|
||||
}
|
||||
@@ -381,7 +384,7 @@ namespace OpenSim
|
||||
scene.LoadPrimsFromStorage(regionInfo.originRegionID);
|
||||
|
||||
// TODO : Try setting resource for region xstats here on scene
|
||||
MainServer.Instance.AddStreamHandler(new Region.Framework.Scenes.RegionStatsHandler(regionInfo));
|
||||
MainServer.Instance.AddStreamHandler(new RegionStatsHandler(regionInfo));
|
||||
|
||||
scene.loadAllLandObjectsFromStorage(regionInfo.originRegionID);
|
||||
scene.EventManager.TriggerParcelPrimCountUpdate();
|
||||
@@ -424,7 +427,7 @@ namespace OpenSim
|
||||
|
||||
mscene = scene;
|
||||
|
||||
scene.StartTimer();
|
||||
scene.Start();
|
||||
|
||||
scene.StartScripts();
|
||||
|
||||
@@ -724,6 +727,9 @@ namespace OpenSim
|
||||
return Util.UTF8.GetBytes("OK");
|
||||
}
|
||||
|
||||
public string Name { get { return "SimStatus"; } }
|
||||
public string Description { get { return "Simulator Status"; } }
|
||||
|
||||
public string ContentType
|
||||
{
|
||||
get { return "text/plain"; }
|
||||
@@ -748,6 +754,9 @@ namespace OpenSim
|
||||
{
|
||||
OpenSimBase m_opensim;
|
||||
string osXStatsURI = String.Empty;
|
||||
|
||||
public string Name { get { return "XSimStatus"; } }
|
||||
public string Description { get { return "Simulator XStatus"; } }
|
||||
|
||||
public XSimStatusHandler(OpenSimBase sim)
|
||||
{
|
||||
@@ -788,6 +797,9 @@ namespace OpenSim
|
||||
{
|
||||
OpenSimBase m_opensim;
|
||||
string osUXStatsURI = String.Empty;
|
||||
|
||||
public string Name { get { return "UXSimStatus"; } }
|
||||
public string Description { get { return "Simulator UXStatus"; } }
|
||||
|
||||
public UXSimStatusHandler(OpenSimBase sim)
|
||||
{
|
||||
|
||||
@@ -151,7 +151,9 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
try
|
||||
{
|
||||
// the root of all evil
|
||||
m_HostCapsObj.RegisterHandler("SEED", new RestStreamHandler("POST", capsBase + m_requestPath, SeedCapRequest));
|
||||
m_HostCapsObj.RegisterHandler(
|
||||
"SEED", new RestStreamHandler("POST", capsBase + m_requestPath, SeedCapRequest, "SEED", null));
|
||||
|
||||
m_log.DebugFormat(
|
||||
"[CAPS]: Registered seed capability {0} for {1}", capsBase + m_requestPath, m_HostCapsObj.AgentID);
|
||||
|
||||
@@ -159,7 +161,10 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
// new LLSDStreamhandler<OSDMapRequest, OSDMapLayerResponse>("POST",
|
||||
// capsBase + m_mapLayerPath,
|
||||
// GetMapLayer);
|
||||
IRequestHandler req = new RestStreamHandler("POST", capsBase + m_notecardTaskUpdatePath, ScriptTaskInventory);
|
||||
IRequestHandler req
|
||||
= new RestStreamHandler(
|
||||
"POST", capsBase + m_notecardTaskUpdatePath, ScriptTaskInventory, "UpdateScript", null);
|
||||
|
||||
m_HostCapsObj.RegisterHandler("UpdateScriptTaskInventory", req);
|
||||
m_HostCapsObj.RegisterHandler("UpdateScriptTask", req);
|
||||
}
|
||||
@@ -174,14 +179,27 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
try
|
||||
{
|
||||
// I don't think this one works...
|
||||
m_HostCapsObj.RegisterHandler("NewFileAgentInventory", new LLSDStreamhandler<LLSDAssetUploadRequest, LLSDAssetUploadResponse>("POST",
|
||||
capsBase + m_newInventory,
|
||||
NewAgentInventoryRequest));
|
||||
IRequestHandler req = new RestStreamHandler("POST", capsBase + m_notecardUpdatePath, NoteCardAgentInventory);
|
||||
m_HostCapsObj.RegisterHandler(
|
||||
"NewFileAgentInventory",
|
||||
new LLSDStreamhandler<LLSDAssetUploadRequest, LLSDAssetUploadResponse>(
|
||||
"POST",
|
||||
capsBase + m_newInventory,
|
||||
NewAgentInventoryRequest,
|
||||
"NewFileAgentInventory",
|
||||
null));
|
||||
|
||||
IRequestHandler req
|
||||
= new RestStreamHandler(
|
||||
"POST", capsBase + m_notecardUpdatePath, NoteCardAgentInventory, "Update*", null);
|
||||
|
||||
m_HostCapsObj.RegisterHandler("UpdateNotecardAgentInventory", req);
|
||||
m_HostCapsObj.RegisterHandler("UpdateScriptAgentInventory", req);
|
||||
m_HostCapsObj.RegisterHandler("UpdateScriptAgent", req);
|
||||
m_HostCapsObj.RegisterHandler("CopyInventoryFromNotecard", new RestStreamHandler("POST", capsBase + m_copyFromNotecardPath, CopyInventoryFromNotecard));
|
||||
|
||||
m_HostCapsObj.RegisterHandler(
|
||||
"CopyInventoryFromNotecard",
|
||||
new RestStreamHandler(
|
||||
"POST", capsBase + m_copyFromNotecardPath, CopyInventoryFromNotecard, "CopyInventoryFromNotecard", null));
|
||||
|
||||
// As of RC 1.22.9 of the Linden client this is
|
||||
// supported
|
||||
@@ -231,7 +249,10 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
|
||||
if (!m_Scene.CheckClient(m_HostCapsObj.AgentID, httpRequest.RemoteIPEndPoint))
|
||||
{
|
||||
m_log.DebugFormat("[CAPS]: Unauthorized CAPS client");
|
||||
m_log.DebugFormat(
|
||||
"[CAPS]: Unauthorized CAPS client {0} from {1}",
|
||||
m_HostCapsObj.AgentID, httpRequest.RemoteIPEndPoint);
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
@@ -282,7 +303,9 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
m_dumpAssetsToFile);
|
||||
uploader.OnUpLoad += TaskScriptUpdated;
|
||||
|
||||
m_HostCapsObj.HttpListener.AddStreamHandler(new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps));
|
||||
m_HostCapsObj.HttpListener.AddStreamHandler(
|
||||
new BinaryStreamHandler(
|
||||
"POST", capsBase + uploaderPath, uploader.uploaderCaps, "TaskInventoryScriptUpdater", null));
|
||||
|
||||
string protocol = "http://";
|
||||
|
||||
@@ -393,8 +416,14 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
AssetUploader uploader =
|
||||
new AssetUploader(assetName, assetDes, newAsset, newInvItem, parentFolder, llsdRequest.inventory_type,
|
||||
llsdRequest.asset_type, capsBase + uploaderPath, m_HostCapsObj.HttpListener, m_dumpAssetsToFile);
|
||||
|
||||
m_HostCapsObj.HttpListener.AddStreamHandler(
|
||||
new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps));
|
||||
new BinaryStreamHandler(
|
||||
"POST",
|
||||
capsBase + uploaderPath,
|
||||
uploader.uploaderCaps,
|
||||
"NewAgentInventoryRequest",
|
||||
m_HostCapsObj.AgentID.ToString()));
|
||||
|
||||
string protocol = "http://";
|
||||
|
||||
@@ -710,7 +739,8 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
uploader.OnUpLoad += ItemUpdated;
|
||||
|
||||
m_HostCapsObj.HttpListener.AddStreamHandler(
|
||||
new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps));
|
||||
new BinaryStreamHandler(
|
||||
"POST", capsBase + uploaderPath, uploader.uploaderCaps, "NoteCardAgentInventory", null));
|
||||
|
||||
string protocol = "http://";
|
||||
|
||||
|
||||
@@ -106,13 +106,14 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
scene.EventManager.OnRegisterCaps += OnRegisterCaps;
|
||||
|
||||
MainConsole.Instance.Commands.AddCommand(
|
||||
"event queue",
|
||||
"Comms",
|
||||
false,
|
||||
"debug eq",
|
||||
"debug eq [0|1]",
|
||||
"Turn on event queue debugging",
|
||||
"debug eq 1 will turn on event queue debugging. This will log all outgoing event queue messages to clients.\n"
|
||||
+ "debug eq 0 will turn off event queue debugging.",
|
||||
"debug eq [0|1|2]",
|
||||
"Turn on event queue debugging"
|
||||
+ "<= 0 - turns off all event queue logging"
|
||||
+ ">= 1 - turns on outgoing event logging"
|
||||
+ ">= 2 - turns on poll notification",
|
||||
HandleDebugEq);
|
||||
}
|
||||
else
|
||||
@@ -235,19 +236,19 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
// ClientClosed(client.AgentId);
|
||||
// }
|
||||
|
||||
private void ClientClosed(UUID AgentID, Scene scene)
|
||||
private void ClientClosed(UUID agentID, Scene scene)
|
||||
{
|
||||
// m_log.DebugFormat("[EVENTQUEUE]: Closed client {0} in region {1}", AgentID, m_scene.RegionInfo.RegionName);
|
||||
// m_log.DebugFormat("[EVENTQUEUE]: Closed client {0} in region {1}", agentID, m_scene.RegionInfo.RegionName);
|
||||
|
||||
int count = 0;
|
||||
while (queues.ContainsKey(AgentID) && queues[AgentID].Count > 0 && count++ < 5)
|
||||
while (queues.ContainsKey(agentID) && queues[agentID].Count > 0 && count++ < 5)
|
||||
{
|
||||
Thread.Sleep(1000);
|
||||
}
|
||||
|
||||
lock (queues)
|
||||
{
|
||||
queues.Remove(AgentID);
|
||||
queues.Remove(agentID);
|
||||
}
|
||||
|
||||
List<UUID> removeitems = new List<UUID>();
|
||||
@@ -256,7 +257,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
foreach (UUID ky in m_AvatarQueueUUIDMapping.Keys)
|
||||
{
|
||||
// m_log.DebugFormat("[EVENTQUEUE]: Found key {0} in m_AvatarQueueUUIDMapping while looking for {1}", ky, AgentID);
|
||||
if (ky == AgentID)
|
||||
if (ky == agentID)
|
||||
{
|
||||
removeitems.Add(ky);
|
||||
}
|
||||
@@ -267,7 +268,12 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
UUID eventQueueGetUuid = m_AvatarQueueUUIDMapping[ky];
|
||||
m_AvatarQueueUUIDMapping.Remove(ky);
|
||||
|
||||
MainServer.Instance.RemovePollServiceHTTPHandler("","/CAPS/EQG/" + eventQueueGetUuid.ToString() + "/");
|
||||
string eqgPath = GenerateEqgCapPath(eventQueueGetUuid);
|
||||
MainServer.Instance.RemovePollServiceHTTPHandler("", eqgPath);
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[EVENT QUEUE GET MODULE]: Removed EQG handler {0} for {1} in {2}",
|
||||
// eqgPath, agentID, m_scene.RegionInfo.RegionName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -281,7 +287,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
{
|
||||
searchval = m_QueueUUIDAvatarMapping[ky];
|
||||
|
||||
if (searchval == AgentID)
|
||||
if (searchval == agentID)
|
||||
{
|
||||
removeitems.Add(ky);
|
||||
}
|
||||
@@ -305,6 +311,15 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
//}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generate an Event Queue Get handler path for the given eqg uuid.
|
||||
/// </summary>
|
||||
/// <param name='eqgUuid'></param>
|
||||
private string GenerateEqgCapPath(UUID eqgUuid)
|
||||
{
|
||||
return string.Format("/CAPS/EQG/{0}/", eqgUuid);
|
||||
}
|
||||
|
||||
public void OnRegisterCaps(UUID agentID, Caps caps)
|
||||
{
|
||||
// Register an event queue for the client
|
||||
@@ -316,8 +331,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
// Let's instantiate a Queue for this agent right now
|
||||
TryGetQueue(agentID);
|
||||
|
||||
string capsBase = "/CAPS/EQG/";
|
||||
UUID EventQueueGetUUID = UUID.Zero;
|
||||
UUID eventQueueGetUUID;
|
||||
|
||||
lock (m_AvatarQueueUUIDMapping)
|
||||
{
|
||||
@@ -325,44 +339,50 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
if (m_AvatarQueueUUIDMapping.ContainsKey(agentID))
|
||||
{
|
||||
//m_log.DebugFormat("[EVENTQUEUE]: Found Existing UUID!");
|
||||
EventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID];
|
||||
eventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID];
|
||||
}
|
||||
else
|
||||
{
|
||||
EventQueueGetUUID = UUID.Random();
|
||||
eventQueueGetUUID = UUID.Random();
|
||||
//m_log.DebugFormat("[EVENTQUEUE]: Using random UUID!");
|
||||
}
|
||||
}
|
||||
|
||||
lock (m_QueueUUIDAvatarMapping)
|
||||
{
|
||||
if (!m_QueueUUIDAvatarMapping.ContainsKey(EventQueueGetUUID))
|
||||
m_QueueUUIDAvatarMapping.Add(EventQueueGetUUID, agentID);
|
||||
if (!m_QueueUUIDAvatarMapping.ContainsKey(eventQueueGetUUID))
|
||||
m_QueueUUIDAvatarMapping.Add(eventQueueGetUUID, agentID);
|
||||
}
|
||||
|
||||
lock (m_AvatarQueueUUIDMapping)
|
||||
{
|
||||
if (!m_AvatarQueueUUIDMapping.ContainsKey(agentID))
|
||||
m_AvatarQueueUUIDMapping.Add(agentID, EventQueueGetUUID);
|
||||
m_AvatarQueueUUIDMapping.Add(agentID, eventQueueGetUUID);
|
||||
}
|
||||
|
||||
string eventQueueGetPath = GenerateEqgCapPath(eventQueueGetUUID);
|
||||
|
||||
// Register this as a caps handler
|
||||
// FIXME: Confusingly, we need to register separate as a capability so that the client is told about
|
||||
// EventQueueGet when it receive capability information, but then we replace the rest handler immediately
|
||||
// afterwards with the poll service. So for now, we'll pass a null instead to simplify code reading, but
|
||||
// really it should be possible to directly register the poll handler as a capability.
|
||||
caps.RegisterHandler("EventQueueGet",
|
||||
new RestHTTPHandler("POST", capsBase + EventQueueGetUUID.ToString() + "/", null));
|
||||
caps.RegisterHandler("EventQueueGet", new RestHTTPHandler("POST", eventQueueGetPath, null));
|
||||
// delegate(Hashtable m_dhttpMethod)
|
||||
// {
|
||||
// return ProcessQueue(m_dhttpMethod, agentID, caps);
|
||||
// }));
|
||||
|
||||
// This will persist this beyond the expiry of the caps handlers
|
||||
// TODO: Add EventQueueGet name/description for diagnostics
|
||||
MainServer.Instance.AddPollServiceHTTPHandler(
|
||||
capsBase + EventQueueGetUUID.ToString() + "/",
|
||||
eventQueueGetPath,
|
||||
new PollServiceEventArgs(null, HasEvents, GetEvents, NoEvents, agentID));
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[EVENT QUEUE GET MODULE]: Registered EQG handler {0} for {1} in {2}",
|
||||
// eventQueueGetPath, agentID, m_scene.RegionInfo.RegionName);
|
||||
|
||||
Random rnd = new Random(Environment.TickCount);
|
||||
lock (m_ids)
|
||||
{
|
||||
@@ -384,9 +404,25 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Logs a debug line for an outbound event queue message if appropriate.
|
||||
/// </summary>
|
||||
/// <param name='element'>Element containing message</param>
|
||||
private void LogOutboundDebugMessage(OSD element, UUID agentId)
|
||||
{
|
||||
if (element is OSDMap)
|
||||
{
|
||||
OSDMap ev = (OSDMap)element;
|
||||
m_log.DebugFormat(
|
||||
"Eq OUT {0,-30} to {1,-20} {2,-20}",
|
||||
ev["message"], m_scene.GetScenePresence(agentId).Name, m_scene.RegionInfo.RegionName);
|
||||
}
|
||||
}
|
||||
|
||||
public Hashtable GetEvents(UUID requestID, UUID pAgentId, string request)
|
||||
{
|
||||
// m_log.DebugFormat("[EVENT QUEUE GET MODULE]: Invoked GetEvents() for {0}", pAgentId);
|
||||
if (DebugLevel >= 2)
|
||||
m_log.DebugFormat("POLLED FOR EQ MESSAGES BY {0} in {1}", pAgentId, m_scene.RegionInfo.RegionName);
|
||||
|
||||
Queue<OSD> queue = TryGetQueue(pAgentId);
|
||||
OSD element;
|
||||
@@ -410,13 +446,8 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
}
|
||||
else
|
||||
{
|
||||
if (DebugLevel > 0 && element is OSDMap)
|
||||
{
|
||||
OSDMap ev = (OSDMap)element;
|
||||
m_log.DebugFormat(
|
||||
"[EVENT QUEUE GET MODULE]: Eq OUT {0} to {1}",
|
||||
ev["message"], m_scene.GetScenePresence(pAgentId).Name);
|
||||
}
|
||||
if (DebugLevel > 0)
|
||||
LogOutboundDebugMessage(element, pAgentId);
|
||||
|
||||
array.Add(element);
|
||||
|
||||
@@ -426,13 +457,8 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
{
|
||||
element = queue.Dequeue();
|
||||
|
||||
if (DebugLevel > 0 && element is OSDMap)
|
||||
{
|
||||
OSDMap ev = (OSDMap)element;
|
||||
m_log.DebugFormat(
|
||||
"[EVENT QUEUE GET MODULE]: Eq OUT {0} to {1}",
|
||||
ev["message"], m_scene.GetScenePresence(pAgentId).Name);
|
||||
}
|
||||
if (DebugLevel > 0)
|
||||
LogOutboundDebugMessage(element, pAgentId);
|
||||
|
||||
array.Add(element);
|
||||
thisID++;
|
||||
|
||||
@@ -60,7 +60,7 @@ namespace OpenSim.Region.ClientStack.Linden.Tests
|
||||
CapabilitiesModule capsModule = new CapabilitiesModule();
|
||||
EventQueueGetModule eqgModule = new EventQueueGetModule();
|
||||
|
||||
m_scene = SceneHelpers.SetupScene();
|
||||
m_scene = new SceneHelpers().SetupScene();
|
||||
SceneHelpers.SetupSceneModules(m_scene, config, capsModule, eqgModule);
|
||||
}
|
||||
|
||||
|
||||
@@ -132,7 +132,8 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
capUrl = "/CAPS/" + UUID.Random();
|
||||
|
||||
IRequestHandler reqHandler
|
||||
= new RestStreamHandler("POST", capUrl, m_fetchHandler.FetchInventoryRequest);
|
||||
= new RestStreamHandler(
|
||||
"POST", capUrl, m_fetchHandler.FetchInventoryRequest, capName, agentID.ToString());
|
||||
|
||||
caps.RegisterHandler(capName, reqHandler);
|
||||
}
|
||||
|
||||
@@ -120,11 +120,13 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
{
|
||||
// m_log.DebugFormat("[GETMESH]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName);
|
||||
GetMeshHandler gmeshHandler = new GetMeshHandler(m_AssetService);
|
||||
IRequestHandler reqHandler = new RestHTTPHandler("GET", "/CAPS/" + UUID.Random(),
|
||||
delegate(Hashtable m_dhttpMethod)
|
||||
{
|
||||
return gmeshHandler.ProcessGetMesh(m_dhttpMethod, UUID.Zero, null);
|
||||
});
|
||||
IRequestHandler reqHandler
|
||||
= new RestHTTPHandler(
|
||||
"GET",
|
||||
"/CAPS/" + UUID.Random(),
|
||||
httpMethod => gmeshHandler.ProcessGetMesh(httpMethod, UUID.Zero, null),
|
||||
"GetMesh",
|
||||
agentID.ToString());
|
||||
|
||||
caps.RegisterHandler("GetMesh", reqHandler);
|
||||
}
|
||||
|
||||
@@ -130,7 +130,9 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
if (m_URL == "localhost")
|
||||
{
|
||||
// m_log.DebugFormat("[GETTEXTURE]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName);
|
||||
caps.RegisterHandler("GetTexture", new GetTextureHandler("/CAPS/" + capID + "/", m_assetService));
|
||||
caps.RegisterHandler(
|
||||
"GetTexture",
|
||||
new GetTextureHandler("/CAPS/" + capID + "/", m_assetService, "GetTexture", agentID.ToString()));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -117,7 +117,9 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
|
||||
public void RegisterCaps(UUID agentID, Caps caps)
|
||||
{
|
||||
IRequestHandler reqHandler = new RestHTTPHandler("GET", "/CAPS/" + UUID.Random(), MeshUploadFlag);
|
||||
IRequestHandler reqHandler
|
||||
= new RestHTTPHandler("GET", "/CAPS/" + UUID.Random(), MeshUploadFlag, "MeshUploadFlag", agentID.ToString());
|
||||
|
||||
caps.RegisterHandler("MeshUploadFlag", reqHandler);
|
||||
m_agentID = agentID;
|
||||
}
|
||||
|
||||
@@ -56,6 +56,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
// private IAssetService m_assetService;
|
||||
private bool m_dumpAssetsToFile = false;
|
||||
private bool m_enabled = true;
|
||||
private int m_levelUpload = 0;
|
||||
|
||||
#region IRegionModuleBase Members
|
||||
|
||||
@@ -72,6 +73,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
return;
|
||||
|
||||
m_enabled = meshConfig.GetBoolean("AllowMeshUpload", true);
|
||||
m_levelUpload = meshConfig.GetInt("LevelUpload", 0);
|
||||
}
|
||||
|
||||
public void AddRegion(Scene pScene)
|
||||
@@ -113,51 +115,66 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
UUID capID = UUID.Random();
|
||||
|
||||
// m_log.Debug("[NEW FILE AGENT INVENTORY VARIABLE PRICE]: /CAPS/" + capID);
|
||||
caps.RegisterHandler("NewFileAgentInventoryVariablePrice",
|
||||
|
||||
new LLSDStreamhandler<LLSDAssetUploadRequest, LLSDNewFileAngentInventoryVariablePriceReplyResponse>("POST",
|
||||
"/CAPS/" + capID.ToString(),
|
||||
delegate(LLSDAssetUploadRequest req)
|
||||
{
|
||||
return NewAgentInventoryRequest(req,agentID);
|
||||
}));
|
||||
|
||||
caps.RegisterHandler(
|
||||
"NewFileAgentInventoryVariablePrice",
|
||||
new LLSDStreamhandler<LLSDAssetUploadRequest, LLSDNewFileAngentInventoryVariablePriceReplyResponse>(
|
||||
"POST",
|
||||
"/CAPS/" + capID.ToString(),
|
||||
req => NewAgentInventoryRequest(req, agentID),
|
||||
"NewFileAgentInventoryVariablePrice",
|
||||
agentID.ToString()));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public LLSDNewFileAngentInventoryVariablePriceReplyResponse NewAgentInventoryRequest(LLSDAssetUploadRequest llsdRequest, UUID agentID)
|
||||
{
|
||||
|
||||
//TODO: The Mesh uploader uploads many types of content. If you're going to implement a Money based limit
|
||||
// You need to be aware of this and
|
||||
|
||||
// you need to be aware of this
|
||||
|
||||
//if (llsdRequest.asset_type == "texture" ||
|
||||
// llsdRequest.asset_type == "animation" ||
|
||||
// llsdRequest.asset_type == "sound")
|
||||
// {
|
||||
IClientAPI client = null;
|
||||
// check user level
|
||||
|
||||
|
||||
IMoneyModule mm = m_scene.RequestModuleInterface<IMoneyModule>();
|
||||
|
||||
if (mm != null)
|
||||
ScenePresence avatar = null;
|
||||
IClientAPI client = null;
|
||||
m_scene.TryGetScenePresence(agentID, out avatar);
|
||||
|
||||
if (avatar != null)
|
||||
{
|
||||
client = avatar.ControllingClient;
|
||||
|
||||
if (avatar.UserLevel < m_levelUpload)
|
||||
{
|
||||
if (m_scene.TryGetClient(agentID, out client))
|
||||
{
|
||||
if (!mm.UploadCovered(client.AgentId, mm.UploadCharge))
|
||||
{
|
||||
if (client != null)
|
||||
client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false);
|
||||
if (client != null)
|
||||
client.SendAgentAlertMessage("Unable to upload asset. Insufficient permissions.", false);
|
||||
|
||||
LLSDNewFileAngentInventoryVariablePriceReplyResponse errorResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse();
|
||||
errorResponse.rsvp = "";
|
||||
errorResponse.state = "error";
|
||||
return errorResponse;
|
||||
}
|
||||
}
|
||||
LLSDNewFileAngentInventoryVariablePriceReplyResponse errorResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse();
|
||||
errorResponse.rsvp = "";
|
||||
errorResponse.state = "error";
|
||||
return errorResponse;
|
||||
}
|
||||
}
|
||||
|
||||
// check funds
|
||||
IMoneyModule mm = m_scene.RequestModuleInterface<IMoneyModule>();
|
||||
|
||||
if (mm != null)
|
||||
{
|
||||
if (!mm.UploadCovered(agentID, mm.UploadCharge))
|
||||
{
|
||||
if (client != null)
|
||||
client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false);
|
||||
|
||||
LLSDNewFileAngentInventoryVariablePriceReplyResponse errorResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse();
|
||||
errorResponse.rsvp = "";
|
||||
errorResponse.state = "error";
|
||||
return errorResponse;
|
||||
}
|
||||
}
|
||||
|
||||
// }
|
||||
|
||||
string assetName = llsdRequest.name;
|
||||
@@ -171,8 +188,14 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
AssetUploader uploader =
|
||||
new AssetUploader(assetName, assetDes, newAsset, newInvItem, parentFolder, llsdRequest.inventory_type,
|
||||
llsdRequest.asset_type, capsBase + uploaderPath, MainServer.Instance, m_dumpAssetsToFile);
|
||||
|
||||
MainServer.Instance.AddStreamHandler(
|
||||
new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps));
|
||||
new BinaryStreamHandler(
|
||||
"POST",
|
||||
capsBase + uploaderPath,
|
||||
uploader.uploaderCaps,
|
||||
"NewFileAgentInventoryVariablePrice",
|
||||
agentID.ToString()));
|
||||
|
||||
string protocol = "http://";
|
||||
|
||||
@@ -181,10 +204,9 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
|
||||
string uploaderURL = protocol + m_scene.RegionInfo.ExternalHostName + ":" + MainServer.Instance.Port.ToString() + capsBase +
|
||||
uploaderPath;
|
||||
|
||||
|
||||
|
||||
LLSDNewFileAngentInventoryVariablePriceReplyResponse uploadResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse();
|
||||
|
||||
|
||||
uploadResponse.rsvp = uploaderURL;
|
||||
uploadResponse.state = "upload";
|
||||
@@ -202,6 +224,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
pinventoryItem, pparentFolder, pdata, pinventoryType,
|
||||
passetType,agentID);
|
||||
};
|
||||
|
||||
return uploadResponse;
|
||||
}
|
||||
|
||||
|
||||
@@ -66,12 +66,14 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
|
||||
// m_log.InfoFormat("[OBJECTADD]: {0}", "/CAPS/OA/" + capuuid + "/");
|
||||
|
||||
caps.RegisterHandler("ObjectAdd",
|
||||
new RestHTTPHandler("POST", "/CAPS/OA/" + capuuid + "/",
|
||||
delegate(Hashtable m_dhttpMethod)
|
||||
{
|
||||
return ProcessAdd(m_dhttpMethod, agentID, caps);
|
||||
}));
|
||||
caps.RegisterHandler(
|
||||
"ObjectAdd",
|
||||
new RestHTTPHandler(
|
||||
"POST",
|
||||
"/CAPS/OA/" + capuuid + "/",
|
||||
httpMethod => ProcessAdd(httpMethod, agentID, caps),
|
||||
"ObjectAdd",
|
||||
agentID.ToString()));;
|
||||
}
|
||||
|
||||
public Hashtable ProcessAdd(Hashtable request, UUID AgentId, Caps cap)
|
||||
|
||||
@@ -106,12 +106,15 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
UUID capID = UUID.Random();
|
||||
|
||||
// m_log.Debug("[UPLOAD OBJECT ASSET MODULE]: /CAPS/" + capID);
|
||||
caps.RegisterHandler("UploadObjectAsset",
|
||||
new RestHTTPHandler("POST", "/CAPS/OA/" + capID + "/",
|
||||
delegate(Hashtable m_dhttpMethod)
|
||||
{
|
||||
return ProcessAdd(m_dhttpMethod, agentID, caps);
|
||||
}));
|
||||
caps.RegisterHandler(
|
||||
"UploadObjectAsset",
|
||||
new RestHTTPHandler(
|
||||
"POST",
|
||||
"/CAPS/OA/" + capID + "/",
|
||||
httpMethod => ProcessAdd(httpMethod, agentID, caps),
|
||||
"UploadObjectAsset",
|
||||
agentID.ToString()));
|
||||
|
||||
/*
|
||||
caps.RegisterHandler("NewFileAgentInventoryVariablePrice",
|
||||
|
||||
|
||||
@@ -154,7 +154,9 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
public void RegisterCaps(UUID agentID, Caps caps)
|
||||
{
|
||||
IRequestHandler reqHandler
|
||||
= new RestHTTPHandler("GET", "/CAPS/" + UUID.Random(), HandleSimulatorFeaturesRequest);
|
||||
= new RestHTTPHandler(
|
||||
"GET", "/CAPS/" + UUID.Random(),
|
||||
HandleSimulatorFeaturesRequest, "SimulatorFeatures", agentID.ToString());
|
||||
|
||||
caps.RegisterHandler("SimulatorFeatures", reqHandler);
|
||||
}
|
||||
|
||||
@@ -106,7 +106,9 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
"POST",
|
||||
"/CAPS/" + caps.CapsObjectPath + m_uploadBakedTexturePath,
|
||||
new UploadBakedTextureHandler(
|
||||
caps, m_scene.AssetService, m_persistBakedTextures).UploadBakedTexture));
|
||||
caps, m_scene.AssetService, m_persistBakedTextures).UploadBakedTexture,
|
||||
"UploadBakedTexture",
|
||||
agentID.ToString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -144,7 +144,12 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
capUrl = "/CAPS/" + UUID.Random();
|
||||
|
||||
IRequestHandler reqHandler
|
||||
= new RestStreamHandler("POST", capUrl, m_webFetchHandler.FetchInventoryDescendentsRequest);
|
||||
= new RestStreamHandler(
|
||||
"POST",
|
||||
capUrl,
|
||||
m_webFetchHandler.FetchInventoryDescendentsRequest,
|
||||
"FetchInventoryDescendents2",
|
||||
agentID.ToString());
|
||||
|
||||
caps.RegisterHandler(capName, reqHandler);
|
||||
}
|
||||
@@ -160,4 +165,4 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
// capName, capUrl, m_scene.RegionInfo.RegionName, agentID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -59,7 +59,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
/// Handles new client connections
|
||||
/// Constructor takes a single Packet and authenticates everything
|
||||
/// </summary>
|
||||
public class LLClientView : IClientAPI, IClientCore, IClientIM, IClientChat, IClientIPEndpoint, IStatsCollector
|
||||
public class LLClientView : IClientAPI, IClientCore, IClientIM, IClientChat, IClientInventory, IClientIPEndpoint, IStatsCollector
|
||||
{
|
||||
/// <value>
|
||||
/// Debug packet level. See OpenSim.RegisterConsoleCommands() for more details.
|
||||
@@ -385,7 +385,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
set { m_startpos = value; }
|
||||
}
|
||||
public UUID AgentId { get { return m_agentId; } }
|
||||
public ISceneAgent SceneAgent { get; private set; }
|
||||
public ISceneAgent SceneAgent { get; set; }
|
||||
public UUID ActiveGroupId { get { return m_activeGroupID; } }
|
||||
public string ActiveGroupName { get { return m_activeGroupName; } }
|
||||
public ulong ActiveGroupPowers { get { return m_activeGroupPowers; } }
|
||||
@@ -449,6 +449,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
// DebugPacketLevel = 1;
|
||||
|
||||
RegisterInterface<IClientIM>(this);
|
||||
RegisterInterface<IClientInventory>(this);
|
||||
RegisterInterface<IClientChat>(this);
|
||||
RegisterInterface<IClientIPEndpoint>(this);
|
||||
|
||||
@@ -698,7 +699,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
|
||||
public virtual void Start()
|
||||
{
|
||||
SceneAgent = m_scene.AddNewClient(this, PresenceType.User);
|
||||
m_scene.AddNewClient(this, PresenceType.User);
|
||||
|
||||
RefreshGroupMembership();
|
||||
}
|
||||
@@ -4273,7 +4274,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
block.OwnerID = sop.OwnerID;
|
||||
|
||||
block.ItemID = sop.FromUserInventoryItemID;
|
||||
block.FolderID = UUID.Zero; // sop.FromFolderID ??
|
||||
block.FolderID = UUID.Zero; // sog.FromFolderID ??
|
||||
block.FromTaskID = UUID.Zero; // ???
|
||||
block.InventorySerial = (short)sop.InventorySerial;
|
||||
|
||||
@@ -4959,7 +4960,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
update.MediaURL = Utils.EmptyBytes; // FIXME: Support this in OpenSim
|
||||
if (data.ParentGroup.IsAttachment)
|
||||
{
|
||||
update.NameValue = Util.StringToBytes256("AttachItemID STRING RW SV " + data.FromItemID);
|
||||
update.NameValue = Util.StringToBytes256("AttachItemID STRING RW SV " + data.ParentGroup.FromItemID);
|
||||
update.State = (byte)((data.ParentGroup.AttachmentPoint % 16) * 16 + (data.ParentGroup.AttachmentPoint / 16));
|
||||
}
|
||||
else
|
||||
@@ -5787,7 +5788,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
// My guess is this is the folder to stick the calling card into
|
||||
List<UUID> callingCardFolders = new List<UUID>();
|
||||
|
||||
UUID agentID = afriendpack.AgentData.AgentID;
|
||||
UUID transactionID = afriendpack.TransactionBlock.TransactionID;
|
||||
|
||||
for (int fi = 0; fi < afriendpack.FolderData.Length; fi++)
|
||||
@@ -5798,10 +5798,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
FriendActionDelegate handlerApproveFriendRequest = OnApproveFriendRequest;
|
||||
if (handlerApproveFriendRequest != null)
|
||||
{
|
||||
handlerApproveFriendRequest(this, agentID, transactionID, callingCardFolders);
|
||||
handlerApproveFriendRequest(this, transactionID, callingCardFolders);
|
||||
}
|
||||
return true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool HandlerDeclineFriendship(IClientAPI sender, Packet Pack)
|
||||
@@ -5820,7 +5820,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
if (OnDenyFriendRequest != null)
|
||||
{
|
||||
OnDenyFriendRequest(this,
|
||||
dfriendpack.AgentData.AgentID,
|
||||
dfriendpack.TransactionBlock.TransactionID,
|
||||
null);
|
||||
}
|
||||
@@ -5840,14 +5839,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
}
|
||||
#endregion
|
||||
|
||||
UUID listOwnerAgentID = tfriendpack.AgentData.AgentID;
|
||||
UUID exFriendID = tfriendpack.ExBlock.OtherID;
|
||||
FriendshipTermination TerminateFriendshipHandler = OnTerminateFriendship;
|
||||
if (TerminateFriendshipHandler != null)
|
||||
{
|
||||
TerminateFriendshipHandler(this, listOwnerAgentID, exFriendID);
|
||||
TerminateFriendshipHandler(this, exFriendID);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -11165,12 +11164,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
return true;
|
||||
}
|
||||
#endregion
|
||||
|
||||
GrantUserFriendRights GrantUserRightsHandler = OnGrantUserRights;
|
||||
if (GrantUserRightsHandler != null)
|
||||
GrantUserRightsHandler(this,
|
||||
GrantUserRights.AgentData.AgentID,
|
||||
GrantUserRights.Rights[0].AgentRelated,
|
||||
GrantUserRights.Rights[0].RelatedRights);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -11984,21 +11984,24 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
protected void MakeAssetRequest(TransferRequestPacket transferRequest, UUID taskID)
|
||||
{
|
||||
UUID requestID = UUID.Zero;
|
||||
if (transferRequest.TransferInfo.SourceType == (int)SourceType.Asset)
|
||||
int sourceType = transferRequest.TransferInfo.SourceType;
|
||||
|
||||
if (sourceType == (int)SourceType.Asset)
|
||||
{
|
||||
requestID = new UUID(transferRequest.TransferInfo.Params, 0);
|
||||
}
|
||||
else if (transferRequest.TransferInfo.SourceType == (int)SourceType.SimInventoryItem)
|
||||
else if (sourceType == (int)SourceType.SimInventoryItem)
|
||||
{
|
||||
requestID = new UUID(transferRequest.TransferInfo.Params, 80);
|
||||
}
|
||||
else if (transferRequest.TransferInfo.SourceType == (int)SourceType.SimEstate)
|
||||
else if (sourceType == (int)SourceType.SimEstate)
|
||||
{
|
||||
requestID = taskID;
|
||||
}
|
||||
|
||||
|
||||
// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID);
|
||||
// m_log.DebugFormat(
|
||||
// "[LLCLIENTVIEW]: Received transfer request for {0} in {1} type {2} by {3}",
|
||||
// requestID, taskID, (SourceType)sourceType, Name);
|
||||
|
||||
m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived);
|
||||
}
|
||||
@@ -12292,5 +12295,175 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
if (reply != null)
|
||||
OutPacket(reply, ThrottleOutPacketType.Task);
|
||||
}
|
||||
|
||||
public void SendRemoveInventoryItems(UUID[] items)
|
||||
{
|
||||
IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>();
|
||||
|
||||
if (eq == null)
|
||||
{
|
||||
m_log.DebugFormat("[LLCLIENT]: Null event queue");
|
||||
return;
|
||||
}
|
||||
|
||||
OSDMap llsd = new OSDMap(3);
|
||||
|
||||
OSDMap AgentDataMap = new OSDMap(1);
|
||||
AgentDataMap.Add("AgentID", OSD.FromUUID(AgentId));
|
||||
AgentDataMap.Add("SessionID", OSD.FromUUID(SessionId));
|
||||
|
||||
OSDArray AgentData = new OSDArray(1);
|
||||
AgentData.Add(AgentDataMap);
|
||||
|
||||
llsd.Add("AgentData", AgentData);
|
||||
|
||||
OSDArray ItemData = new OSDArray();
|
||||
|
||||
foreach (UUID item in items)
|
||||
{
|
||||
OSDMap ItemDataMap = new OSDMap(2);
|
||||
ItemDataMap.Add("ItemID", OSD.FromUUID(item));
|
||||
ItemDataMap.Add("AgentID", OSD.FromUUID(AgentId));
|
||||
|
||||
ItemData.Add(ItemDataMap);
|
||||
}
|
||||
|
||||
llsd.Add("InventoryData", ItemData);
|
||||
|
||||
eq.Enqueue(BuildEvent("RemoveInventoryItem",
|
||||
llsd), AgentId);
|
||||
}
|
||||
|
||||
public void SendRemoveInventoryFolders(UUID[] folders)
|
||||
{
|
||||
IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>();
|
||||
|
||||
if (eq == null)
|
||||
{
|
||||
m_log.DebugFormat("[LLCLIENT]: Null event queue");
|
||||
return;
|
||||
}
|
||||
|
||||
OSDMap llsd = new OSDMap(3);
|
||||
|
||||
OSDMap AgentDataMap = new OSDMap(1);
|
||||
AgentDataMap.Add("AgentID", OSD.FromUUID(AgentId));
|
||||
AgentDataMap.Add("SessionID", OSD.FromUUID(SessionId));
|
||||
|
||||
OSDArray AgentData = new OSDArray(1);
|
||||
AgentData.Add(AgentDataMap);
|
||||
|
||||
llsd.Add("AgentData", AgentData);
|
||||
|
||||
OSDArray FolderData = new OSDArray();
|
||||
|
||||
foreach (UUID folder in folders)
|
||||
{
|
||||
OSDMap FolderDataMap = new OSDMap(2);
|
||||
FolderDataMap.Add("FolderID", OSD.FromUUID(folder));
|
||||
FolderDataMap.Add("AgentID", OSD.FromUUID(AgentId));
|
||||
|
||||
FolderData.Add(FolderDataMap);
|
||||
}
|
||||
|
||||
llsd.Add("FolderData", FolderData);
|
||||
|
||||
eq.Enqueue(BuildEvent("RemoveInventoryFolder",
|
||||
llsd), AgentId);
|
||||
}
|
||||
|
||||
private byte[] EncodeU32(uint val)
|
||||
{
|
||||
byte[] ret = BitConverter.GetBytes(val);
|
||||
if (BitConverter.IsLittleEndian)
|
||||
Array.Reverse(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void SendBulkUpdateInventory(InventoryFolderBase[] folders, InventoryItemBase[] items)
|
||||
{
|
||||
IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>();
|
||||
|
||||
if (eq == null)
|
||||
{
|
||||
m_log.DebugFormat("[LLCLIENT]: Null event queue");
|
||||
return;
|
||||
}
|
||||
|
||||
OSDMap llsd = new OSDMap(3);
|
||||
|
||||
OSDMap AgentDataMap = new OSDMap(1);
|
||||
AgentDataMap.Add("AgentID", OSD.FromUUID(AgentId));
|
||||
AgentDataMap.Add("SessionID", OSD.FromUUID(SessionId));
|
||||
AgentDataMap.Add("TransactionID", OSD.FromUUID(UUID.Random()));
|
||||
|
||||
OSDArray AgentData = new OSDArray(1);
|
||||
AgentData.Add(AgentDataMap);
|
||||
|
||||
llsd.Add("AgentData", AgentData);
|
||||
|
||||
OSDArray FolderData = new OSDArray();
|
||||
|
||||
foreach (InventoryFolderBase folder in folders)
|
||||
{
|
||||
OSDMap FolderDataMap = new OSDMap(5);
|
||||
FolderDataMap.Add("FolderID", OSD.FromUUID(folder.ID));
|
||||
FolderDataMap.Add("AgentID", OSD.FromUUID(AgentId));
|
||||
FolderDataMap.Add("ParentID", OSD.FromUUID(folder.ParentID));
|
||||
FolderDataMap.Add("Type", OSD.FromInteger(folder.Type));
|
||||
FolderDataMap.Add("Name", OSD.FromString(folder.Name));
|
||||
|
||||
FolderData.Add(FolderDataMap);
|
||||
}
|
||||
|
||||
llsd.Add("FolderData", FolderData);
|
||||
|
||||
OSDArray ItemData = new OSDArray();
|
||||
|
||||
foreach (InventoryItemBase item in items)
|
||||
{
|
||||
OSDMap ItemDataMap = new OSDMap();
|
||||
|
||||
ItemDataMap.Add("ItemID", OSD.FromUUID(item.ID));
|
||||
ItemDataMap.Add("FolderID", OSD.FromUUID(item.Folder));
|
||||
|
||||
ItemDataMap.Add("CreatorID", OSD.FromUUID(item.CreatorIdAsUuid));
|
||||
ItemDataMap.Add("OwnerID", OSD.FromUUID(item.Owner));
|
||||
ItemDataMap.Add("GroupID", OSD.FromUUID(item.GroupID));
|
||||
ItemDataMap.Add("BaseMask", OSD.FromBinary(EncodeU32((uint)item.BasePermissions)));
|
||||
ItemDataMap.Add("OwnerMask", OSD.FromBinary(EncodeU32((uint)item.CurrentPermissions)));
|
||||
ItemDataMap.Add("GroupMask", OSD.FromBinary(EncodeU32((uint)item.GroupPermissions)));
|
||||
ItemDataMap.Add("EveryoneMask", OSD.FromBinary(EncodeU32((uint)item.EveryOnePermissions)));
|
||||
ItemDataMap.Add("NextOwnerMask", OSD.FromBinary(EncodeU32((uint)item.NextPermissions)));
|
||||
ItemDataMap.Add("GroupOwned", OSD.FromBoolean(item.GroupOwned));
|
||||
ItemDataMap.Add("AssetID", OSD.FromUUID(item.AssetID));
|
||||
ItemDataMap.Add("Type", OSD.FromInteger(item.AssetType));
|
||||
ItemDataMap.Add("InvType", OSD.FromInteger(item.InvType));
|
||||
ItemDataMap.Add("Flags", OSD.FromBinary(EncodeU32((uint)item.Flags)));
|
||||
ItemDataMap.Add("SaleType", OSD.FromInteger((byte)item.SaleType));
|
||||
ItemDataMap.Add("SalePrice", OSD.FromInteger(item.SalePrice));
|
||||
ItemDataMap.Add("Name", OSD.FromString(item.Name));
|
||||
ItemDataMap.Add("Description", OSD.FromString(item.Description));
|
||||
ItemDataMap.Add("CreationDate", OSD.FromInteger(item.CreationDate));
|
||||
|
||||
ItemDataMap.Add("CRC", OSD.FromBinary(EncodeU32(
|
||||
Helpers.InventoryCRC(1000, 0, (sbyte)item.InvType,
|
||||
(sbyte)item.AssetType, item.AssetID,
|
||||
item.GroupID, 100,
|
||||
item.Owner, item.CreatorIdAsUuid,
|
||||
item.ID, item.Folder,
|
||||
(uint)PermissionMask.All, 1, (uint)PermissionMask.All, (uint)PermissionMask.All,
|
||||
(uint)PermissionMask.All)
|
||||
)));
|
||||
ItemDataMap.Add("CallbackID", 0);
|
||||
|
||||
ItemData.Add(ItemDataMap);
|
||||
}
|
||||
|
||||
llsd.Add("ItemData", ItemData);
|
||||
|
||||
eq.Enqueue(BuildEvent("BulkUpdateInventory",
|
||||
llsd), AgentId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -244,8 +244,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
base.Start(m_recvBufferSize, m_asyncPacketHandling);
|
||||
|
||||
// Start the packet processing threads
|
||||
Watchdog.StartThread(IncomingPacketHandler, "Incoming Packets (" + m_scene.RegionInfo.RegionName + ")", ThreadPriority.Normal, false);
|
||||
Watchdog.StartThread(OutgoingPacketHandler, "Outgoing Packets (" + m_scene.RegionInfo.RegionName + ")", ThreadPriority.Normal, false);
|
||||
Watchdog.StartThread(
|
||||
IncomingPacketHandler, "Incoming Packets (" + m_scene.RegionInfo.RegionName + ")", ThreadPriority.Normal, false, true);
|
||||
Watchdog.StartThread(
|
||||
OutgoingPacketHandler, "Outgoing Packets (" + m_scene.RegionInfo.RegionName + ")", ThreadPriority.Normal, false, true);
|
||||
|
||||
m_elapsedMSSinceLastStatReport = Environment.TickCount;
|
||||
}
|
||||
|
||||
@@ -903,47 +906,66 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
|
||||
private void HandleUseCircuitCode(object o)
|
||||
{
|
||||
// DateTime startTime = DateTime.Now;
|
||||
object[] array = (object[])o;
|
||||
UDPPacketBuffer buffer = (UDPPacketBuffer)array[0];
|
||||
UseCircuitCodePacket uccp = (UseCircuitCodePacket)array[1];
|
||||
IPEndPoint remoteEndPoint = null;
|
||||
IClientAPI client = null;
|
||||
|
||||
try
|
||||
{
|
||||
// DateTime startTime = DateTime.Now;
|
||||
object[] array = (object[])o;
|
||||
UDPPacketBuffer buffer = (UDPPacketBuffer)array[0];
|
||||
UseCircuitCodePacket uccp = (UseCircuitCodePacket)array[1];
|
||||
|
||||
m_log.DebugFormat(
|
||||
"[LLUDPSERVER]: Handling UseCircuitCode request for circuit {0} from {1}",
|
||||
uccp.CircuitCode.Code, buffer.RemoteEndPoint);
|
||||
|
||||
remoteEndPoint = (IPEndPoint)buffer.RemoteEndPoint;
|
||||
|
||||
AuthenticateResponse sessionInfo;
|
||||
if (IsClientAuthorized(uccp, out sessionInfo))
|
||||
{
|
||||
// Begin the process of adding the client to the simulator
|
||||
client
|
||||
= AddClient(
|
||||
uccp.CircuitCode.Code,
|
||||
uccp.CircuitCode.ID,
|
||||
uccp.CircuitCode.SessionID,
|
||||
remoteEndPoint,
|
||||
sessionInfo);
|
||||
|
||||
m_log.DebugFormat("[LLUDPSERVER]: Handling UseCircuitCode request from {0}", buffer.RemoteEndPoint);
|
||||
// Send ack straight away to let the viewer know that the connection is active.
|
||||
// The client will be null if it already exists (e.g. if on a region crossing the client sends a use
|
||||
// circuit code to the existing child agent. This is not particularly obvious.
|
||||
SendAckImmediate(remoteEndPoint, uccp.Header.Sequence);
|
||||
|
||||
// We only want to send initial data to new clients, not ones which are being converted from child to root.
|
||||
if (client != null)
|
||||
client.SceneAgent.SendInitialDataToMe();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Don't create clients for unauthorized requesters.
|
||||
m_log.WarnFormat(
|
||||
"[LLUDPSERVER]: Connection request for client {0} connecting with unnotified circuit code {1} from {2}",
|
||||
uccp.CircuitCode.ID, uccp.CircuitCode.Code, remoteEndPoint);
|
||||
}
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[LLUDPSERVER]: Handling UseCircuitCode request from {0} took {1}ms",
|
||||
// buffer.RemoteEndPoint, (DateTime.Now - startTime).Milliseconds);
|
||||
|
||||
IPEndPoint remoteEndPoint = (IPEndPoint)buffer.RemoteEndPoint;
|
||||
|
||||
AuthenticateResponse sessionInfo;
|
||||
if (IsClientAuthorized(uccp, out sessionInfo))
|
||||
{
|
||||
// Begin the process of adding the client to the simulator
|
||||
IClientAPI client
|
||||
= AddClient(
|
||||
uccp.CircuitCode.Code,
|
||||
uccp.CircuitCode.ID,
|
||||
uccp.CircuitCode.SessionID,
|
||||
remoteEndPoint,
|
||||
sessionInfo);
|
||||
|
||||
// Send ack straight away to let the viewer know that the connection is active.
|
||||
// The client will be null if it already exists (e.g. if on a region crossing the client sends a use
|
||||
// circuit code to the existing child agent. This is not particularly obvious.
|
||||
SendAckImmediate(remoteEndPoint, uccp.Header.Sequence);
|
||||
|
||||
// We only want to send initial data to new clients, not ones which are being converted from child to root.
|
||||
if (client != null)
|
||||
client.SceneAgent.SendInitialDataToMe();
|
||||
}
|
||||
else
|
||||
catch (Exception e)
|
||||
{
|
||||
// Don't create clients for unauthorized requesters.
|
||||
m_log.WarnFormat(
|
||||
"[LLUDPSERVER]: Connection request for client {0} connecting with unnotified circuit code {1} from {2}",
|
||||
uccp.CircuitCode.ID, uccp.CircuitCode.Code, remoteEndPoint);
|
||||
m_log.ErrorFormat(
|
||||
"[LLUDPSERVER]: UseCircuitCode handling from endpoint {0}, client {1} {2} failed. Exception {3}{4}",
|
||||
remoteEndPoint != null ? remoteEndPoint.ToString() : "n/a",
|
||||
client != null ? client.Name : "unknown",
|
||||
client != null ? client.AgentId.ToString() : "unknown",
|
||||
e.Message,
|
||||
e.StackTrace);
|
||||
}
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[LLUDPSERVER]: Handling UseCircuitCode request from {0} took {1}ms",
|
||||
// buffer.RemoteEndPoint, (DateTime.Now - startTime).Milliseconds);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1330,7 +1352,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.DebugFormat("[LLUDPSERVER]: Dropping incoming {0} packet for dead client {1}", packet.Type, udpClient.AgentID);
|
||||
m_log.DebugFormat(
|
||||
"[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}",
|
||||
packet.Type, udpClient.AgentID, m_scene.RegionInfo.RegionName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -158,7 +158,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
|
||||
TestHelpers.InMethod();
|
||||
// XmlConfigurator.Configure();
|
||||
|
||||
TestScene scene = SceneHelpers.SetupScene();
|
||||
TestScene scene = new SceneHelpers().SetupScene();
|
||||
uint myCircuitCode = 123456;
|
||||
UUID myAgentUuid = TestHelpers.ParseTail(0x1);
|
||||
UUID mySessionUuid = TestHelpers.ParseTail(0x2);
|
||||
|
||||
@@ -79,7 +79,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
|
||||
|
||||
J2KDecoderModule j2kdm = new J2KDecoderModule();
|
||||
|
||||
scene = SceneHelpers.SetupScene();
|
||||
SceneHelpers sceneHelpers = new SceneHelpers();
|
||||
scene = sceneHelpers.SetupScene();
|
||||
SceneHelpers.SetupSceneModules(scene, j2kdm);
|
||||
|
||||
tc = new TestClient(SceneHelpers.GenerateAgentData(userId), scene);
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
|
||||
m_regStatus = RegionStatus.Up;
|
||||
}
|
||||
|
||||
public override void Update() {}
|
||||
public override void Update(int frames) {}
|
||||
public override void LoadWorldMap() {}
|
||||
|
||||
public override ISceneAgent AddNewClient(IClientAPI client, PresenceType type)
|
||||
|
||||
@@ -111,7 +111,7 @@ namespace OpenSim.Region.ClientStack
|
||||
server.Start();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
base.StartupSpecific();
|
||||
}
|
||||
|
||||
|
||||
@@ -203,10 +203,10 @@ namespace Flotsam.RegionModules.AssetCache
|
||||
m_CacheDirectoryTierLen = 4;
|
||||
}
|
||||
|
||||
MainConsole.Instance.Commands.AddCommand(Name, true, "fcache status", "fcache status", "Display cache status", HandleConsoleCommand);
|
||||
MainConsole.Instance.Commands.AddCommand(Name, true, "fcache clear", "fcache clear [file] [memory]", "Remove all assets in the cache. If file or memory is specified then only this cache is cleared.", HandleConsoleCommand);
|
||||
MainConsole.Instance.Commands.AddCommand(Name, true, "fcache assets", "fcache assets", "Attempt a deep scan and cache of all assets in all scenes", HandleConsoleCommand);
|
||||
MainConsole.Instance.Commands.AddCommand(Name, true, "fcache expire", "fcache expire <datetime>", "Purge cached assets older then the specified date/time", HandleConsoleCommand);
|
||||
MainConsole.Instance.Commands.AddCommand("Assets", true, "fcache status", "fcache status", "Display cache status", HandleConsoleCommand);
|
||||
MainConsole.Instance.Commands.AddCommand("Assets", true, "fcache clear", "fcache clear [file] [memory]", "Remove all assets in the cache. If file or memory is specified then only this cache is cleared.", HandleConsoleCommand);
|
||||
MainConsole.Instance.Commands.AddCommand("Assets", true, "fcache assets", "fcache assets", "Attempt a deep scan and cache of all assets in all scenes", HandleConsoleCommand);
|
||||
MainConsole.Instance.Commands.AddCommand("Assets", true, "fcache expire", "fcache expire <datetime>", "Purge cached assets older then the specified date/time", HandleConsoleCommand);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ namespace OpenSim.Region.CoreModules.Asset.Tests
|
||||
config.Configs["AssetCache"].Set("MemoryCacheEnabled", "true");
|
||||
|
||||
m_cache = new FlotsamAssetCache();
|
||||
m_scene = SceneHelpers.SetupScene();
|
||||
m_scene = new SceneHelpers().SetupScene();
|
||||
SceneHelpers.SetupSceneModules(m_scene, config, m_cache);
|
||||
}
|
||||
|
||||
|
||||
@@ -49,6 +49,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
|
||||
private Scene m_scene;
|
||||
private IDialogModule m_dialogModule;
|
||||
private IInventoryAccessModule m_invAccessModule;
|
||||
|
||||
/// <summary>
|
||||
/// Are attachments enabled?
|
||||
@@ -70,7 +71,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
public void AddRegion(Scene scene)
|
||||
{
|
||||
m_scene = scene;
|
||||
m_dialogModule = m_scene.RequestModuleInterface<IDialogModule>();
|
||||
m_scene.RegisterModuleInterface<IAttachmentsModule>(this);
|
||||
|
||||
if (Enabled)
|
||||
@@ -87,7 +87,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
m_scene.EventManager.OnNewClient -= SubscribeToClientEvents;
|
||||
}
|
||||
|
||||
public void RegionLoaded(Scene scene) {}
|
||||
public void RegionLoaded(Scene scene)
|
||||
{
|
||||
m_dialogModule = m_scene.RequestModuleInterface<IDialogModule>();
|
||||
m_invAccessModule = m_scene.RequestModuleInterface<IInventoryAccessModule>();
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
@@ -239,7 +243,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
// At the moment we can only deal with a single attachment
|
||||
if (attachments.Count != 0)
|
||||
{
|
||||
UUID oldAttachmentItemID = attachments[0].GetFromItemID();
|
||||
UUID oldAttachmentItemID = attachments[0].FromItemID;
|
||||
|
||||
if (oldAttachmentItemID != UUID.Zero)
|
||||
DetachSingleAttachmentToInvInternal(sp, oldAttachmentItemID);
|
||||
@@ -250,7 +254,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
}
|
||||
|
||||
// Add the new attachment to inventory if we don't already have it.
|
||||
UUID newAttachmentItemID = group.GetFromItemID();
|
||||
UUID newAttachmentItemID = group.FromItemID;
|
||||
if (newAttachmentItemID == UUID.Zero)
|
||||
newAttachmentItemID = AddSceneObjectAsNewAttachmentInInv(sp, group).ID;
|
||||
|
||||
@@ -285,7 +289,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
List<SceneObjectGroup> existingAttachments = sp.GetAttachments();
|
||||
foreach (SceneObjectGroup so in existingAttachments)
|
||||
{
|
||||
if (so.GetFromItemID() == itemID)
|
||||
if (so.FromItemID == itemID)
|
||||
{
|
||||
alreadyOn = true;
|
||||
break;
|
||||
@@ -342,7 +346,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
if (so.AttachedAvatar != sp.UUID)
|
||||
return;
|
||||
|
||||
UUID inventoryID = so.GetFromItemID();
|
||||
UUID inventoryID = so.FromItemID;
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[ATTACHMENTS MODULE]: In DetachSingleAttachmentToGround(), object is {0} {1}, associated item is {2}",
|
||||
@@ -359,9 +363,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID);
|
||||
|
||||
sp.RemoveAttachment(so);
|
||||
so.FromItemID = UUID.Zero;
|
||||
|
||||
SceneObjectPart rootPart = so.RootPart;
|
||||
rootPart.FromItemID = UUID.Zero;
|
||||
so.AbsolutePosition = sp.AbsolutePosition;
|
||||
so.AttachedAvatar = UUID.Zero;
|
||||
rootPart.SetParentLocalId(0);
|
||||
@@ -389,7 +393,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
lock (sp.AttachmentsSyncLock)
|
||||
{
|
||||
// Save avatar attachment information
|
||||
m_log.Debug("[ATTACHMENTS MODULE]: Detaching from UserID: " + sp.UUID + ", ItemID: " + itemID);
|
||||
// m_log.Debug("[ATTACHMENTS MODULE]: Detaching from UserID: " + sp.UUID + ", ItemID: " + itemID);
|
||||
|
||||
bool changed = sp.Appearance.DetachAttachment(itemID);
|
||||
if (changed && m_scene.AvatarFactory != null)
|
||||
@@ -469,13 +473,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
|
||||
if (grp.HasGroupChanged || (saveAllScripted && grp.ContainsScripts()))
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"[ATTACHMENTS MODULE]: Updating asset for attachment {0}, attachpoint {1}",
|
||||
grp.UUID, grp.AttachmentPoint);
|
||||
// m_log.DebugFormat(
|
||||
// "[ATTACHMENTS MODULE]: Updating asset for attachment {0}, attachpoint {1}",
|
||||
// grp.UUID, grp.AttachmentPoint);
|
||||
|
||||
string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp);
|
||||
|
||||
InventoryItemBase item = new InventoryItemBase(grp.GetFromItemID(), sp.UUID);
|
||||
InventoryItemBase item = new InventoryItemBase(grp.FromItemID, sp.UUID);
|
||||
item = m_scene.InventoryService.GetItem(item);
|
||||
|
||||
if (item != null)
|
||||
@@ -502,12 +506,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
}
|
||||
grp.HasGroupChanged = false; // Prevent it being saved over and over
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"[ATTACHMENTS MODULE]: Don't need to update asset for unchanged attachment {0}, attachpoint {1}",
|
||||
grp.UUID, grp.AttachmentPoint);
|
||||
}
|
||||
// else
|
||||
// {
|
||||
// m_log.DebugFormat(
|
||||
// "[ATTACHMENTS MODULE]: Don't need to update asset for unchanged attachment {0}, attachpoint {1}",
|
||||
// grp.UUID, grp.AttachmentPoint);
|
||||
// }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -576,90 +580,23 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
/// <returns>The user inventory item created that holds the attachment.</returns>
|
||||
private InventoryItemBase AddSceneObjectAsNewAttachmentInInv(IScenePresence sp, SceneObjectGroup grp)
|
||||
{
|
||||
if (m_invAccessModule == null)
|
||||
return null;
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[ATTACHMENTS MODULE]: Called AddSceneObjectAsAttachment for object {0} {1} for {2}",
|
||||
// grp.Name, grp.LocalId, remoteClient.Name);
|
||||
|
||||
Vector3 inventoryStoredPosition = new Vector3
|
||||
(((grp.AbsolutePosition.X > (int)Constants.RegionSize)
|
||||
? Constants.RegionSize - 6
|
||||
: grp.AbsolutePosition.X)
|
||||
,
|
||||
(grp.AbsolutePosition.Y > (int)Constants.RegionSize)
|
||||
? Constants.RegionSize - 6
|
||||
: grp.AbsolutePosition.Y,
|
||||
grp.AbsolutePosition.Z);
|
||||
|
||||
Vector3 originalPosition = grp.AbsolutePosition;
|
||||
|
||||
grp.AbsolutePosition = inventoryStoredPosition;
|
||||
|
||||
// If we're being called from a script, then trying to serialize that same script's state will not complete
|
||||
// in any reasonable time period. Therefore, we'll avoid it. The worst that can happen is that if
|
||||
// the client/server crashes rather than logging out normally, the attachment's scripts will resume
|
||||
// without state on relog. Arguably, this is what we want anyway.
|
||||
string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp, false);
|
||||
|
||||
grp.AbsolutePosition = originalPosition;
|
||||
|
||||
AssetBase asset = m_scene.CreateAsset(
|
||||
grp.GetPartName(grp.LocalId),
|
||||
grp.GetPartDescription(grp.LocalId),
|
||||
(sbyte)AssetType.Object,
|
||||
Utils.StringToBytes(sceneObjectXml),
|
||||
sp.UUID);
|
||||
|
||||
m_scene.AssetService.Store(asset);
|
||||
|
||||
InventoryItemBase item = new InventoryItemBase();
|
||||
item.CreatorId = grp.RootPart.CreatorID.ToString();
|
||||
item.CreatorData = grp.RootPart.CreatorData;
|
||||
item.Owner = sp.UUID;
|
||||
item.ID = UUID.Random();
|
||||
item.AssetID = asset.FullID;
|
||||
item.Description = asset.Description;
|
||||
item.Name = asset.Name;
|
||||
item.AssetType = asset.Type;
|
||||
item.InvType = (int)InventoryType.Object;
|
||||
|
||||
InventoryFolderBase folder = m_scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object);
|
||||
if (folder != null)
|
||||
item.Folder = folder.ID;
|
||||
else // oopsies
|
||||
item.Folder = UUID.Zero;
|
||||
|
||||
if ((sp.UUID != grp.RootPart.OwnerID) && m_scene.Permissions.PropagatePermissions())
|
||||
{
|
||||
item.BasePermissions = grp.RootPart.NextOwnerMask;
|
||||
item.CurrentPermissions = grp.RootPart.NextOwnerMask;
|
||||
item.NextPermissions = grp.RootPart.NextOwnerMask;
|
||||
item.EveryOnePermissions = grp.RootPart.EveryoneMask & grp.RootPart.NextOwnerMask;
|
||||
item.GroupPermissions = grp.RootPart.GroupMask & grp.RootPart.NextOwnerMask;
|
||||
}
|
||||
else
|
||||
{
|
||||
item.BasePermissions = grp.RootPart.BaseMask;
|
||||
item.CurrentPermissions = grp.RootPart.OwnerMask;
|
||||
item.NextPermissions = grp.RootPart.NextOwnerMask;
|
||||
item.EveryOnePermissions = grp.RootPart.EveryoneMask;
|
||||
item.GroupPermissions = grp.RootPart.GroupMask;
|
||||
}
|
||||
item.CreationDate = Util.UnixTimeSinceEpoch();
|
||||
InventoryItemBase newItem = m_invAccessModule.CopyToInventory(
|
||||
DeRezAction.TakeCopy,
|
||||
m_scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object).ID,
|
||||
new List<SceneObjectGroup> { grp },
|
||||
sp.ControllingClient, true)[0];
|
||||
|
||||
// sets itemID so client can show item as 'attached' in inventory
|
||||
grp.SetFromItemID(item.ID);
|
||||
grp.FromItemID = newItem.ID;
|
||||
|
||||
if (m_scene.AddInventoryItem(item))
|
||||
{
|
||||
sp.ControllingClient.SendInventoryItemCreateUpdate(item, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_dialogModule != null)
|
||||
m_dialogModule.SendAlertToUser(sp.ControllingClient, "Operation failed");
|
||||
}
|
||||
|
||||
return item;
|
||||
return newItem;
|
||||
}
|
||||
|
||||
// What makes this method odd and unique is it tries to detach using an UUID.... Yay for standards.
|
||||
@@ -683,7 +620,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
if (entity is SceneObjectGroup)
|
||||
{
|
||||
group = (SceneObjectGroup)entity;
|
||||
if (group.GetFromItemID() == itemID)
|
||||
if (group.FromItemID == itemID)
|
||||
{
|
||||
m_scene.EventManager.TriggerOnAttach(group.LocalId, itemID, UUID.Zero);
|
||||
sp.RemoveAttachment(group);
|
||||
@@ -707,70 +644,69 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
private SceneObjectGroup RezSingleAttachmentFromInventoryInternal(
|
||||
IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt)
|
||||
{
|
||||
IInventoryAccessModule invAccess = m_scene.RequestModuleInterface<IInventoryAccessModule>();
|
||||
if (invAccess != null)
|
||||
if (m_invAccessModule == null)
|
||||
return null;
|
||||
|
||||
lock (sp.AttachmentsSyncLock)
|
||||
{
|
||||
lock (sp.AttachmentsSyncLock)
|
||||
SceneObjectGroup objatt;
|
||||
|
||||
if (itemID != UUID.Zero)
|
||||
objatt = m_invAccessModule.RezObject(sp.ControllingClient,
|
||||
itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true,
|
||||
false, false, sp.UUID, true);
|
||||
else
|
||||
objatt = m_invAccessModule.RezObject(sp.ControllingClient,
|
||||
null, assetID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true,
|
||||
false, false, sp.UUID, true);
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[ATTACHMENTS MODULE]: Retrieved single object {0} for attachment to {1} on point {2}",
|
||||
// objatt.Name, remoteClient.Name, AttachmentPt);
|
||||
|
||||
if (objatt != null)
|
||||
{
|
||||
SceneObjectGroup objatt;
|
||||
// HasGroupChanged is being set from within RezObject. Ideally it would be set by the caller.
|
||||
objatt.HasGroupChanged = false;
|
||||
bool tainted = false;
|
||||
if (attachmentPt != 0 && attachmentPt != objatt.AttachmentPoint)
|
||||
tainted = true;
|
||||
|
||||
if (itemID != UUID.Zero)
|
||||
objatt = invAccess.RezObject(sp.ControllingClient,
|
||||
itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true,
|
||||
false, false, sp.UUID, true);
|
||||
else
|
||||
objatt = invAccess.RezObject(sp.ControllingClient,
|
||||
null, assetID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true,
|
||||
false, false, sp.UUID, true);
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[ATTACHMENTS MODULE]: Retrieved single object {0} for attachment to {1} on point {2}",
|
||||
// objatt.Name, remoteClient.Name, AttachmentPt);
|
||||
|
||||
if (objatt != null)
|
||||
// This will throw if the attachment fails
|
||||
try
|
||||
{
|
||||
// HasGroupChanged is being set from within RezObject. Ideally it would be set by the caller.
|
||||
objatt.HasGroupChanged = false;
|
||||
bool tainted = false;
|
||||
if (attachmentPt != 0 && attachmentPt != objatt.AttachmentPoint)
|
||||
tainted = true;
|
||||
|
||||
// This will throw if the attachment fails
|
||||
try
|
||||
{
|
||||
AttachObject(sp, objatt, attachmentPt, false);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat(
|
||||
"[ATTACHMENTS MODULE]: Failed to attach {0} {1} for {2}, exception {3}{4}",
|
||||
objatt.Name, objatt.UUID, sp.Name, e.Message, e.StackTrace);
|
||||
|
||||
// Make sure the object doesn't stick around and bail
|
||||
sp.RemoveAttachment(objatt);
|
||||
m_scene.DeleteSceneObject(objatt, false);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (tainted)
|
||||
objatt.HasGroupChanged = true;
|
||||
|
||||
// Fire after attach, so we don't get messy perms dialogs
|
||||
// 4 == AttachedRez
|
||||
objatt.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 4);
|
||||
objatt.ResumeScripts();
|
||||
|
||||
// Do this last so that event listeners have access to all the effects of the attachment
|
||||
m_scene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, sp.UUID);
|
||||
|
||||
return objatt;
|
||||
AttachObject(sp, objatt, attachmentPt, false);
|
||||
}
|
||||
else
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.WarnFormat(
|
||||
"[ATTACHMENTS MODULE]: Could not retrieve item {0} for attaching to avatar {1} at point {2}",
|
||||
itemID, sp.Name, attachmentPt);
|
||||
m_log.ErrorFormat(
|
||||
"[ATTACHMENTS MODULE]: Failed to attach {0} {1} for {2}, exception {3}{4}",
|
||||
objatt.Name, objatt.UUID, sp.Name, e.Message, e.StackTrace);
|
||||
|
||||
// Make sure the object doesn't stick around and bail
|
||||
sp.RemoveAttachment(objatt);
|
||||
m_scene.DeleteSceneObject(objatt, false);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (tainted)
|
||||
objatt.HasGroupChanged = true;
|
||||
|
||||
// Fire after attach, so we don't get messy perms dialogs
|
||||
// 4 == AttachedRez
|
||||
objatt.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 4);
|
||||
objatt.ResumeScripts();
|
||||
|
||||
// Do this last so that event listeners have access to all the effects of the attachment
|
||||
m_scene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, sp.UUID);
|
||||
|
||||
return objatt;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.WarnFormat(
|
||||
"[ATTACHMENTS MODULE]: Could not retrieve item {0} for attaching to avatar {1} at point {2}",
|
||||
itemID, sp.Name, attachmentPt);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -889,13 +825,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
// Calls attach with a Zero position
|
||||
if (AttachObject(sp, part.ParentGroup, AttachmentPt, false))
|
||||
{
|
||||
m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId);
|
||||
// m_log.Debug(
|
||||
// "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId
|
||||
// + ", AttachmentPoint: " + AttachmentPt);
|
||||
|
||||
// Save avatar attachment information
|
||||
m_log.Debug(
|
||||
"[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId
|
||||
+ ", AttachmentPoint: " + AttachmentPt);
|
||||
|
||||
m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.FromItemID, remoteClient.AgentId);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
@@ -912,7 +847,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
|
||||
SceneObjectGroup group = m_scene.GetGroupByPrim(objectLocalID);
|
||||
if (sp != null && group != null)
|
||||
DetachSingleAttachmentToInv(sp, group.GetFromItemID());
|
||||
DetachSingleAttachmentToInv(sp, group.FromItemID);
|
||||
}
|
||||
|
||||
private void Client_OnDetachAttachmentIntoInv(UUID itemID, IClientAPI remoteClient)
|
||||
|
||||
@@ -72,7 +72,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
|
||||
config.AddConfig("Modules");
|
||||
config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule");
|
||||
|
||||
scene = SceneHelpers.SetupScene();
|
||||
scene = new SceneHelpers().SetupScene();
|
||||
m_attMod = new AttachmentsModule();
|
||||
SceneHelpers.SetupSceneModules(scene, config, m_attMod, new BasicInventoryAccessModule());
|
||||
}
|
||||
@@ -99,12 +99,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
|
||||
public void TestAddAttachmentFromGround()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
// TestHelpers.EnableLogging();
|
||||
|
||||
AddPresence();
|
||||
string attName = "att";
|
||||
|
||||
SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName).ParentGroup;
|
||||
SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, m_presence.UUID).ParentGroup;
|
||||
|
||||
m_attMod.AttachObject(m_presence, so, (uint)AttachmentPoint.Chest, false);
|
||||
|
||||
@@ -120,8 +120,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
|
||||
Assert.That(attSo.IsTemporary, Is.False);
|
||||
|
||||
// Check item status
|
||||
Assert.That(m_presence.Appearance.GetAttachpoint(
|
||||
attSo.GetFromItemID()), Is.EqualTo((int)AttachmentPoint.Chest));
|
||||
Assert.That(
|
||||
m_presence.Appearance.GetAttachpoint(attSo.FromItemID),
|
||||
Is.EqualTo((int)AttachmentPoint.Chest));
|
||||
|
||||
InventoryItemBase attachmentItem = scene.InventoryService.GetItem(new InventoryItemBase(attSo.FromItemID));
|
||||
Assert.That(attachmentItem, Is.Not.Null);
|
||||
Assert.That(attachmentItem.Name, Is.EqualTo(attName));
|
||||
|
||||
InventoryFolderBase targetFolder = scene.InventoryService.GetFolderForType(m_presence.UUID, AssetType.Object);
|
||||
Assert.That(attachmentItem.Folder, Is.EqualTo(targetFolder.ID));
|
||||
|
||||
// TestHelpers.DisableLogging();
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -111,6 +111,15 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
|
||||
#region IAvatarFactoryModule
|
||||
|
||||
/// </summary>
|
||||
/// <param name="sp"></param>
|
||||
/// <param name="texture"></param>
|
||||
/// <param name="visualParam"></param>
|
||||
public void SetAppearance(IScenePresence sp, AvatarAppearance appearance)
|
||||
{
|
||||
SetAppearance(sp, appearance.Texture, appearance.VisualParams);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set appearance data (texture asset IDs and slider settings)
|
||||
/// </summary>
|
||||
@@ -149,21 +158,30 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
// Process the baked texture array
|
||||
if (textureEntry != null)
|
||||
{
|
||||
m_log.InfoFormat("[AVFACTORY]: Received texture update for {0} {1}", sp.Name, sp.UUID);
|
||||
// m_log.DebugFormat("[AVFACTORY]: Received texture update for {0} {1}", sp.Name, sp.UUID);
|
||||
|
||||
// WriteBakedTexturesReport(sp, m_log.DebugFormat);
|
||||
|
||||
changed = sp.Appearance.SetTextureEntries(textureEntry) || changed;
|
||||
|
||||
// WriteBakedTexturesReport(sp, m_log.DebugFormat);
|
||||
if (!ValidateBakedTextureCache(sp))
|
||||
|
||||
// If bake textures are missing and this is not an NPC, request a rebake from client
|
||||
if (!ValidateBakedTextureCache(sp) && (((ScenePresence)sp).PresenceType != PresenceType.Npc))
|
||||
RequestRebake(sp, true);
|
||||
|
||||
// This appears to be set only in the final stage of the appearance
|
||||
// update transaction. In theory, we should be able to do an immediate
|
||||
// appearance send and save here.
|
||||
}
|
||||
|
||||
|
||||
// NPC should send to clients immediately and skip saving appearance
|
||||
if (((ScenePresence)sp).PresenceType == PresenceType.Npc)
|
||||
{
|
||||
SendAppearance((ScenePresence)sp);
|
||||
return;
|
||||
}
|
||||
|
||||
// save only if there were changes, send no matter what (doesn't hurt to send twice)
|
||||
if (changed)
|
||||
QueueAppearanceSave(sp.ControllingClient.AgentId);
|
||||
@@ -174,6 +192,15 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
// m_log.WarnFormat("[AVFACTORY]: complete SetAppearance for {0}:\n{1}",client.AgentId,sp.Appearance.ToString());
|
||||
}
|
||||
|
||||
private void SendAppearance(ScenePresence sp)
|
||||
{
|
||||
// Send the appearance to everyone in the scene
|
||||
sp.SendAppearanceToAllOtherAgents();
|
||||
|
||||
// Send animations back to the avatar as well
|
||||
sp.Animator.SendAnimPack();
|
||||
}
|
||||
|
||||
public bool SendAppearance(UUID agentId)
|
||||
{
|
||||
// m_log.DebugFormat("[AVFACTORY]: Sending appearance for {0}", agentId);
|
||||
@@ -181,16 +208,12 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
ScenePresence sp = m_scene.GetScenePresence(agentId);
|
||||
if (sp == null)
|
||||
{
|
||||
m_log.WarnFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentId);
|
||||
// This is expected if the user has gone away.
|
||||
// m_log.DebugFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentId);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Send the appearance to everyone in the scene
|
||||
sp.SendAppearanceToAllOtherAgents();
|
||||
|
||||
// Send animations back to the avatar as well
|
||||
sp.Animator.SendAnimPack();
|
||||
|
||||
SendAppearance(sp);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -315,7 +338,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
return false;
|
||||
}
|
||||
|
||||
m_log.DebugFormat("[AVFACTORY]: Completed texture check for {0} {1}", sp.Name, sp.UUID);
|
||||
// m_log.DebugFormat("[AVFACTORY]: Completed texture check for {0} {1}", sp.Name, sp.UUID);
|
||||
|
||||
// If we only found default textures, then the appearance is not cached
|
||||
return (defonly ? false : true);
|
||||
@@ -348,11 +371,21 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
if (missingTexturesOnly)
|
||||
{
|
||||
if (m_scene.AssetService.Get(face.TextureID.ToString()) != null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
// On inter-simulator teleports, this occurs if baked textures are not being stored by the
|
||||
// grid asset service (which means that they are not available to the new region and so have
|
||||
// to be re-requested from the client).
|
||||
//
|
||||
// The only available core OpenSimulator behaviour right now
|
||||
// is not to store these textures, temporarily or otherwise.
|
||||
m_log.DebugFormat(
|
||||
"[AVFACTORY]: Missing baked texture {0} ({1}) for {2}, requesting rebake.",
|
||||
face.TextureID, idx, sp.Name);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -460,7 +493,8 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
ScenePresence sp = m_scene.GetScenePresence(agentid);
|
||||
if (sp == null)
|
||||
{
|
||||
m_log.WarnFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentid);
|
||||
// This is expected if the user has gone away.
|
||||
// m_log.DebugFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentid);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -474,6 +508,10 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
SetAppearanceAssets(sp.UUID, sp.Appearance);
|
||||
|
||||
m_scene.AvatarService.SetAppearance(agentid, sp.Appearance);
|
||||
|
||||
// Trigger this here because it's the final step in the set/queue/save process for appearance setting.
|
||||
// Everything has been updated and stored. Ensures bakes have been persisted (if option is set to persist bakes).
|
||||
m_scene.EventManager.TriggerAvatarAppearanceChanged(sp);
|
||||
}
|
||||
|
||||
private void SetAppearanceAssets(UUID userID, AvatarAppearance appearance)
|
||||
@@ -626,4 +664,4 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
outputAction("{0} baked appearance texture is {1}", sp.Name, bakedTextureValid ? "OK" : "corrupt");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
UUID userId = TestHelpers.ParseTail(0x1);
|
||||
|
||||
AvatarFactoryModule afm = new AvatarFactoryModule();
|
||||
TestScene scene = SceneHelpers.SetupScene();
|
||||
TestScene scene = new SceneHelpers().SetupScene();
|
||||
SceneHelpers.SetupSceneModules(scene, afm);
|
||||
ScenePresence sp = SceneHelpers.AddScenePresence(scene, userId);
|
||||
|
||||
@@ -81,7 +81,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
CoreAssetCache assetCache = new CoreAssetCache();
|
||||
|
||||
AvatarFactoryModule afm = new AvatarFactoryModule();
|
||||
TestScene scene = SceneHelpers.SetupScene(assetCache);
|
||||
TestScene scene = new SceneHelpers(assetCache).SetupScene();
|
||||
SceneHelpers.SetupSceneModules(scene, afm);
|
||||
ScenePresence sp = SceneHelpers.AddScenePresence(scene, userId);
|
||||
|
||||
|
||||
189
OpenSim/Region/CoreModules/Avatar/Commands/UserCommandsModule.cs
Normal file
189
OpenSim/Region/CoreModules/Avatar/Commands/UserCommandsModule.cs
Normal file
@@ -0,0 +1,189 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using log4net;
|
||||
using Mono.Addins;
|
||||
using NDesk.Options;
|
||||
using Nini.Config;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Console;
|
||||
using OpenSim.Framework.Statistics;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
|
||||
namespace OpenSim.Region.CoreModules.Avatars.Commands
|
||||
{
|
||||
/// <summary>
|
||||
/// A module that holds commands for manipulating objects in the scene.
|
||||
/// </summary>
|
||||
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "UserCommandsModule")]
|
||||
public class UserCommandsModule : ISharedRegionModule
|
||||
{
|
||||
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
public const string TeleportUserCommandSyntax = "teleport user <first-name> <last-name> <destination>";
|
||||
|
||||
public static Regex InterRegionDestinationRegex
|
||||
= new Regex(@"^(?<regionName>.+)/(?<x>\d+)/(?<y>\d+)/(?<z>\d+)$", RegexOptions.Compiled);
|
||||
|
||||
public static Regex WithinRegionDestinationRegex
|
||||
= new Regex(@"^(?<x>\d+)/(?<y>\d+)/(?<z>\d+)$", RegexOptions.Compiled);
|
||||
|
||||
private Dictionary<UUID, Scene> m_scenes = new Dictionary<UUID, Scene>();
|
||||
|
||||
public string Name { get { return "User Commands Module"; } }
|
||||
|
||||
public Type ReplaceableInterface { get { return null; } }
|
||||
|
||||
public void Initialise(IConfigSource source)
|
||||
{
|
||||
// m_log.DebugFormat("[USER COMMANDS MODULE]: INITIALIZED MODULE");
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
// m_log.DebugFormat("[USER COMMANDS MODULE]: POST INITIALIZED MODULE");
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
// m_log.DebugFormat("[USER COMMANDS MODULE]: CLOSED MODULE");
|
||||
}
|
||||
|
||||
public void AddRegion(Scene scene)
|
||||
{
|
||||
// m_log.DebugFormat("[USER COMMANDS MODULE]: REGION {0} ADDED", scene.RegionInfo.RegionName);
|
||||
|
||||
lock (m_scenes)
|
||||
m_scenes[scene.RegionInfo.RegionID] = scene;
|
||||
|
||||
scene.AddCommand(
|
||||
"Users",
|
||||
this,
|
||||
"teleport user",
|
||||
TeleportUserCommandSyntax,
|
||||
"Teleport a user in this simulator to the given destination",
|
||||
"<destination> is in format [<region-name>]/<x>/<y>/<z>, e.g. regionone/20/30/40 or just 20/30/40 to teleport within same region."
|
||||
+ "\nIf the region contains a space then the whole destination must be in quotes, e.g. \"region one/20/30/40\"",
|
||||
HandleTeleportUser);
|
||||
}
|
||||
|
||||
public void RemoveRegion(Scene scene)
|
||||
{
|
||||
// m_log.DebugFormat("[USER COMMANDS MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName);
|
||||
|
||||
lock (m_scenes)
|
||||
m_scenes.Remove(scene.RegionInfo.RegionID);
|
||||
}
|
||||
|
||||
public void RegionLoaded(Scene scene)
|
||||
{
|
||||
// m_log.DebugFormat("[USER COMMANDS MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName);
|
||||
}
|
||||
|
||||
private ScenePresence GetUser(string firstName, string lastName)
|
||||
{
|
||||
ScenePresence userFound = null;
|
||||
|
||||
lock (m_scenes)
|
||||
{
|
||||
foreach (Scene scene in m_scenes.Values)
|
||||
{
|
||||
ScenePresence user = scene.GetScenePresence(firstName, lastName);
|
||||
if (user != null && !user.IsChildAgent)
|
||||
{
|
||||
userFound = user;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return userFound;
|
||||
}
|
||||
|
||||
private void HandleTeleportUser(string module, string[] cmd)
|
||||
{
|
||||
if (cmd.Length < 5)
|
||||
{
|
||||
MainConsole.Instance.OutputFormat("Usage: " + TeleportUserCommandSyntax);
|
||||
return;
|
||||
}
|
||||
|
||||
string firstName = cmd[2];
|
||||
string lastName = cmd[3];
|
||||
string rawDestination = cmd[4];
|
||||
|
||||
ScenePresence user = GetUser(firstName, lastName);
|
||||
|
||||
if (user == null)
|
||||
{
|
||||
MainConsole.Instance.OutputFormat("No user found with name {0} {1}", firstName, lastName);
|
||||
return;
|
||||
}
|
||||
|
||||
// MainConsole.Instance.OutputFormat("rawDestination [{0}]", rawDestination);
|
||||
|
||||
Match m = WithinRegionDestinationRegex.Match(rawDestination);
|
||||
|
||||
if (!m.Success)
|
||||
{
|
||||
m = InterRegionDestinationRegex.Match(rawDestination);
|
||||
|
||||
if (!m.Success)
|
||||
{
|
||||
MainConsole.Instance.OutputFormat("Invalid destination {0}", rawDestination);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
string regionName
|
||||
= m.Groups["regionName"].Success ? m.Groups["regionName"].Value : user.Scene.RegionInfo.RegionName;
|
||||
|
||||
MainConsole.Instance.OutputFormat(
|
||||
"Teleporting {0} to {1},{2},{3} in {4}",
|
||||
user.Name,
|
||||
m.Groups["x"], m.Groups["y"], m.Groups["z"],
|
||||
regionName);
|
||||
|
||||
user.Scene.RequestTeleportLocation(
|
||||
user.ControllingClient,
|
||||
regionName,
|
||||
new Vector3(
|
||||
float.Parse(m.Groups["x"].Value),
|
||||
float.Parse(m.Groups["y"].Value),
|
||||
float.Parse(m.Groups["z"].Value)),
|
||||
user.Lookat,
|
||||
(uint)TeleportFlags.ViaLocation);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -51,12 +51,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog
|
||||
m_scene.RegisterModuleInterface<IDialogModule>(this);
|
||||
|
||||
m_scene.AddCommand(
|
||||
this, "alert", "alert <message>",
|
||||
"Users", this, "alert", "alert <message>",
|
||||
"Send an alert to everyone",
|
||||
HandleAlertConsoleCommand);
|
||||
|
||||
m_scene.AddCommand(
|
||||
this, "alert-user", "alert-user <first> <last> <message>",
|
||||
"Users", this, "alert-user", "alert-user <first> <last> <message>",
|
||||
"Send an alert to a user",
|
||||
HandleAlertConsoleCommand);
|
||||
}
|
||||
|
||||
313
OpenSim/Region/CoreModules/Avatar/Friends/CallingCardModule.cs
Normal file
313
OpenSim/Region/CoreModules/Avatar/Friends/CallingCardModule.cs
Normal file
@@ -0,0 +1,313 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using Mono.Addins;
|
||||
|
||||
namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
{
|
||||
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "XCallingCard")]
|
||||
public class CallingCardModule : ISharedRegionModule, ICallingCardModule
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
protected List<Scene> m_Scenes = new List<Scene>();
|
||||
protected bool m_Enabled = true;
|
||||
|
||||
public void Initialise(IConfigSource source)
|
||||
{
|
||||
IConfig ccConfig = source.Configs["XCallingCard"];
|
||||
if (ccConfig != null)
|
||||
m_Enabled = ccConfig.GetBoolean("Enabled", true);
|
||||
}
|
||||
|
||||
public void AddRegion(Scene scene)
|
||||
{
|
||||
if (!m_Enabled)
|
||||
return;
|
||||
|
||||
m_Scenes.Add(scene);
|
||||
|
||||
scene.RegisterModuleInterface<ICallingCardModule>(this);
|
||||
}
|
||||
|
||||
public void RemoveRegion(Scene scene)
|
||||
{
|
||||
if (!m_Enabled)
|
||||
return;
|
||||
|
||||
m_Scenes.Remove(scene);
|
||||
|
||||
scene.EventManager.OnNewClient -= OnNewClient;
|
||||
scene.EventManager.OnIncomingInstantMessage +=
|
||||
OnIncomingInstantMessage;
|
||||
|
||||
scene.UnregisterModuleInterface<ICallingCardModule>(this);
|
||||
}
|
||||
|
||||
public void RegionLoaded(Scene scene)
|
||||
{
|
||||
if (!m_Enabled)
|
||||
return;
|
||||
scene.EventManager.OnNewClient += OnNewClient;
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
}
|
||||
|
||||
public Type ReplaceableInterface
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return "XCallingCardModule"; }
|
||||
}
|
||||
|
||||
private void OnNewClient(IClientAPI client)
|
||||
{
|
||||
client.OnOfferCallingCard += OnOfferCallingCard;
|
||||
client.OnAcceptCallingCard += OnAcceptCallingCard;
|
||||
client.OnDeclineCallingCard += OnDeclineCallingCard;
|
||||
}
|
||||
|
||||
private void OnOfferCallingCard(IClientAPI client, UUID destID, UUID transactionID)
|
||||
{
|
||||
ScenePresence sp = GetClientPresence(client.AgentId);
|
||||
if (sp != null)
|
||||
{
|
||||
// If we're in god mode, we reverse the meaning. Offer
|
||||
// calling card becomes "Take a calling card" for that
|
||||
// person, no matter if they agree or not.
|
||||
if (sp.GodLevel >= 200)
|
||||
{
|
||||
CreateCallingCard(client.AgentId, destID, UUID.Zero, true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
IClientAPI dest = FindClientObject(destID);
|
||||
if (dest != null)
|
||||
{
|
||||
DoCallingCardOffer(dest, client.AgentId);
|
||||
return;
|
||||
}
|
||||
|
||||
IMessageTransferModule transferModule =
|
||||
m_Scenes[0].RequestModuleInterface<IMessageTransferModule>();
|
||||
|
||||
if (transferModule != null)
|
||||
{
|
||||
transferModule.SendInstantMessage(new GridInstantMessage(
|
||||
client.Scene, client.AgentId,
|
||||
client.FirstName+" "+client.LastName,
|
||||
destID, (byte)211, false,
|
||||
String.Empty,
|
||||
transactionID, false, new Vector3(), new byte[0]),
|
||||
delegate(bool success) {} );
|
||||
}
|
||||
}
|
||||
|
||||
private void DoCallingCardOffer(IClientAPI dest, UUID from)
|
||||
{
|
||||
UUID itemID = CreateCallingCard(dest.AgentId, from, UUID.Zero, false);
|
||||
|
||||
dest.SendOfferCallingCard(from, itemID);
|
||||
}
|
||||
|
||||
// Create a calling card in the user's inventory. This is called
|
||||
// from direct calling card creation, when the offer is forwarded,
|
||||
// and from the friends module when the friend is confirmed.
|
||||
// Because of the latter, it will send a bulk inventory update
|
||||
// if the receiving user is in the same simulator.
|
||||
public UUID CreateCallingCard(UUID userID, UUID creatorID, UUID folderID)
|
||||
{
|
||||
return CreateCallingCard(userID, creatorID, folderID, false);
|
||||
}
|
||||
|
||||
private UUID CreateCallingCard(UUID userID, UUID creatorID, UUID folderID, bool isGod)
|
||||
{
|
||||
IUserAccountService userv = m_Scenes[0].UserAccountService;
|
||||
if (userv == null)
|
||||
return UUID.Zero;
|
||||
|
||||
UserAccount info = userv.GetUserAccount(UUID.Zero, creatorID);
|
||||
if (info == null)
|
||||
return UUID.Zero;
|
||||
|
||||
IInventoryService inv = m_Scenes[0].InventoryService;
|
||||
if (inv == null)
|
||||
return UUID.Zero;
|
||||
|
||||
if (folderID == UUID.Zero)
|
||||
{
|
||||
InventoryFolderBase folder = inv.GetFolderForType(userID,
|
||||
AssetType.CallingCard);
|
||||
|
||||
if (folder == null) // Nowhere to put it
|
||||
return UUID.Zero;
|
||||
|
||||
folderID = folder.ID;
|
||||
}
|
||||
|
||||
m_log.DebugFormat("[XCALLINGCARD]: Creating calling card for {0} in inventory of {1}", info.Name, userID);
|
||||
|
||||
InventoryItemBase item = new InventoryItemBase();
|
||||
item.AssetID = UUID.Zero;
|
||||
item.AssetType = (int)AssetType.CallingCard;
|
||||
item.BasePermissions = (uint)(PermissionMask.Copy | PermissionMask.Modify);
|
||||
if (isGod)
|
||||
item.BasePermissions = (uint)(PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer | PermissionMask.Move);
|
||||
|
||||
item.EveryOnePermissions = (uint)PermissionMask.None;
|
||||
item.CurrentPermissions = item.BasePermissions;
|
||||
item.NextPermissions = (uint)(PermissionMask.Copy | PermissionMask.Modify);
|
||||
|
||||
item.ID = UUID.Random();
|
||||
item.CreatorId = creatorID.ToString();
|
||||
item.Owner = userID;
|
||||
item.GroupID = UUID.Zero;
|
||||
item.GroupOwned = false;
|
||||
item.Folder = folderID;
|
||||
|
||||
item.CreationDate = Util.UnixTimeSinceEpoch();
|
||||
item.InvType = (int)InventoryType.CallingCard;
|
||||
item.Flags = 0;
|
||||
|
||||
item.Name = info.Name;
|
||||
item.Description = "";
|
||||
|
||||
item.SalePrice = 10;
|
||||
item.SaleType = (byte)SaleType.Not;
|
||||
|
||||
inv.AddItem(item);
|
||||
|
||||
IClientAPI client = FindClientObject(userID);
|
||||
if (client != null)
|
||||
client.SendBulkUpdateInventory(item);
|
||||
|
||||
return item.ID;
|
||||
}
|
||||
|
||||
private void OnAcceptCallingCard(IClientAPI client, UUID transactionID, UUID folderID)
|
||||
{
|
||||
}
|
||||
|
||||
private void OnDeclineCallingCard(IClientAPI client, UUID transactionID)
|
||||
{
|
||||
IInventoryService invService = m_Scenes[0].InventoryService;
|
||||
|
||||
InventoryFolderBase trashFolder =
|
||||
invService.GetFolderForType(client.AgentId, AssetType.TrashFolder);
|
||||
|
||||
InventoryItemBase item = new InventoryItemBase(transactionID, client.AgentId);
|
||||
item = invService.GetItem(item);
|
||||
|
||||
if (item != null && trashFolder != null)
|
||||
{
|
||||
item.Folder = trashFolder.ID;
|
||||
List<UUID> uuids = new List<UUID>();
|
||||
uuids.Add(item.ID);
|
||||
invService.DeleteItems(item.Owner, uuids);
|
||||
m_Scenes[0].AddInventoryItem(client, item);
|
||||
}
|
||||
}
|
||||
|
||||
public IClientAPI FindClientObject(UUID agentID)
|
||||
{
|
||||
Scene scene = GetClientScene(agentID);
|
||||
if (scene == null)
|
||||
return null;
|
||||
|
||||
ScenePresence presence = scene.GetScenePresence(agentID);
|
||||
if (presence == null)
|
||||
return null;
|
||||
|
||||
return presence.ControllingClient;
|
||||
}
|
||||
|
||||
private Scene GetClientScene(UUID agentId)
|
||||
{
|
||||
lock (m_Scenes)
|
||||
{
|
||||
foreach (Scene scene in m_Scenes)
|
||||
{
|
||||
ScenePresence presence = scene.GetScenePresence(agentId);
|
||||
if (presence != null)
|
||||
{
|
||||
if (!presence.IsChildAgent)
|
||||
return scene;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private ScenePresence GetClientPresence(UUID agentId)
|
||||
{
|
||||
lock (m_Scenes)
|
||||
{
|
||||
foreach (Scene scene in m_Scenes)
|
||||
{
|
||||
ScenePresence presence = scene.GetScenePresence(agentId);
|
||||
if (presence != null)
|
||||
{
|
||||
if (!presence.IsChildAgent)
|
||||
return presence;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void OnIncomingInstantMessage(GridInstantMessage msg)
|
||||
{
|
||||
if (msg.dialog == (uint)211)
|
||||
{
|
||||
IClientAPI client = FindClientObject(new UUID(msg.toAgentID));
|
||||
if (client == null)
|
||||
return;
|
||||
|
||||
DoCallingCardOffer(client, new UUID(msg.fromAgentID));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -51,6 +51,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
{
|
||||
public class FriendsModule : ISharedRegionModule, IFriendsModule
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
protected bool m_Enabled = false;
|
||||
|
||||
protected class UserFriendData
|
||||
@@ -72,7 +74,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
}
|
||||
|
||||
protected static readonly FriendInfo[] EMPTY_FRIENDS = new FriendInfo[0];
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
protected List<Scene> m_Scenes = new List<Scene>();
|
||||
|
||||
@@ -109,7 +110,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
}
|
||||
}
|
||||
|
||||
protected IFriendsService FriendsService
|
||||
public IFriendsService FriendsService
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -156,7 +157,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
InitModule(config);
|
||||
|
||||
m_Enabled = true;
|
||||
m_log.InfoFormat("[FRIENDS MODULE]: {0} enabled.", Name);
|
||||
m_log.DebugFormat("[FRIENDS MODULE]: {0} enabled.", Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -201,7 +202,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
if (!m_Enabled)
|
||||
return;
|
||||
|
||||
m_log.DebugFormat("[FRIENDS MODULE]: AddRegion on {0}", Name);
|
||||
// m_log.DebugFormat("[FRIENDS MODULE]: AddRegion on {0}", Name);
|
||||
|
||||
m_Scenes.Add(scene);
|
||||
scene.RegisterModuleInterface<IFriendsModule>(this);
|
||||
@@ -212,9 +213,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
scene.EventManager.OnClientLogin += OnClientLogin;
|
||||
}
|
||||
|
||||
public void RegionLoaded(Scene scene)
|
||||
{
|
||||
}
|
||||
public virtual void RegionLoaded(Scene scene) {}
|
||||
|
||||
public void RemoveRegion(Scene scene)
|
||||
{
|
||||
@@ -236,13 +235,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
|
||||
#endregion
|
||||
|
||||
public virtual uint GetFriendPerms(UUID principalID, UUID friendID)
|
||||
public virtual int GetRightsGrantedByFriend(UUID principalID, UUID friendID)
|
||||
{
|
||||
FriendInfo[] friends = GetFriends(principalID);
|
||||
FriendInfo[] friends = GetFriendsFromCache(principalID);
|
||||
FriendInfo finfo = GetFriend(friends, friendID);
|
||||
if (finfo != null)
|
||||
{
|
||||
return (uint)finfo.TheirFlags;
|
||||
return finfo.TheirFlags;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -253,9 +252,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
client.OnInstantMessage += OnInstantMessage;
|
||||
client.OnApproveFriendRequest += OnApproveFriendRequest;
|
||||
client.OnDenyFriendRequest += OnDenyFriendRequest;
|
||||
client.OnTerminateFriendship += (thisClient, agentID, exfriendID) => RemoveFriendship(thisClient, exfriendID);
|
||||
client.OnGrantUserRights += OnGrantUserRights;
|
||||
client.OnTerminateFriendship += RemoveFriendship;
|
||||
client.OnGrantUserRights += GrantRights;
|
||||
|
||||
// We need to cache information for child agents as well as root agents so that friend edit/move/delete
|
||||
// permissions will work across borders where both regions are on different simulators.
|
||||
//
|
||||
// Do not do this asynchronously. If we do, then subsequent code can outrace CacheFriends() and
|
||||
// return misleading results from the still empty friends cache.
|
||||
// If we absolutely need to do this asynchronously, then a signalling mechanism is needed so that calls
|
||||
@@ -328,7 +330,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
//m_log.DebugFormat("[XXX]: OnClientLogin!");
|
||||
// Inform the friends that this user is online
|
||||
StatusChange(agentID, true);
|
||||
|
||||
|
||||
// Register that we need to send the list of online friends to this user
|
||||
lock (m_NeedsListOfOnlineFriends)
|
||||
m_NeedsListOfOnlineFriends.Add(agentID);
|
||||
@@ -347,18 +349,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
|
||||
// Send the friends online
|
||||
List<UUID> online = GetOnlineFriends(agentID);
|
||||
if (online.Count > 0)
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"[FRIENDS MODULE]: User {0} in region {1} has {2} friends online",
|
||||
client.Name, client.Scene.RegionInfo.RegionName, online.Count);
|
||||
|
||||
if (online.Count > 0)
|
||||
client.SendAgentOnline(online.ToArray());
|
||||
}
|
||||
|
||||
// Send outstanding friendship offers
|
||||
List<string> outstanding = new List<string>();
|
||||
FriendInfo[] friends = GetFriends(agentID);
|
||||
FriendInfo[] friends = GetFriendsFromCache(agentID);
|
||||
foreach (FriendInfo fi in friends)
|
||||
{
|
||||
if (fi.TheirFlags == -1)
|
||||
@@ -414,23 +411,30 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
List<UUID> GetOnlineFriends(UUID userID)
|
||||
{
|
||||
List<string> friendList = new List<string>();
|
||||
List<UUID> online = new List<UUID>();
|
||||
|
||||
FriendInfo[] friends = GetFriends(userID);
|
||||
FriendInfo[] friends = GetFriendsFromCache(userID);
|
||||
foreach (FriendInfo fi in friends)
|
||||
{
|
||||
if (((fi.TheirFlags & 1) != 0) && (fi.TheirFlags != -1))
|
||||
if (((fi.TheirFlags & (int)FriendRights.CanSeeOnline) != 0) && (fi.TheirFlags != -1))
|
||||
friendList.Add(fi.Friend);
|
||||
}
|
||||
|
||||
List<UUID> online = new List<UUID>();
|
||||
|
||||
if (friendList.Count > 0)
|
||||
GetOnlineFriends(userID, friendList, online);
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[FRIENDS MODULE]: User {0} has {1} friends online", userID, online.Count);
|
||||
|
||||
return online;
|
||||
}
|
||||
|
||||
protected virtual void GetOnlineFriends(UUID userID, List<string> friendList, /*collector*/ List<UUID> online)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[FRIENDS MODULE]: Looking for online presence of {0} users for {1}", friendList.Count, userID);
|
||||
|
||||
PresenceInfo[] presence = PresenceService.GetAgents(friendList.ToArray());
|
||||
foreach (PresenceInfo pi in presence)
|
||||
{
|
||||
@@ -444,30 +448,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
/// Find the client for a ID
|
||||
/// </summary>
|
||||
public IClientAPI LocateClientObject(UUID agentID)
|
||||
{
|
||||
Scene scene = GetClientScene(agentID);
|
||||
if (scene != null)
|
||||
{
|
||||
ScenePresence presence = scene.GetScenePresence(agentID);
|
||||
if (presence != null)
|
||||
return presence.ControllingClient;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Find the scene for an agent
|
||||
/// </summary>
|
||||
private Scene GetClientScene(UUID agentId)
|
||||
{
|
||||
lock (m_Scenes)
|
||||
{
|
||||
foreach (Scene scene in m_Scenes)
|
||||
{
|
||||
ScenePresence presence = scene.GetScenePresence(agentId);
|
||||
ScenePresence presence = scene.GetScenePresence(agentID);
|
||||
if (presence != null && !presence.IsChildAgent)
|
||||
return scene;
|
||||
return presence.ControllingClient;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -481,20 +469,23 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
/// <param name="online"></param>
|
||||
private void StatusChange(UUID agentID, bool online)
|
||||
{
|
||||
FriendInfo[] friends = GetFriends(agentID);
|
||||
FriendInfo[] friends = GetFriendsFromCache(agentID);
|
||||
if (friends.Length > 0)
|
||||
{
|
||||
List<FriendInfo> friendList = new List<FriendInfo>();
|
||||
foreach (FriendInfo fi in friends)
|
||||
{
|
||||
if (((fi.MyFlags & 1) != 0) && (fi.TheirFlags != -1))
|
||||
if (((fi.MyFlags & (int)FriendRights.CanSeeOnline) != 0) && (fi.TheirFlags != -1))
|
||||
friendList.Add(fi);
|
||||
}
|
||||
|
||||
Util.FireAndForget(
|
||||
delegate
|
||||
{
|
||||
m_log.DebugFormat("[FRIENDS MODULE]: Notifying {0} friends", friendList.Count);
|
||||
m_log.DebugFormat(
|
||||
"[FRIENDS MODULE]: Notifying {0} friends of {1} of online status {2}",
|
||||
friendList.Count, agentID, online);
|
||||
|
||||
// Notify about this user status
|
||||
StatusNotify(friendList, agentID, online);
|
||||
}
|
||||
@@ -511,7 +502,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
{
|
||||
// Try local
|
||||
if (LocalStatusNotification(userID, friendID, online))
|
||||
return;
|
||||
continue;
|
||||
|
||||
// The friend is not here [as root]. Let's forward.
|
||||
PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() });
|
||||
@@ -519,11 +510,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
{
|
||||
PresenceInfo friendSession = null;
|
||||
foreach (PresenceInfo pinfo in friendSessions)
|
||||
{
|
||||
if (pinfo.RegionID != UUID.Zero) // let's guard against sessions-gone-bad
|
||||
{
|
||||
friendSession = pinfo;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (friendSession != null)
|
||||
{
|
||||
@@ -550,7 +543,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
UUID principalID = new UUID(im.fromAgentID);
|
||||
UUID friendID = new UUID(im.toAgentID);
|
||||
|
||||
m_log.DebugFormat("[FRIENDS]: {0} ({1}) offered friendship to {2}", principalID, im.fromAgentName, friendID);
|
||||
m_log.DebugFormat("[FRIENDS]: {0} ({1}) offered friendship to {2} ({3})", principalID, client.FirstName + client.LastName, friendID, im.fromAgentName);
|
||||
|
||||
// Check that the friendship doesn't exist yet
|
||||
FriendInfo[] finfos = GetFriendsFromCache(principalID);
|
||||
if (finfos != null)
|
||||
{
|
||||
FriendInfo f = GetFriend(finfos, friendID);
|
||||
if (f != null)
|
||||
{
|
||||
client.SendAgentAlertMessage("This person is already your friend. Please delete it first if you want to reestablish the friendship.", false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// This user wants to be friends with the other user.
|
||||
// Let's add the relation backwards, in case the other is not online
|
||||
@@ -592,7 +597,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
return (account == null) ? "Unknown" : account.FirstName + " " + account.LastName;
|
||||
}
|
||||
|
||||
private void OnApproveFriendRequest(IClientAPI client, UUID agentID, UUID friendID, List<UUID> callingCardFolders)
|
||||
protected virtual void OnApproveFriendRequest(IClientAPI client, UUID friendID, List<UUID> callingCardFolders)
|
||||
{
|
||||
m_log.DebugFormat("[FRIENDS]: {0} accepted friendship from {1}", client.AgentId, friendID);
|
||||
|
||||
@@ -603,8 +608,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
{
|
||||
StoreFriendships(client.AgentId, friendID);
|
||||
|
||||
// Update the local cache
|
||||
RecacheFriends(client);
|
||||
ICallingCardModule ccm = client.Scene.RequestModuleInterface<ICallingCardModule>();
|
||||
if (ccm != null)
|
||||
{
|
||||
ccm.CreateCallingCard(client.AgentId, friendID, UUID.Zero);
|
||||
}
|
||||
|
||||
// Update the local cache.
|
||||
CacheFriends(client);
|
||||
|
||||
//
|
||||
// Notify the friend
|
||||
@@ -631,18 +642,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDenyFriendRequest(IClientAPI client, UUID agentID, UUID friendID, List<UUID> callingCardFolders)
|
||||
private void OnDenyFriendRequest(IClientAPI client, UUID friendID, List<UUID> callingCardFolders)
|
||||
{
|
||||
m_log.DebugFormat("[FRIENDS]: {0} denied friendship to {1}", agentID, friendID);
|
||||
m_log.DebugFormat("[FRIENDS]: {0} denied friendship to {1}", client.AgentId, friendID);
|
||||
|
||||
DeleteFriendship(agentID, friendID);
|
||||
DeleteFriendship(client.AgentId, friendID);
|
||||
|
||||
//
|
||||
// Notify the friend
|
||||
//
|
||||
|
||||
// Try local
|
||||
if (LocalFriendshipDenied(agentID, client.Name, friendID))
|
||||
if (LocalFriendshipDenied(client.AgentId, client.Name, friendID))
|
||||
return;
|
||||
|
||||
PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() });
|
||||
@@ -653,7 +664,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
{
|
||||
GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID);
|
||||
if (region != null)
|
||||
m_FriendsSimConnector.FriendshipDenied(region, agentID, client.Name, friendID);
|
||||
m_FriendsSimConnector.FriendshipDenied(region, client.AgentId, client.Name, friendID);
|
||||
else
|
||||
m_log.WarnFormat("[FRIENDS]: Could not find region {0} in locating {1}", friendSession.RegionID, friendID);
|
||||
}
|
||||
@@ -690,23 +701,27 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
}
|
||||
}
|
||||
|
||||
private void OnGrantUserRights(IClientAPI remoteClient, UUID requester, UUID target, int rights)
|
||||
public void GrantRights(IClientAPI remoteClient, UUID friendID, int rights)
|
||||
{
|
||||
m_log.DebugFormat("[FRIENDS MODULE]: User {0} changing rights to {1} for friend {2}", requester, rights, target);
|
||||
UUID requester = remoteClient.AgentId;
|
||||
|
||||
FriendInfo[] friends = GetFriends(remoteClient.AgentId);
|
||||
m_log.DebugFormat(
|
||||
"[FRIENDS MODULE]: User {0} changing rights to {1} for friend {2}",
|
||||
requester, rights, friendID);
|
||||
|
||||
FriendInfo[] friends = GetFriendsFromCache(requester);
|
||||
if (friends.Length == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Let's find the friend in this user's friend list
|
||||
FriendInfo friend = GetFriend(friends, target);
|
||||
FriendInfo friend = GetFriend(friends, friendID);
|
||||
|
||||
if (friend != null) // Found it
|
||||
{
|
||||
// Store it on the DB
|
||||
if (!StoreRights(requester, target, rights))
|
||||
if (!StoreRights(requester, friendID, rights))
|
||||
{
|
||||
remoteClient.SendAlertMessage("Unable to grant rights.");
|
||||
return;
|
||||
@@ -717,17 +732,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
friend.MyFlags = rights;
|
||||
|
||||
// Always send this back to the original client
|
||||
remoteClient.SendChangeUserRights(requester, target, rights);
|
||||
remoteClient.SendChangeUserRights(requester, friendID, rights);
|
||||
|
||||
//
|
||||
// Notify the friend
|
||||
//
|
||||
|
||||
// Try local
|
||||
if (LocalGrantRights(requester, target, myFlags, rights))
|
||||
if (LocalGrantRights(requester, friendID, myFlags, rights))
|
||||
return;
|
||||
|
||||
PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { target.ToString() });
|
||||
PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() });
|
||||
if (friendSessions != null && friendSessions.Length > 0)
|
||||
{
|
||||
PresenceInfo friendSession = friendSessions[0];
|
||||
@@ -736,12 +751,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID);
|
||||
// TODO: You might want to send the delta to save the lookup
|
||||
// on the other end!!
|
||||
m_FriendsSimConnector.GrantRights(region, requester, target, myFlags, rights);
|
||||
m_FriendsSimConnector.GrantRights(region, requester, friendID, myFlags, rights);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
m_log.DebugFormat("[FRIENDS MODULE]: friend {0} not found for {1}", target, requester);
|
||||
{
|
||||
m_log.DebugFormat("[FRIENDS MODULE]: friend {0} not found for {1}", friendID, requester);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual FriendInfo GetFriend(FriendInfo[] friends, UUID friendID)
|
||||
@@ -779,6 +796,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
(byte)OpenMetaverse.InstantMessageDialog.FriendshipAccepted, userID.ToString(), false, Vector3.Zero);
|
||||
friendClient.SendInstantMessage(im);
|
||||
|
||||
ICallingCardModule ccm = friendClient.Scene.RequestModuleInterface<ICallingCardModule>();
|
||||
if (ccm != null)
|
||||
{
|
||||
ccm.CreateCallingCard(friendID, userID, UUID.Zero);
|
||||
}
|
||||
|
||||
// Update the local cache
|
||||
RecacheFriends(friendClient);
|
||||
|
||||
@@ -801,7 +824,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
// we're done
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -853,7 +876,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
|
||||
public bool LocalStatusNotification(UUID userID, UUID friendID, bool online)
|
||||
{
|
||||
// m_log.DebugFormat("[FRIENDS]: Local Status Notify {0} that user {1} is {2}", friendID, userID, online);
|
||||
//m_log.DebugFormat("[FRIENDS]: Local Status Notify {0} that user {1} is {2}", friendID, userID, online);
|
||||
IClientAPI friendClient = LocateClientObject(friendID);
|
||||
if (friendClient != null)
|
||||
{
|
||||
@@ -872,18 +895,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
#endregion
|
||||
|
||||
#region Get / Set friends in several flavours
|
||||
/// <summary>
|
||||
/// Get friends from local cache only
|
||||
/// </summary>
|
||||
/// <param name="agentID"></param>
|
||||
/// <returns></returns>
|
||||
protected FriendInfo[] GetFriends(UUID agentID)
|
||||
|
||||
public FriendInfo[] GetFriendsFromCache(UUID userID)
|
||||
{
|
||||
UserFriendData friendsData;
|
||||
|
||||
lock (m_Friends)
|
||||
{
|
||||
if (m_Friends.TryGetValue(agentID, out friendsData))
|
||||
if (m_Friends.TryGetValue(userID, out friendsData))
|
||||
return friendsData.Friends;
|
||||
}
|
||||
|
||||
@@ -901,13 +920,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
// Update local cache
|
||||
lock (m_Friends)
|
||||
{
|
||||
FriendInfo[] friends = GetFriends(friendID);
|
||||
FriendInfo[] friends = GetFriendsFromCache(friendID);
|
||||
FriendInfo finfo = GetFriend(friends, userID);
|
||||
finfo.TheirFlags = rights;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual FriendInfo[] GetFriendsFromService(IClientAPI client)
|
||||
public virtual FriendInfo[] GetFriendsFromService(IClientAPI client)
|
||||
{
|
||||
return FriendsService.GetFriends(client.AgentId);
|
||||
}
|
||||
@@ -925,6 +944,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
}
|
||||
}
|
||||
|
||||
public bool AreFriendsCached(UUID userID)
|
||||
{
|
||||
lock (m_Friends)
|
||||
return m_Friends.ContainsKey(userID);
|
||||
}
|
||||
|
||||
protected virtual bool StoreRights(UUID agentID, UUID friendID, int rights)
|
||||
{
|
||||
FriendsService.StoreFriend(agentID.ToString(), friendID.ToString(), rights);
|
||||
@@ -938,8 +963,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
|
||||
protected virtual void StoreFriendships(UUID agentID, UUID friendID)
|
||||
{
|
||||
FriendsService.StoreFriend(agentID.ToString(), friendID.ToString(), 1);
|
||||
FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), 1);
|
||||
FriendsService.StoreFriend(agentID.ToString(), friendID.ToString(), (int)FriendRights.CanSeeOnline);
|
||||
FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), (int)FriendRights.CanSeeOnline);
|
||||
}
|
||||
|
||||
protected virtual bool DeleteFriendship(UUID agentID, UUID exfriendID)
|
||||
|
||||
@@ -94,6 +94,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
|
||||
#endregion
|
||||
|
||||
protected override void OnApproveFriendRequest(IClientAPI client, UUID friendID, List<UUID> callingCardFolders)
|
||||
{
|
||||
// Update the local cache. Yes, we need to do it right here
|
||||
// because the HGFriendsService placed something on the DB
|
||||
// from under the sim
|
||||
base.OnApproveFriendRequest(client, friendID, callingCardFolders);
|
||||
}
|
||||
|
||||
protected override bool CacheFriends(IClientAPI client)
|
||||
{
|
||||
// m_log.DebugFormat("[HGFRIENDS MODULE]: Entered CacheFriends for {0}", client.Name);
|
||||
@@ -144,7 +152,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(client.Scene.RegionInfo.ScopeID, client.AgentId);
|
||||
if (account == null) // foreign
|
||||
{
|
||||
FriendInfo[] friends = GetFriends(client.AgentId);
|
||||
FriendInfo[] friends = GetFriendsFromCache(client.AgentId);
|
||||
foreach (FriendInfo f in friends)
|
||||
{
|
||||
client.SendChangeUserRights(new UUID(f.Friend), client.AgentId, f.TheirFlags);
|
||||
@@ -376,8 +384,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
protected override FriendInfo[] GetFriendsFromService(IClientAPI client)
|
||||
public override FriendInfo[] GetFriendsFromService(IClientAPI client)
|
||||
{
|
||||
// m_log.DebugFormat("[HGFRIENDS MODULE]: Entering GetFriendsFromService for {0}", client.Name);
|
||||
Boolean agentIsLocal = true;
|
||||
@@ -422,7 +429,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
|
||||
if (agentIsLocal) // agent is local, friend is foreigner
|
||||
{
|
||||
FriendInfo[] finfos = GetFriends(agentID);
|
||||
FriendInfo[] finfos = GetFriendsFromCache(agentID);
|
||||
FriendInfo finfo = GetFriend(finfos, friendID);
|
||||
if (finfo != null)
|
||||
{
|
||||
@@ -519,10 +526,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
{
|
||||
// This may happen when the agent returned home, in which case the friend is not there
|
||||
// We need to look for its information in the friends list itself
|
||||
FriendInfo[] finfos = null;
|
||||
bool confirming = false;
|
||||
if (friendUUI == string.Empty)
|
||||
{
|
||||
FriendInfo[] finfos = GetFriends(agentID);
|
||||
finfos = GetFriendsFromCache(agentID);
|
||||
|
||||
foreach (FriendInfo finfo in finfos)
|
||||
{
|
||||
if (finfo.TheirFlags == -1)
|
||||
@@ -606,7 +615,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
if (agentIsLocal) // agent is local, 'friend' is foreigner
|
||||
{
|
||||
// We need to look for its information in the friends list itself
|
||||
FriendInfo[] finfos = GetFriends(agentID);
|
||||
FriendInfo[] finfos = GetFriendsFromCache(agentID);
|
||||
FriendInfo finfo = GetFriend(finfos, exfriendID);
|
||||
if (finfo != null)
|
||||
{
|
||||
@@ -650,7 +659,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
private string GetUUI(UUID localUser, UUID foreignUser)
|
||||
{
|
||||
// Let's see if the user is here by any chance
|
||||
FriendInfo[] finfos = GetFriends(localUser);
|
||||
FriendInfo[] finfos = GetFriendsFromCache(localUser);
|
||||
if (finfos != EMPTY_FRIENDS) // friend is here, cool
|
||||
{
|
||||
FriendInfo finfo = GetFriend(finfos, foreignUser);
|
||||
|
||||
@@ -30,6 +30,7 @@ using System.Collections.Generic;
|
||||
using Nini.Config;
|
||||
using NUnit.Framework;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Data.Null;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.CoreModules.Avatar.Friends;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
@@ -44,9 +45,30 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends.Tests
|
||||
private FriendsModule m_fm;
|
||||
private TestScene m_scene;
|
||||
|
||||
[TestFixtureSetUp]
|
||||
public void FixtureInit()
|
||||
{
|
||||
// Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread.
|
||||
Util.FireAndForgetMethod = FireAndForgetMethod.RegressionTest;
|
||||
}
|
||||
|
||||
[TestFixtureTearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
// We must set this back afterwards, otherwise later tests will fail since they're expecting multiple
|
||||
// threads. Possibly, later tests should be rewritten so none of them require async stuff (which regression
|
||||
// tests really shouldn't).
|
||||
Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod;
|
||||
}
|
||||
|
||||
[SetUp]
|
||||
public void Init()
|
||||
{
|
||||
// We must clear friends data between tests since Data.Null holds it in static properties. This is necessary
|
||||
// so that different services and simulator can share the data in standalone mode. This is pretty horrible
|
||||
// effectively the statics are global variables.
|
||||
NullFriendsData.Clear();
|
||||
|
||||
IConfigSource config = new IniConfigSource();
|
||||
config.AddConfig("Modules");
|
||||
// Not strictly necessary since FriendsModule assumes it is the default (!)
|
||||
@@ -56,13 +78,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends.Tests
|
||||
config.AddConfig("FriendsService");
|
||||
config.Configs["FriendsService"].Set("StorageProvider", "OpenSim.Data.Null.dll");
|
||||
|
||||
m_scene = SceneHelpers.SetupScene();
|
||||
m_scene = new SceneHelpers().SetupScene();
|
||||
m_fm = new FriendsModule();
|
||||
SceneHelpers.SetupSceneModules(m_scene, config, m_fm);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestNoFriends()
|
||||
public void TestLoginWithNoFriends()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
@@ -75,6 +97,76 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends.Tests
|
||||
Assert.That(((TestClient)sp.ControllingClient).ReceivedOnlineNotifications.Count, Is.EqualTo(0));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestLoginWithOfflineFriends()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
UUID user1Id = TestHelpers.ParseTail(0x1);
|
||||
UUID user2Id = TestHelpers.ParseTail(0x2);
|
||||
|
||||
// UserAccountHelpers.CreateUserWithInventory(m_scene, user1Id);
|
||||
// UserAccountHelpers.CreateUserWithInventory(m_scene, user2Id);
|
||||
//
|
||||
// m_fm.AddFriendship(user1Id, user2Id);
|
||||
|
||||
ScenePresence sp1 = SceneHelpers.AddScenePresence(m_scene, user1Id);
|
||||
ScenePresence sp2 = SceneHelpers.AddScenePresence(m_scene, user2Id);
|
||||
|
||||
m_fm.AddFriendship(sp1.ControllingClient, user2Id);
|
||||
|
||||
// Not necessary for this test. CanSeeOnline is automatically granted.
|
||||
// m_fm.GrantRights(sp1.ControllingClient, user2Id, (int)FriendRights.CanSeeOnline);
|
||||
|
||||
// We must logout from the client end so that the presence service is correctly updated by the presence
|
||||
// detector. This is listening to the OnConnectionClosed event on the client.
|
||||
((TestClient)sp1.ControllingClient).Logout();
|
||||
((TestClient)sp2.ControllingClient).Logout();
|
||||
// m_scene.RemoveClient(sp1.UUID, true);
|
||||
// m_scene.RemoveClient(sp2.UUID, true);
|
||||
|
||||
ScenePresence sp1Redux = SceneHelpers.AddScenePresence(m_scene, user1Id);
|
||||
|
||||
// We don't expect to receive notifications of offline friends on login, just online.
|
||||
Assert.That(((TestClient)sp1Redux.ControllingClient).ReceivedOfflineNotifications.Count, Is.EqualTo(0));
|
||||
Assert.That(((TestClient)sp1Redux.ControllingClient).ReceivedOnlineNotifications.Count, Is.EqualTo(0));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestLoginWithOnlineFriends()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
UUID user1Id = TestHelpers.ParseTail(0x1);
|
||||
UUID user2Id = TestHelpers.ParseTail(0x2);
|
||||
|
||||
// UserAccountHelpers.CreateUserWithInventory(m_scene, user1Id);
|
||||
// UserAccountHelpers.CreateUserWithInventory(m_scene, user2Id);
|
||||
//
|
||||
// m_fm.AddFriendship(user1Id, user2Id);
|
||||
|
||||
ScenePresence sp1 = SceneHelpers.AddScenePresence(m_scene, user1Id);
|
||||
ScenePresence sp2 = SceneHelpers.AddScenePresence(m_scene, user2Id);
|
||||
|
||||
m_fm.AddFriendship(sp1.ControllingClient, user2Id);
|
||||
|
||||
// Not necessary for this test. CanSeeOnline is automatically granted.
|
||||
// m_fm.GrantRights(sp1.ControllingClient, user2Id, (int)FriendRights.CanSeeOnline);
|
||||
|
||||
// We must logout from the client end so that the presence service is correctly updated by the presence
|
||||
// detector. This is listening to the OnConnectionClosed event on the client.
|
||||
// ((TestClient)sp1.ControllingClient).Logout();
|
||||
((TestClient)sp2.ControllingClient).Logout();
|
||||
// m_scene.RemoveClient(user2Id, true);
|
||||
|
||||
ScenePresence sp2Redux = SceneHelpers.AddScenePresence(m_scene, user2Id);
|
||||
|
||||
Assert.That(((TestClient)sp2Redux.ControllingClient).ReceivedOfflineNotifications.Count, Is.EqualTo(0));
|
||||
Assert.That(((TestClient)sp2Redux.ControllingClient).ReceivedOnlineNotifications.Count, Is.EqualTo(1));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestAddFriendshipWhileOnline()
|
||||
{
|
||||
|
||||
@@ -108,7 +108,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
OnInventoryArchiveSaved += SaveInvConsoleCommandCompleted;
|
||||
|
||||
scene.AddCommand(
|
||||
this, "load iar",
|
||||
"Archiving", this, "load iar",
|
||||
"load iar [-m|--merge] <first> <last> <inventory path> <password> [<IAR path>]",
|
||||
"Load user inventory archive (IAR).",
|
||||
"-m|--merge is an option which merges the loaded IAR with existing inventory folders where possible, rather than always creating new ones"
|
||||
@@ -121,18 +121,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
HandleLoadInvConsoleCommand);
|
||||
|
||||
scene.AddCommand(
|
||||
this, "save iar",
|
||||
"Archiving", this, "save iar",
|
||||
"save iar [-h|--home=<url>] [--noassets] <first> <last> <inventory path> <password> [<IAR path>] [-c|--creators] [-v|--verbose]",
|
||||
"Save user inventory archive (IAR).",
|
||||
"<first> is the user's first name." + Environment.NewLine
|
||||
+ "<last> is the user's last name." + Environment.NewLine
|
||||
+ "<inventory path> is the path inside the user's inventory for the folder/item to be saved." + Environment.NewLine
|
||||
+ "-h|--home=<url> adds the url of the profile service to the saved user information." + Environment.NewLine
|
||||
+ "-c|--creators preserves information about foreign creators." + Environment.NewLine
|
||||
+ "-v|--verbose extra debug messages." + Environment.NewLine
|
||||
+ "--noassets stops assets being saved to the IAR."
|
||||
"<first> is the user's first name.\n"
|
||||
+ "<last> is the user's last name.\n"
|
||||
+ "<inventory path> is the path inside the user's inventory for the folder/item to be saved.\n"
|
||||
+ "<IAR path> is the filesystem path at which to save the IAR."
|
||||
+ string.Format(" If this is not given then the filename {0} in the current directory is used", DEFAULT_INV_BACKUP_FILENAME),
|
||||
+ string.Format(" If this is not given then the filename {0} in the current directory is used.\n", DEFAULT_INV_BACKUP_FILENAME)
|
||||
+ "-h|--home=<url> adds the url of the profile service to the saved user information.\n"
|
||||
+ "-c|--creators preserves information about foreign creators.\n"
|
||||
+ "-v|--verbose extra debug messages.\n"
|
||||
+ "--noassets stops assets being saved to the IAR.",
|
||||
HandleSaveInvConsoleCommand);
|
||||
|
||||
m_aScene = scene;
|
||||
@@ -349,8 +349,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
{
|
||||
try
|
||||
{
|
||||
m_log.Info("[INVENTORY ARCHIVER]: PLEASE NOTE THAT THIS FACILITY IS EXPERIMENTAL. BUG REPORTS WELCOME.");
|
||||
|
||||
Dictionary<string, object> options = new Dictionary<string, object>();
|
||||
OptionSet optionSet = new OptionSet().Add("m|merge", delegate (string v) { options["merge"] = v != null; });
|
||||
|
||||
@@ -412,7 +410,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
return;
|
||||
}
|
||||
|
||||
m_log.Info("[INVENTORY ARCHIVER]: PLEASE NOTE THAT THIS FACILITY IS EXPERIMENTAL. BUG REPORTS WELCOME.");
|
||||
if (options.ContainsKey("home"))
|
||||
m_log.WarnFormat("[INVENTORY ARCHIVER]: Please be aware that inventory archives with creator information are not compatible with OpenSim 0.7.0.2 and earlier. Do not use the -home option if you want to produce a compatible IAR");
|
||||
|
||||
|
||||
@@ -100,7 +100,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
InventoryArchiverModule archiverModule = new InventoryArchiverModule();
|
||||
Scene scene = SceneHelpers.SetupScene();
|
||||
Scene scene = new SceneHelpers().SetupScene();
|
||||
SceneHelpers.SetupSceneModules(scene, archiverModule);
|
||||
|
||||
UserAccountHelpers.CreateUserWithInventory(scene, m_uaLL1, "hampshire");
|
||||
|
||||
@@ -61,7 +61,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
SerialiserModule serialiserModule = new SerialiserModule();
|
||||
m_archiverModule = new InventoryArchiverModule();
|
||||
|
||||
m_scene = SceneHelpers.SetupScene();
|
||||
m_scene = new SceneHelpers().SetupScene();
|
||||
SceneHelpers.SetupSceneModules(m_scene, serialiserModule, m_archiverModule);
|
||||
}
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
|
||||
InventoryArchiverModule archiverModule = new InventoryArchiverModule();
|
||||
|
||||
Scene scene = SceneHelpers.SetupScene();
|
||||
Scene scene = new SceneHelpers().SetupScene();
|
||||
SceneHelpers.SetupSceneModules(scene, archiverModule);
|
||||
|
||||
// Create user
|
||||
@@ -179,7 +179,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
InventoryArchiverModule archiverModule = new InventoryArchiverModule();
|
||||
|
||||
// Annoyingly, we have to set up a scene even though inventory loading has nothing to do with a scene
|
||||
Scene scene = SceneHelpers.SetupScene();
|
||||
Scene scene = new SceneHelpers().SetupScene();
|
||||
|
||||
SceneHelpers.SetupSceneModules(scene, serialiserModule, archiverModule);
|
||||
|
||||
@@ -222,7 +222,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
|
||||
SerialiserModule serialiserModule = new SerialiserModule();
|
||||
InventoryArchiverModule archiverModule = new InventoryArchiverModule();
|
||||
Scene scene = SceneHelpers.SetupScene();
|
||||
Scene scene = new SceneHelpers().SetupScene();
|
||||
SceneHelpers.SetupSceneModules(scene, serialiserModule, archiverModule);
|
||||
|
||||
UserAccountHelpers.CreateUserWithInventory(scene, m_uaMT, "password");
|
||||
@@ -247,7 +247,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
|
||||
InventoryArchiverModule archiverModule = new InventoryArchiverModule();
|
||||
|
||||
Scene scene = SceneHelpers.SetupScene();
|
||||
Scene scene = new SceneHelpers().SetupScene();
|
||||
SceneHelpers.SetupSceneModules(scene, archiverModule);
|
||||
|
||||
// Create user
|
||||
@@ -326,7 +326,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
Scene scene = SceneHelpers.SetupScene();
|
||||
Scene scene = new SceneHelpers().SetupScene();
|
||||
UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene);
|
||||
|
||||
Dictionary <string, InventoryFolderBase> foldersCreated = new Dictionary<string, InventoryFolderBase>();
|
||||
@@ -393,7 +393,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
TestHelpers.InMethod();
|
||||
//log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
Scene scene = SceneHelpers.SetupScene();
|
||||
Scene scene = new SceneHelpers().SetupScene();
|
||||
UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene);
|
||||
|
||||
string folder1ExistingName = "a";
|
||||
@@ -444,7 +444,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
Scene scene = SceneHelpers.SetupScene();
|
||||
Scene scene = new SceneHelpers().SetupScene();
|
||||
UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene);
|
||||
|
||||
string folder1ExistingName = "a";
|
||||
|
||||
@@ -240,13 +240,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure
|
||||
{
|
||||
ScenePresence sp = scene.GetScenePresence(client.AgentId);
|
||||
IEntityTransferModule transferMod = scene.RequestModuleInterface<IEntityTransferModule>();
|
||||
IEventQueue eq = sp.Scene.RequestModuleInterface<IEventQueue>();
|
||||
if (transferMod != null && sp != null && eq != null)
|
||||
transferMod.DoTeleport(sp, gatekeeper, finalDestination, im.Position + new Vector3(0.5f, 0.5f, 0f), Vector3.UnitX, teleportflags, eq);
|
||||
|
||||
if (transferMod != null && sp != null)
|
||||
transferMod.DoTeleport(
|
||||
sp, gatekeeper, finalDestination, im.Position + new Vector3(0.5f, 0.5f, 0f),
|
||||
Vector3.UnitX, teleportflags);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -151,11 +151,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure
|
||||
Scene scene = (Scene)(client.Scene);
|
||||
ScenePresence presence = scene.GetScenePresence(client.AgentId);
|
||||
|
||||
// Round up Z co-ordinate rather than round-down by casting. This stops tall avatars from being given
|
||||
// a teleport Z co-ordinate by short avatars that drops them through or embeds them in thin floors on
|
||||
// arrival.
|
||||
//
|
||||
// Ideally we would give the exact float position adjusting for the relative height of the two avatars
|
||||
// but it looks like a float component isn't possible with a parcel ID.
|
||||
UUID dest = Util.BuildFakeParcelID(
|
||||
scene.RegionInfo.RegionHandle,
|
||||
(uint)presence.AbsolutePosition.X,
|
||||
(uint)presence.AbsolutePosition.Y,
|
||||
(uint)presence.AbsolutePosition.Z);
|
||||
(uint)Math.Ceiling(presence.AbsolutePosition.Z));
|
||||
|
||||
m_log.DebugFormat("TP invite with message {0}", message);
|
||||
|
||||
|
||||
@@ -150,7 +150,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Profile
|
||||
string skillsText = String.Empty;
|
||||
string languages = String.Empty;
|
||||
|
||||
Byte[] charterMember = Utils.StringToBytes("Avatar");
|
||||
UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, avatarID);
|
||||
|
||||
string name = "Avatar";
|
||||
int created = 0;
|
||||
if (account != null)
|
||||
{
|
||||
name = account.FirstName + " " + account.LastName;
|
||||
created = account.Created;
|
||||
}
|
||||
Byte[] charterMember = Utils.StringToBytes(name);
|
||||
|
||||
profileUrl = "No profile data";
|
||||
aboutText = string.Empty;
|
||||
@@ -160,7 +169,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Profile
|
||||
partner = UUID.Zero;
|
||||
|
||||
remoteClient.SendAvatarProperties(avatarID, aboutText,
|
||||
Util.ToDateTime(0).ToString(
|
||||
Util.ToDateTime(created).ToString(
|
||||
"M/d/yyyy", CultureInfo.InvariantCulture),
|
||||
charterMember, firstLifeAboutText,
|
||||
(uint)(0 & 0xff),
|
||||
|
||||
@@ -69,9 +69,10 @@ namespace OpenSim.Region.CoreModules.Framework
|
||||
{
|
||||
m_scene = scene;
|
||||
m_scene.RegisterModuleInterface<ICapabilitiesModule>(this);
|
||||
MainConsole.Instance.Commands.AddCommand("Capabilities", false, "show caps",
|
||||
|
||||
MainConsole.Instance.Commands.AddCommand("Comms", false, "show caps",
|
||||
"show caps",
|
||||
"Shows all registered capabilities", HandleShowCapsCommand);
|
||||
"Shows all registered capabilities for users", HandleShowCapsCommand);
|
||||
}
|
||||
|
||||
public void RegionLoaded(Scene scene)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,269 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using OpenMetaverse;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Capabilities;
|
||||
using OpenSim.Framework.Client;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Region.Physics.Manager;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using GridRegion = OpenSim.Services.Interfaces.GridRegion;
|
||||
|
||||
namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
{
|
||||
/// <summary>
|
||||
/// The possible states that an agent can be in when its being transferred between regions.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is a state machine.
|
||||
///
|
||||
/// [Entry] => Preparing
|
||||
/// Preparing => { Transferring || CleaningUp || [Exit] }
|
||||
/// Transferring => { ReceivedAtDestination || CleaningUp }
|
||||
/// ReceivedAtDestination => CleaningUp
|
||||
/// CleaningUp => [Exit]
|
||||
///
|
||||
/// In other words, agents normally travel throwing Preparing => Transferring => ReceivedAtDestination => CleaningUp
|
||||
/// However, any state can transition to CleaningUp if the teleport has failed.
|
||||
/// </remarks>
|
||||
enum AgentTransferState
|
||||
{
|
||||
Preparing, // The agent is being prepared for transfer
|
||||
Transferring, // The agent is in the process of being transferred to a destination
|
||||
ReceivedAtDestination, // The destination has notified us that the agent has been successfully received
|
||||
CleaningUp // The agent is being changed to child/removed after a transfer
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Records the state of entities when they are in transfer within or between regions (cross or teleport).
|
||||
/// </summary>
|
||||
public class EntityTransferStateMachine
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
/// <summary>
|
||||
/// If true then on a teleport, the source region waits for a callback from the destination region. If
|
||||
/// a callback fails to arrive within a set time then the user is pulled back into the source region.
|
||||
/// </summary>
|
||||
public bool EnableWaitForAgentArrivedAtDestination { get; set; }
|
||||
|
||||
private EntityTransferModule m_mod;
|
||||
|
||||
private Dictionary<UUID, AgentTransferState> m_agentsInTransit = new Dictionary<UUID, AgentTransferState>();
|
||||
|
||||
public EntityTransferStateMachine(EntityTransferModule module)
|
||||
{
|
||||
m_mod = module;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set that an agent is in transit.
|
||||
/// </summary>
|
||||
/// <param name='id'>The ID of the agent being teleported</param>
|
||||
/// <returns>true if the agent was not already in transit, false if it was</returns>
|
||||
internal bool SetInTransit(UUID id)
|
||||
{
|
||||
lock (m_agentsInTransit)
|
||||
{
|
||||
if (!m_agentsInTransit.ContainsKey(id))
|
||||
{
|
||||
m_agentsInTransit[id] = AgentTransferState.Preparing;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the state of an agent that is already in transit.
|
||||
/// </summary>
|
||||
/// <param name='id'></param>
|
||||
/// <param name='newState'></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref='Exception'>Illegal transitions will throw an Exception</exception>
|
||||
internal void UpdateInTransit(UUID id, AgentTransferState newState)
|
||||
{
|
||||
lock (m_agentsInTransit)
|
||||
{
|
||||
// Illegal to try and update an agent that's not actually in transit.
|
||||
if (!m_agentsInTransit.ContainsKey(id))
|
||||
throw new Exception(
|
||||
string.Format(
|
||||
"Agent with ID {0} is not registered as in transit in {1}",
|
||||
id, m_mod.Scene.RegionInfo.RegionName));
|
||||
|
||||
AgentTransferState oldState = m_agentsInTransit[id];
|
||||
|
||||
bool transitionOkay = false;
|
||||
|
||||
if (newState == AgentTransferState.CleaningUp && oldState != AgentTransferState.CleaningUp)
|
||||
transitionOkay = true;
|
||||
else if (newState == AgentTransferState.Transferring && oldState == AgentTransferState.Preparing)
|
||||
transitionOkay = true;
|
||||
else if (newState == AgentTransferState.ReceivedAtDestination && oldState == AgentTransferState.Transferring)
|
||||
transitionOkay = true;
|
||||
|
||||
if (transitionOkay)
|
||||
m_agentsInTransit[id] = newState;
|
||||
else
|
||||
throw new Exception(
|
||||
string.Format(
|
||||
"Agent with ID {0} is not allowed to move from old transit state {1} to new state {2} in {3}",
|
||||
id, oldState, newState, m_mod.Scene.RegionInfo.RegionName));
|
||||
}
|
||||
}
|
||||
|
||||
internal bool IsInTransit(UUID id)
|
||||
{
|
||||
lock (m_agentsInTransit)
|
||||
return m_agentsInTransit.ContainsKey(id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes an agent from the transit state machine.
|
||||
/// </summary>
|
||||
/// <param name='id'></param>
|
||||
/// <returns>true if the agent was flagged as being teleported when this method was called, false otherwise</returns>
|
||||
internal bool ResetFromTransit(UUID id)
|
||||
{
|
||||
lock (m_agentsInTransit)
|
||||
{
|
||||
if (m_agentsInTransit.ContainsKey(id))
|
||||
{
|
||||
AgentTransferState state = m_agentsInTransit[id];
|
||||
|
||||
if (state == AgentTransferState.Transferring || state == AgentTransferState.ReceivedAtDestination)
|
||||
{
|
||||
// FIXME: For now, we allow exit from any state since a thrown exception in teleport is now guranteed
|
||||
// to be handled properly - ResetFromTransit() could be invoked at any step along the process
|
||||
m_log.WarnFormat(
|
||||
"[ENTITY TRANSFER STATE MACHINE]: Agent with ID {0} should not exit directly from state {1}, should go to {2} state first in {3}",
|
||||
id, state, AgentTransferState.CleaningUp, m_mod.Scene.RegionInfo.RegionName);
|
||||
|
||||
// throw new Exception(
|
||||
// "Agent with ID {0} cannot exit directly from state {1}, it must go to {2} state first",
|
||||
// state, AgentTransferState.CleaningUp);
|
||||
}
|
||||
|
||||
m_agentsInTransit.Remove(id);
|
||||
|
||||
m_log.DebugFormat(
|
||||
"[ENTITY TRANSFER STATE MACHINE]: Agent {0} cleared from transit in {1}",
|
||||
id, m_mod.Scene.RegionInfo.RegionName);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
m_log.WarnFormat(
|
||||
"[ENTITY TRANSFER STATE MACHINE]: Agent {0} requested to clear from transit in {1} but was already cleared",
|
||||
id, m_mod.Scene.RegionInfo.RegionName);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
internal bool WaitForAgentArrivedAtDestination(UUID id)
|
||||
{
|
||||
if (!m_mod.WaitForAgentArrivedAtDestination)
|
||||
return true;
|
||||
|
||||
lock (m_agentsInTransit)
|
||||
{
|
||||
if (!IsInTransit(id))
|
||||
throw new Exception(
|
||||
string.Format(
|
||||
"Asked to wait for destination callback for agent with ID {0} in {1} but agent is not in transit",
|
||||
id, m_mod.Scene.RegionInfo.RegionName));
|
||||
|
||||
AgentTransferState currentState = m_agentsInTransit[id];
|
||||
|
||||
if (currentState != AgentTransferState.Transferring && currentState != AgentTransferState.ReceivedAtDestination)
|
||||
throw new Exception(
|
||||
string.Format(
|
||||
"Asked to wait for destination callback for agent with ID {0} in {1} but agent is in state {2}",
|
||||
id, m_mod.Scene.RegionInfo.RegionName, currentState));
|
||||
}
|
||||
|
||||
int count = 200;
|
||||
|
||||
// There should be no race condition here since no other code should be removing the agent transfer or
|
||||
// changing the state to another other than Transferring => ReceivedAtDestination.
|
||||
while (m_agentsInTransit[id] != AgentTransferState.ReceivedAtDestination && count-- > 0)
|
||||
{
|
||||
// m_log.Debug(" >>> Waiting... " + count);
|
||||
Thread.Sleep(100);
|
||||
}
|
||||
|
||||
return count > 0;
|
||||
}
|
||||
|
||||
internal void SetAgentArrivedAtDestination(UUID id)
|
||||
{
|
||||
lock (m_agentsInTransit)
|
||||
{
|
||||
if (!m_agentsInTransit.ContainsKey(id))
|
||||
{
|
||||
m_log.WarnFormat(
|
||||
"[ENTITY TRANSFER STATE MACHINE]: Region {0} received notification of arrival in destination of agent {1} but no teleport request is active",
|
||||
m_mod.Scene.RegionInfo.RegionName, id);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
AgentTransferState currentState = m_agentsInTransit[id];
|
||||
|
||||
if (currentState == AgentTransferState.ReceivedAtDestination)
|
||||
{
|
||||
// An anomoly but don't make this an outright failure - destination region could be overzealous in sending notification.
|
||||
m_log.WarnFormat(
|
||||
"[ENTITY TRANSFER STATE MACHINE]: Region {0} received notification of arrival in destination of agent {1} but notification has already previously been received",
|
||||
m_mod.Scene.RegionInfo.RegionName, id);
|
||||
}
|
||||
else if (currentState != AgentTransferState.Transferring)
|
||||
{
|
||||
m_log.ErrorFormat(
|
||||
"[ENTITY TRANSFER STATE MACHINE]: Region {0} received notification of arrival in destination of agent {1} but agent is in state {2}",
|
||||
m_mod.Scene.RegionInfo.RegionName, id, currentState);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
m_agentsInTransit[id] = AgentTransferState.ReceivedAtDestination;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -44,11 +44,12 @@ using Nini.Config;
|
||||
|
||||
namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
{
|
||||
public class HGEntityTransferModule : EntityTransferModule, ISharedRegionModule, IEntityTransferModule, IUserAgentVerificationModule
|
||||
public class HGEntityTransferModule
|
||||
: EntityTransferModule, INonSharedRegionModule, IEntityTransferModule, IUserAgentVerificationModule
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private bool m_Initialized = false;
|
||||
private int m_levelHGTeleport = 0;
|
||||
|
||||
private GatekeeperServiceConnector m_GatekeeperConnector;
|
||||
|
||||
@@ -62,12 +63,18 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
public override void Initialise(IConfigSource source)
|
||||
{
|
||||
IConfig moduleConfig = source.Configs["Modules"];
|
||||
|
||||
if (moduleConfig != null)
|
||||
{
|
||||
string name = moduleConfig.GetString("EntityTransferModule", "");
|
||||
if (name == Name)
|
||||
{
|
||||
IConfig transferConfig = source.Configs["EntityTransfer"];
|
||||
if (transferConfig != null)
|
||||
m_levelHGTeleport = transferConfig.GetInt("LevelHGTeleport", 0);
|
||||
|
||||
InitialiseCommon(source);
|
||||
|
||||
m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: {0} enabled.", Name);
|
||||
}
|
||||
}
|
||||
@@ -76,10 +83,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
public override void AddRegion(Scene scene)
|
||||
{
|
||||
base.AddRegion(scene);
|
||||
|
||||
if (m_Enabled)
|
||||
{
|
||||
scene.RegisterModuleInterface<IUserAgentVerificationModule>(this);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnNewClient(IClientAPI client)
|
||||
@@ -89,27 +95,21 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
client.OnConnectionClosed += new Action<IClientAPI>(OnConnectionClosed);
|
||||
}
|
||||
|
||||
|
||||
public override void RegionLoaded(Scene scene)
|
||||
{
|
||||
base.RegionLoaded(scene);
|
||||
if (m_Enabled)
|
||||
if (!m_Initialized)
|
||||
{
|
||||
m_GatekeeperConnector = new GatekeeperServiceConnector(scene.AssetService);
|
||||
m_Initialized = true;
|
||||
}
|
||||
|
||||
if (m_Enabled)
|
||||
m_GatekeeperConnector = new GatekeeperServiceConnector(scene.AssetService);
|
||||
}
|
||||
|
||||
public override void RemoveRegion(Scene scene)
|
||||
{
|
||||
base.AddRegion(scene);
|
||||
if (m_Enabled)
|
||||
{
|
||||
scene.UnregisterModuleInterface<IUserAgentVerificationModule>(this);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_Enabled)
|
||||
scene.UnregisterModuleInterface<IUserAgentVerificationModule>(this);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -117,8 +117,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
|
||||
protected override GridRegion GetFinalDestination(GridRegion region)
|
||||
{
|
||||
int flags = m_aScene.GridService.GetRegionFlags(m_aScene.RegionInfo.ScopeID, region.RegionID);
|
||||
int flags = Scene.GridService.GetRegionFlags(Scene.RegionInfo.ScopeID, region.RegionID);
|
||||
m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: region {0} flags: {1}", region.RegionID, flags);
|
||||
|
||||
if ((flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0)
|
||||
{
|
||||
m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Destination region {0} is hyperlink", region.RegionID);
|
||||
@@ -129,6 +130,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
m_log.WarnFormat("[HG ENTITY TRANSFER MODULE]: GetHyperlinkRegion to Gatekeeper {0} failed", region.ServerURI);
|
||||
return real_destination;
|
||||
}
|
||||
|
||||
return region;
|
||||
}
|
||||
|
||||
@@ -137,7 +139,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
if (base.NeedsClosing(drawdist, oldRegionX, newRegionX, oldRegionY, newRegionY, reg))
|
||||
return true;
|
||||
|
||||
int flags = m_aScene.GridService.GetRegionFlags(m_aScene.RegionInfo.ScopeID, reg.RegionID);
|
||||
int flags = Scene.GridService.GetRegionFlags(Scene.RegionInfo.ScopeID, reg.RegionID);
|
||||
if (flags == -1 /* no region in DB */ || (flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0)
|
||||
return true;
|
||||
|
||||
@@ -150,7 +152,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
if (logout)
|
||||
{
|
||||
// Log them out of this grid
|
||||
m_aScene.PresenceService.LogoutAgent(sp.ControllingClient.SessionId);
|
||||
Scene.PresenceService.LogoutAgent(sp.ControllingClient.SessionId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,10 +161,18 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: CreateAgent {0} {1}", reg.ServerURI, finalDestination.ServerURI);
|
||||
reason = string.Empty;
|
||||
logout = false;
|
||||
int flags = m_aScene.GridService.GetRegionFlags(m_aScene.RegionInfo.ScopeID, reg.RegionID);
|
||||
int flags = Scene.GridService.GetRegionFlags(Scene.RegionInfo.ScopeID, reg.RegionID);
|
||||
if (flags == -1 /* no region in DB */ || (flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0)
|
||||
{
|
||||
// this user is going to another grid
|
||||
// check if HyperGrid teleport is allowed, based on user level
|
||||
if (sp.UserLevel < m_levelHGTeleport)
|
||||
{
|
||||
m_log.WarnFormat("[HG ENTITY TRANSFER MODULE]: Unable to HG teleport agent due to insufficient UserLevel.");
|
||||
reason = "HyperGrid teleport not permitted";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (agentCircuit.ServiceURLs.ContainsKey("HomeURI"))
|
||||
{
|
||||
string userAgentDriver = agentCircuit.ServiceURLs["HomeURI"].ToString();
|
||||
@@ -170,6 +180,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
bool success = connector.LoginAgentToGrid(agentCircuit, reg, finalDestination, out reason);
|
||||
logout = success; // flag for later logout from this grid; this is an HG TP
|
||||
|
||||
if (success)
|
||||
sp.Scene.EventManager.TriggerTeleportStart(sp.ControllingClient, reg, finalDestination, teleportFlags, logout);
|
||||
|
||||
return success;
|
||||
}
|
||||
else
|
||||
@@ -179,15 +192,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
}
|
||||
}
|
||||
|
||||
return m_aScene.SimulationService.CreateAgent(reg, agentCircuit, teleportFlags, out reason);
|
||||
return base.CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout);
|
||||
}
|
||||
|
||||
public override void TeleportHome(UUID id, IClientAPI client)
|
||||
{
|
||||
m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Request to teleport {0} {1} home", client.FirstName, client.LastName);
|
||||
m_log.DebugFormat(
|
||||
"[ENTITY TRANSFER MODULE]: Request to teleport {0} {1} home", client.Name, client.AgentId);
|
||||
|
||||
// Let's find out if this is a foreign user or a local user
|
||||
IUserManagement uMan = m_aScene.RequestModuleInterface<IUserManagement>();
|
||||
IUserManagement uMan = Scene.RequestModuleInterface<IUserManagement>();
|
||||
if (uMan != null && uMan.IsLocalGridUser(id))
|
||||
{
|
||||
// local grid user
|
||||
@@ -224,13 +238,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
return;
|
||||
}
|
||||
|
||||
IEventQueue eq = sp.Scene.RequestModuleInterface<IEventQueue>();
|
||||
GridRegion homeGatekeeper = MakeRegion(aCircuit);
|
||||
|
||||
m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: teleporting user {0} {1} home to {2} via {3}:{4}",
|
||||
aCircuit.firstname, aCircuit.lastname, finalDestination.RegionName, homeGatekeeper.ServerURI, homeGatekeeper.RegionName);
|
||||
|
||||
DoTeleport(sp, homeGatekeeper, finalDestination, position, lookAt, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome), eq);
|
||||
DoTeleport(
|
||||
sp, homeGatekeeper, finalDestination,
|
||||
position, lookAt, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -243,19 +258,21 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
{
|
||||
m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Teleporting agent via landmark to {0} region {1} position {2}",
|
||||
(lm.Gatekeeper == string.Empty) ? "local" : lm.Gatekeeper, lm.RegionID, lm.Position);
|
||||
|
||||
if (lm.Gatekeeper == string.Empty)
|
||||
{
|
||||
base.RequestTeleportLandmark(remoteClient, lm);
|
||||
return;
|
||||
}
|
||||
|
||||
GridRegion info = m_aScene.GridService.GetRegionByUUID(UUID.Zero, lm.RegionID);
|
||||
GridRegion info = Scene.GridService.GetRegionByUUID(UUID.Zero, lm.RegionID);
|
||||
|
||||
// Local region?
|
||||
if (info != null)
|
||||
{
|
||||
((Scene)(remoteClient.Scene)).RequestTeleportLocation(remoteClient, info.RegionHandle, lm.Position,
|
||||
Vector3.Zero, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaLandmark));
|
||||
|
||||
return;
|
||||
}
|
||||
else
|
||||
@@ -266,21 +283,22 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
GridRegion gatekeeper = new GridRegion();
|
||||
gatekeeper.ServerURI = lm.Gatekeeper;
|
||||
GridRegion finalDestination = gConn.GetHyperlinkRegion(gatekeeper, new UUID(lm.RegionID));
|
||||
|
||||
if (finalDestination != null)
|
||||
{
|
||||
ScenePresence sp = scene.GetScenePresence(remoteClient.AgentId);
|
||||
IEntityTransferModule transferMod = scene.RequestModuleInterface<IEntityTransferModule>();
|
||||
IEventQueue eq = sp.Scene.RequestModuleInterface<IEventQueue>();
|
||||
if (transferMod != null && sp != null && eq != null)
|
||||
transferMod.DoTeleport(sp, gatekeeper, finalDestination, lm.Position,
|
||||
Vector3.UnitX, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaLandmark), eq);
|
||||
|
||||
if (transferMod != null && sp != null)
|
||||
transferMod.DoTeleport(
|
||||
sp, gatekeeper, finalDestination, lm.Position, Vector3.UnitX,
|
||||
(uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaLandmark));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// can't find the region: Tell viewer and abort
|
||||
remoteClient.SendTeleportFailed("The teleport destination could not be found.");
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -295,8 +313,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
IUserAgentService security = new UserAgentServiceConnector(url);
|
||||
return security.VerifyClient(aCircuit.SessionID, token);
|
||||
}
|
||||
else
|
||||
m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Agent {0} {1} does not have a HomeURI OH NO!", aCircuit.firstname, aCircuit.lastname);
|
||||
else
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"[HG ENTITY TRANSFER MODULE]: Agent {0} {1} does not have a HomeURI OH NO!",
|
||||
aCircuit.firstname, aCircuit.lastname);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -313,8 +335,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
}
|
||||
|
||||
// Let's find out if this is a foreign user or a local user
|
||||
IUserManagement uMan = m_aScene.RequestModuleInterface<IUserManagement>();
|
||||
UserAccount account = m_aScene.UserAccountService.GetUserAccount(m_aScene.RegionInfo.ScopeID, obj.AgentId);
|
||||
IUserManagement uMan = Scene.RequestModuleInterface<IUserManagement>();
|
||||
// UserAccount account = Scene.UserAccountService.GetUserAccount(Scene.RegionInfo.ScopeID, obj.AgentId);
|
||||
|
||||
if (uMan != null && uMan.IsLocalGridUser(obj.AgentId))
|
||||
{
|
||||
// local grid user
|
||||
|
||||
@@ -30,6 +30,7 @@ using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Client;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Services.Connectors.Hypergrid;
|
||||
@@ -57,6 +58,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
private string m_HomeURI;
|
||||
private bool m_OutboundPermission;
|
||||
private string m_ThisGatekeeper;
|
||||
private bool m_RestrictInventoryAccessAbroad;
|
||||
|
||||
// private bool m_Initialized = false;
|
||||
|
||||
@@ -90,6 +92,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
m_HomeURI = thisModuleConfig.GetString("HomeURI", m_HomeURI);
|
||||
m_OutboundPermission = thisModuleConfig.GetBoolean("OutboundPermission", true);
|
||||
m_ThisGatekeeper = thisModuleConfig.GetString("Gatekeeper", string.Empty);
|
||||
m_RestrictInventoryAccessAbroad = thisModuleConfig.GetBoolean("RestrictInventoryAccessAbroad", false);
|
||||
}
|
||||
else
|
||||
m_log.Warn("[HG INVENTORY ACCESS MODULE]: HGInventoryAccessModule configs not found. ProfileServerURI not set!");
|
||||
@@ -105,19 +108,85 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
base.AddRegion(scene);
|
||||
m_assMapper = new HGAssetMapper(scene, m_HomeURI);
|
||||
scene.EventManager.OnNewInventoryItemUploadComplete += UploadInventoryItem;
|
||||
|
||||
scene.EventManager.OnTeleportStart += TeleportStart;
|
||||
scene.EventManager.OnTeleportFail += TeleportFail;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Event handlers
|
||||
|
||||
protected override void OnNewClient(IClientAPI client)
|
||||
{
|
||||
base.OnNewClient(client);
|
||||
client.OnCompleteMovementToRegion += new Action<IClientAPI, bool>(OnCompleteMovementToRegion);
|
||||
}
|
||||
|
||||
protected void OnCompleteMovementToRegion(IClientAPI client, bool arg2)
|
||||
{
|
||||
//m_log.DebugFormat("[HG INVENTORY ACCESS MODULE]: OnCompleteMovementToRegion of user {0}", client.Name);
|
||||
object sp = null;
|
||||
if (client.Scene.TryGetScenePresence(client.AgentId, out sp))
|
||||
{
|
||||
if (sp is ScenePresence)
|
||||
{
|
||||
AgentCircuitData aCircuit = ((ScenePresence)sp).Scene.AuthenticateHandler.GetAgentCircuitData(client.AgentId);
|
||||
if ((aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0)
|
||||
{
|
||||
if (m_RestrictInventoryAccessAbroad)
|
||||
{
|
||||
IUserManagement uMan = m_Scene.RequestModuleInterface<IUserManagement>();
|
||||
if (uMan.IsLocalGridUser(client.AgentId))
|
||||
ProcessInventoryForComingHome(client);
|
||||
else
|
||||
ProcessInventoryForArriving(client);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void TeleportStart(IClientAPI client, GridRegion destination, GridRegion finalDestination, uint teleportFlags, bool gridLogout)
|
||||
{
|
||||
if (gridLogout && m_RestrictInventoryAccessAbroad)
|
||||
{
|
||||
IUserManagement uMan = m_Scene.RequestModuleInterface<IUserManagement>();
|
||||
if (uMan != null && uMan.IsLocalGridUser(client.AgentId))
|
||||
{
|
||||
// local grid user
|
||||
ProcessInventoryForHypergriding(client);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Foreigner
|
||||
ProcessInventoryForLeaving(client);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected void TeleportFail(IClientAPI client, bool gridLogout)
|
||||
{
|
||||
if (gridLogout && m_RestrictInventoryAccessAbroad)
|
||||
{
|
||||
IUserManagement uMan = m_Scene.RequestModuleInterface<IUserManagement>();
|
||||
if (uMan.IsLocalGridUser(client.AgentId))
|
||||
{
|
||||
ProcessInventoryForComingHome(client);
|
||||
}
|
||||
else
|
||||
{
|
||||
ProcessInventoryForArriving(client);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void UploadInventoryItem(UUID avatarID, UUID assetID, string name, int userlevel)
|
||||
{
|
||||
string userAssetServer = string.Empty;
|
||||
if (IsForeignUser(avatarID, out userAssetServer) && userAssetServer != string.Empty && m_OutboundPermission)
|
||||
{
|
||||
Util.FireAndForget(delegate { m_assMapper.Post(assetID, avatarID, userAssetServer); });
|
||||
m_assMapper.Post(assetID, avatarID, userAssetServer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -236,8 +305,6 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
protected override InventoryItemBase GetItem(UUID agentID, UUID itemID)
|
||||
{
|
||||
InventoryItemBase item = base.GetItem(agentID, itemID);
|
||||
@@ -248,5 +315,84 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Inventory manipulation upon arriving/leaving
|
||||
|
||||
//
|
||||
// These 2 are for local and foreign users coming back, respectively
|
||||
//
|
||||
|
||||
private void ProcessInventoryForComingHome(IClientAPI client)
|
||||
{
|
||||
m_log.DebugFormat("[HG INVENTORY ACCESS MODULE]: Restoring root folder for local user {0}", client.Name);
|
||||
if (client is IClientCore)
|
||||
{
|
||||
IClientCore core = (IClientCore)client;
|
||||
IClientInventory inv;
|
||||
|
||||
if (core.TryGet<IClientInventory>(out inv))
|
||||
{
|
||||
InventoryFolderBase root = m_Scene.InventoryService.GetRootFolder(client.AgentId);
|
||||
InventoryCollection content = m_Scene.InventoryService.GetFolderContent(client.AgentId, root.ID);
|
||||
|
||||
inv.SendBulkUpdateInventory(content.Folders.ToArray(), content.Items.ToArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessInventoryForArriving(IClientAPI client)
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// These 2 are for local and foreign users going away respectively
|
||||
//
|
||||
|
||||
private void ProcessInventoryForHypergriding(IClientAPI client)
|
||||
{
|
||||
if (client is IClientCore)
|
||||
{
|
||||
IClientCore core = (IClientCore)client;
|
||||
IClientInventory inv;
|
||||
|
||||
if (core.TryGet<IClientInventory>(out inv))
|
||||
{
|
||||
InventoryFolderBase root = m_Scene.InventoryService.GetRootFolder(client.AgentId);
|
||||
if (root != null)
|
||||
{
|
||||
m_log.DebugFormat("[HG INVENTORY ACCESS MODULE]: Changing root inventory for user {0}", client.Name);
|
||||
InventoryCollection content = m_Scene.InventoryService.GetFolderContent(client.AgentId, root.ID);
|
||||
List<UUID> fids = new List<UUID>();
|
||||
List<UUID> iids = new List<UUID>();
|
||||
List<InventoryFolderBase> keep = new List<InventoryFolderBase>();
|
||||
|
||||
foreach (InventoryFolderBase f in content.Folders)
|
||||
{
|
||||
if (f.Name != "My Suitcase")
|
||||
{
|
||||
f.Name = f.Name + " (Unavailable)";
|
||||
keep.Add(f);
|
||||
}
|
||||
}
|
||||
|
||||
// items directly under the root folder
|
||||
foreach (InventoryItemBase it in content.Items)
|
||||
it.Name = it.Name + " (Unavailable)"; ;
|
||||
|
||||
// Send the new names
|
||||
inv.SendBulkUpdateInventory(keep.ToArray(), content.Items.ToArray());
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessInventoryForLeaving(IClientAPI client)
|
||||
{
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -175,7 +175,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
sbyte assetType,
|
||||
byte wearableType, uint nextOwnerMask, int creationDate)
|
||||
{
|
||||
m_log.DebugFormat("[AGENT INVENTORY]: Received request to create inventory item {0} in folder {1}", name, folderID);
|
||||
m_log.DebugFormat("[INVENTORY ACCESS MODULE]: Received request to create inventory item {0} in folder {1}", name, folderID);
|
||||
|
||||
if (!m_Scene.Permissions.CanCreateUserInventory(invType, remoteClient.AgentId))
|
||||
return;
|
||||
@@ -210,7 +210,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
else
|
||||
{
|
||||
m_log.ErrorFormat(
|
||||
"ScenePresence for agent uuid {0} unexpectedly not found in CreateNewInventoryItem",
|
||||
"[INVENTORY ACCESS MODULE]: ScenePresence for agent uuid {0} unexpectedly not found in CreateNewInventoryItem",
|
||||
remoteClient.AgentId);
|
||||
}
|
||||
}
|
||||
@@ -288,16 +288,19 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
else
|
||||
{
|
||||
m_log.ErrorFormat(
|
||||
"[AGENT INVENTORY]: Could not find item {0} for caps inventory update",
|
||||
"[INVENTORY ACCESS MODULE]: Could not find item {0} for caps inventory update",
|
||||
itemID);
|
||||
}
|
||||
|
||||
return UUID.Zero;
|
||||
}
|
||||
|
||||
public virtual UUID CopyToInventory(DeRezAction action, UUID folderID,
|
||||
List<SceneObjectGroup> objectGroups, IClientAPI remoteClient)
|
||||
public virtual List<InventoryItemBase> CopyToInventory(
|
||||
DeRezAction action, UUID folderID,
|
||||
List<SceneObjectGroup> objectGroups, IClientAPI remoteClient, bool asAttachment)
|
||||
{
|
||||
List<InventoryItemBase> copiedItems = new List<InventoryItemBase>();
|
||||
|
||||
Dictionary<UUID, List<SceneObjectGroup>> bundlesToCopy = new Dictionary<UUID, List<SceneObjectGroup>>();
|
||||
|
||||
if (CoalesceMultipleObjectsToInventory)
|
||||
@@ -324,16 +327,16 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
}
|
||||
}
|
||||
|
||||
// This is method scoped and will be returned. It will be the
|
||||
// last created asset id
|
||||
UUID assetID = UUID.Zero;
|
||||
// m_log.DebugFormat(
|
||||
// "[INVENTORY ACCESS MODULE]: Copying {0} object bundles to folder {1} action {2} for {3}",
|
||||
// bundlesToCopy.Count, folderID, action, remoteClient.Name);
|
||||
|
||||
// Each iteration is really a separate asset being created,
|
||||
// with distinct destinations as well.
|
||||
foreach (List<SceneObjectGroup> bundle in bundlesToCopy.Values)
|
||||
assetID = CopyBundleToInventory(action, folderID, bundle, remoteClient);
|
||||
copiedItems.Add(CopyBundleToInventory(action, folderID, bundle, remoteClient, asAttachment));
|
||||
|
||||
return assetID;
|
||||
return copiedItems;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -344,12 +347,13 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
/// <param name="folderID"></param>
|
||||
/// <param name="objlist"></param>
|
||||
/// <param name="remoteClient"></param>
|
||||
/// <returns></returns>
|
||||
protected UUID CopyBundleToInventory(
|
||||
DeRezAction action, UUID folderID, List<SceneObjectGroup> objlist, IClientAPI remoteClient)
|
||||
/// <param name="asAttachment">Should be true if the bundle is being copied as an attachment. This prevents
|
||||
/// attempted serialization of any script state which would abort any operating scripts.</param>
|
||||
/// <returns>The inventory item created by the copy</returns>
|
||||
protected InventoryItemBase CopyBundleToInventory(
|
||||
DeRezAction action, UUID folderID, List<SceneObjectGroup> objlist, IClientAPI remoteClient,
|
||||
bool asAttachment)
|
||||
{
|
||||
UUID assetID = UUID.Zero;
|
||||
|
||||
CoalescedSceneObjects coa = new CoalescedSceneObjects(UUID.Zero);
|
||||
Dictionary<UUID, Vector3> originalPositions = new Dictionary<UUID, Vector3>();
|
||||
|
||||
@@ -385,18 +389,27 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
|
||||
string itemXml;
|
||||
|
||||
// If we're being called from a script, then trying to serialize that same script's state will not complete
|
||||
// in any reasonable time period. Therefore, we'll avoid it. The worst that can happen is that if
|
||||
// the client/server crashes rather than logging out normally, the attachment's scripts will resume
|
||||
// without state on relog. Arguably, this is what we want anyway.
|
||||
if (objlist.Count > 1)
|
||||
itemXml = CoalescedSceneObjectsSerializer.ToXml(coa);
|
||||
itemXml = CoalescedSceneObjectsSerializer.ToXml(coa, !asAttachment);
|
||||
else
|
||||
itemXml = SceneObjectSerializer.ToOriginalXmlFormat(objlist[0]);
|
||||
itemXml = SceneObjectSerializer.ToOriginalXmlFormat(objlist[0], !asAttachment);
|
||||
|
||||
// Restore the position of each group now that it has been stored to inventory.
|
||||
foreach (SceneObjectGroup objectGroup in objlist)
|
||||
objectGroup.AbsolutePosition = originalPositions[objectGroup.UUID];
|
||||
|
||||
InventoryItemBase item = CreateItemForObject(action, remoteClient, objlist[0], folderID);
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[INVENTORY ACCESS MODULE]: Created item is {0}",
|
||||
// item != null ? item.ID.ToString() : "NULL");
|
||||
|
||||
if (item == null)
|
||||
return UUID.Zero;
|
||||
return null;
|
||||
|
||||
// Can't know creator is the same, so null it in inventory
|
||||
if (objlist.Count > 1)
|
||||
@@ -406,7 +419,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
}
|
||||
else
|
||||
{
|
||||
item.CreatorId = objlist[0].RootPart.CreatorID.ToString();
|
||||
item.CreatorId = objlist[0].RootPart.CreatorID.ToString();
|
||||
item.CreatorData = objlist[0].RootPart.CreatorData;
|
||||
item.SaleType = objlist[0].RootPart.ObjectSaleType;
|
||||
item.SalePrice = objlist[0].RootPart.SalePrice;
|
||||
}
|
||||
@@ -419,8 +433,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
objlist[0].OwnerID.ToString());
|
||||
m_Scene.AssetService.Store(asset);
|
||||
|
||||
item.AssetID = asset.FullID;
|
||||
assetID = asset.FullID;
|
||||
item.AssetID = asset.FullID;
|
||||
|
||||
if (DeRezAction.SaveToExistingUserInventoryItem == action)
|
||||
{
|
||||
@@ -453,9 +466,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
|
||||
// This is a hook to do some per-asset post-processing for subclasses that need that
|
||||
if (remoteClient != null)
|
||||
ExportAsset(remoteClient.AgentId, assetID);
|
||||
ExportAsset(remoteClient.AgentId, asset.FullID);
|
||||
|
||||
return assetID;
|
||||
return item;
|
||||
}
|
||||
|
||||
protected virtual void ExportAsset(UUID agentID, UUID assetID)
|
||||
@@ -551,9 +564,14 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
// "[INVENTORY ACCESS MODULE]: Target of {0} in CreateItemForObject() is {1} {2}",
|
||||
// action, remoteClient.Name, userID);
|
||||
}
|
||||
else if (so.RootPart.OwnerID == so.RootPart.GroupID)
|
||||
{
|
||||
// Group owned objects go to the last owner before the object was transferred.
|
||||
userID = so.RootPart.LastOwnerID;
|
||||
}
|
||||
else
|
||||
{
|
||||
// All returns / deletes go to the object owner
|
||||
// Other returns / deletes go to the object owner
|
||||
//
|
||||
userID = so.RootPart.OwnerID;
|
||||
|
||||
@@ -587,7 +605,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
if (null == item)
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"[AGENT INVENTORY]: Object {0} {1} scheduled for save to inventory has already been deleted.",
|
||||
"[INVENTORY ACCESS MODULE]: Object {0} {1} scheduled for save to inventory has already been deleted.",
|
||||
so.Name, so.UUID);
|
||||
|
||||
return null;
|
||||
@@ -638,7 +656,6 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
{
|
||||
// Catch all. Use lost & found
|
||||
//
|
||||
|
||||
folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder);
|
||||
}
|
||||
}
|
||||
@@ -649,9 +666,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
//
|
||||
if (action == DeRezAction.Take || action == DeRezAction.TakeCopy)
|
||||
{
|
||||
if (so.RootPart.FromFolderID != UUID.Zero && userID == remoteClient.AgentId)
|
||||
if (so.FromFolderID != UUID.Zero && userID == remoteClient.AgentId)
|
||||
{
|
||||
InventoryFolderBase f = new InventoryFolderBase(so.RootPart.FromFolderID, userID);
|
||||
InventoryFolderBase f = new InventoryFolderBase(so.FromFolderID, userID);
|
||||
folder = m_Scene.InventoryService.GetFolder(f);
|
||||
}
|
||||
}
|
||||
@@ -689,7 +706,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
if (item == null)
|
||||
{
|
||||
m_log.WarnFormat(
|
||||
"[InventoryAccessModule]: Could not find item {0} for {1} in RezObject()",
|
||||
"[INVENTORY ACCESS MODULE]: Could not find item {0} for {1} in RezObject()",
|
||||
itemID, remoteClient.Name);
|
||||
|
||||
return null;
|
||||
@@ -721,7 +738,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
else
|
||||
{
|
||||
m_log.WarnFormat(
|
||||
"[InventoryAccessModule]: Could not find asset {0} for {1} in RezObject()",
|
||||
"[INVENTORY ACCESS MODULE]: Could not find asset {0} for {1} in RezObject()",
|
||||
assetID, remoteClient.Name);
|
||||
}
|
||||
|
||||
@@ -798,7 +815,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
group = objlist[i];
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[InventoryAccessModule]: Preparing to rez {0} {1} {2} ownermask={3:X} nextownermask={4:X} groupmask={5:X} everyonemask={6:X} for {7}",
|
||||
// "[INVENTORY ACCESS MODULE]: Preparing to rez {0} {1} {2} ownermask={3:X} nextownermask={4:X} groupmask={5:X} everyonemask={6:X} for {7}",
|
||||
// group.Name, group.LocalId, group.UUID,
|
||||
// group.RootPart.OwnerMask, group.RootPart.NextOwnerMask, group.RootPart.GroupMask, group.RootPart.EveryoneMask,
|
||||
// remoteClient.Name);
|
||||
@@ -806,7 +823,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
// Vector3 storedPosition = group.AbsolutePosition;
|
||||
if (group.UUID == UUID.Zero)
|
||||
{
|
||||
m_log.Debug("[InventoryAccessModule]: Object has UUID.Zero! Position 3");
|
||||
m_log.Debug("[INVENTORY ACCESS MODULE]: Object has UUID.Zero! Position 3");
|
||||
}
|
||||
|
||||
foreach (SceneObjectPart part in group.Parts)
|
||||
@@ -869,7 +886,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
}
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[InventoryAccessModule]: Rezzed {0} {1} {2} ownermask={3:X} nextownermask={4:X} groupmask={5:X} everyonemask={6:X} for {7}",
|
||||
// "[INVENTORY ACCESS MODULE]: Rezzed {0} {1} {2} ownermask={3:X} nextownermask={4:X} groupmask={5:X} everyonemask={6:X} for {7}",
|
||||
// group.Name, group.LocalId, group.UUID,
|
||||
// group.RootPart.OwnerMask, group.RootPart.NextOwnerMask, group.RootPart.GroupMask, group.RootPart.EveryoneMask,
|
||||
// remoteClient.Name);
|
||||
@@ -952,10 +969,11 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
rootPart.SalePrice = item.SalePrice;
|
||||
}
|
||||
|
||||
rootPart.FromFolderID = item.Folder;
|
||||
so.FromFolderID = item.Folder;
|
||||
|
||||
// Console.WriteLine("rootPart.OwnedID {0}, item.Owner {1}, item.CurrentPermissions {2:X}",
|
||||
// rootPart.OwnerID, item.Owner, item.CurrentPermissions);
|
||||
// m_log.DebugFormat(
|
||||
// "[INVENTORY ACCESS MODULE]: rootPart.OwnedID {0}, item.Owner {1}, item.CurrentPermissions {2:X}",
|
||||
// rootPart.OwnerID, item.Owner, item.CurrentPermissions);
|
||||
|
||||
if ((rootPart.OwnerID != item.Owner) ||
|
||||
(item.CurrentPermissions & 16) != 0)
|
||||
@@ -998,7 +1016,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
rootPart.TrimPermissions();
|
||||
|
||||
if (isAttachment)
|
||||
so.SetFromItemID(item.ID);
|
||||
so.FromItemID = item.ID;
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -1078,7 +1096,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
if (assetRequestItem.AssetID != requestID)
|
||||
{
|
||||
m_log.WarnFormat(
|
||||
"[CLIENT]: {0} requested asset {1} from item {2} but this does not match item's asset {3}",
|
||||
"[INVENTORY ACCESS MODULE]: {0} requested asset {1} from item {2} but this does not match item's asset {3}",
|
||||
Name, requestID, itemID, assetRequestItem.AssetID);
|
||||
|
||||
return false;
|
||||
|
||||
@@ -64,8 +64,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests
|
||||
IConfigSource config = new IniConfigSource();
|
||||
config.AddConfig("Modules");
|
||||
config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule");
|
||||
|
||||
m_scene = SceneHelpers.SetupScene();
|
||||
|
||||
SceneHelpers sceneHelpers = new SceneHelpers();
|
||||
m_scene = sceneHelpers.SetupScene();
|
||||
SceneHelpers.SetupSceneModules(m_scene, config, m_iam);
|
||||
|
||||
// Create user
|
||||
@@ -76,7 +77,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests
|
||||
|
||||
AgentCircuitData acd = new AgentCircuitData();
|
||||
acd.AgentID = m_userId;
|
||||
m_tc = new TestClient(acd, m_scene);
|
||||
m_tc = new TestClient(acd, m_scene);
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -49,7 +49,16 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
|
||||
public bool Enabled { get; private set; }
|
||||
|
||||
private Scene m_scene;
|
||||
private readonly List<IMonitor> m_monitors = new List<IMonitor>();
|
||||
|
||||
/// <summary>
|
||||
/// These are monitors where we know the static details in advance.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Dynamic monitors also exist (we don't know any of the details of what stats we get back here)
|
||||
/// but these are currently hardcoded.
|
||||
/// </remarks>
|
||||
private readonly List<IMonitor> m_staticMonitors = new List<IMonitor>();
|
||||
|
||||
private readonly List<IAlert> m_alerts = new List<IAlert>();
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
@@ -72,7 +81,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
|
||||
|
||||
m_scene = scene;
|
||||
|
||||
m_scene.AddCommand(this, "monitor report",
|
||||
m_scene.AddCommand("General", this, "monitor report",
|
||||
"monitor report",
|
||||
"Returns a variety of statistics about the current region and/or simulator",
|
||||
DebugMonitors);
|
||||
@@ -84,9 +93,18 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
|
||||
|
||||
public void DebugMonitors(string module, string[] args)
|
||||
{
|
||||
foreach (IMonitor monitor in m_monitors)
|
||||
foreach (IMonitor monitor in m_staticMonitors)
|
||||
{
|
||||
m_log.Info("[MonitorModule]: " + m_scene.RegionInfo.RegionName + " reports " + monitor.GetFriendlyName() + " = " + monitor.GetFriendlyValue());
|
||||
m_log.InfoFormat(
|
||||
"[MONITOR MODULE]: {0} reports {1} = {2}",
|
||||
m_scene.RegionInfo.RegionName, monitor.GetFriendlyName(), monitor.GetFriendlyValue());
|
||||
}
|
||||
|
||||
foreach (KeyValuePair<string, float> tuple in m_scene.StatsReporter.GetExtraSimStats())
|
||||
{
|
||||
m_log.InfoFormat(
|
||||
"[MONITOR MODULE]: {0} reports {1} = {2}",
|
||||
m_scene.RegionInfo.RegionName, tuple.Key, tuple.Value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,11 +124,12 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
|
||||
{
|
||||
string monID = (string) request["monitor"];
|
||||
|
||||
foreach (IMonitor monitor in m_monitors)
|
||||
foreach (IMonitor monitor in m_staticMonitors)
|
||||
{
|
||||
string elemName = monitor.ToString();
|
||||
if (elemName.StartsWith(monitor.GetType().Namespace))
|
||||
elemName = elemName.Substring(monitor.GetType().Namespace.Length + 1);
|
||||
|
||||
if (elemName == monID || monitor.ToString() == monID)
|
||||
{
|
||||
Hashtable ereply3 = new Hashtable();
|
||||
@@ -123,6 +142,9 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: Arguably this should also be done with dynamic monitors but I'm not sure what the above code
|
||||
// is even doing. Why are we inspecting the type of the monitor???
|
||||
|
||||
// No monitor with that name
|
||||
Hashtable ereply2 = new Hashtable();
|
||||
|
||||
@@ -134,12 +156,18 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
|
||||
}
|
||||
|
||||
string xml = "<data>";
|
||||
foreach (IMonitor monitor in m_monitors)
|
||||
foreach (IMonitor monitor in m_staticMonitors)
|
||||
{
|
||||
string elemName = monitor.GetName();
|
||||
xml += "<" + elemName + ">" + monitor.GetValue().ToString() + "</" + elemName + ">";
|
||||
// m_log.DebugFormat("[MONITOR MODULE]: {0} = {1}", elemName, monitor.GetValue());
|
||||
}
|
||||
|
||||
foreach (KeyValuePair<string, float> tuple in m_scene.StatsReporter.GetExtraSimStats())
|
||||
{
|
||||
xml += "<" + tuple.Key + ">" + tuple.Value + "</" + tuple.Key + ">";
|
||||
}
|
||||
|
||||
xml += "</data>";
|
||||
|
||||
Hashtable ereply = new Hashtable();
|
||||
@@ -156,20 +184,20 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
|
||||
if (!Enabled)
|
||||
return;
|
||||
|
||||
m_monitors.Add(new AgentCountMonitor(m_scene));
|
||||
m_monitors.Add(new ChildAgentCountMonitor(m_scene));
|
||||
m_monitors.Add(new GCMemoryMonitor());
|
||||
m_monitors.Add(new ObjectCountMonitor(m_scene));
|
||||
m_monitors.Add(new PhysicsFrameMonitor(m_scene));
|
||||
m_monitors.Add(new PhysicsUpdateFrameMonitor(m_scene));
|
||||
m_monitors.Add(new PWSMemoryMonitor());
|
||||
m_monitors.Add(new ThreadCountMonitor());
|
||||
m_monitors.Add(new TotalFrameMonitor(m_scene));
|
||||
m_monitors.Add(new EventFrameMonitor(m_scene));
|
||||
m_monitors.Add(new LandFrameMonitor(m_scene));
|
||||
m_monitors.Add(new LastFrameTimeMonitor(m_scene));
|
||||
m_staticMonitors.Add(new AgentCountMonitor(m_scene));
|
||||
m_staticMonitors.Add(new ChildAgentCountMonitor(m_scene));
|
||||
m_staticMonitors.Add(new GCMemoryMonitor());
|
||||
m_staticMonitors.Add(new ObjectCountMonitor(m_scene));
|
||||
m_staticMonitors.Add(new PhysicsFrameMonitor(m_scene));
|
||||
m_staticMonitors.Add(new PhysicsUpdateFrameMonitor(m_scene));
|
||||
m_staticMonitors.Add(new PWSMemoryMonitor());
|
||||
m_staticMonitors.Add(new ThreadCountMonitor());
|
||||
m_staticMonitors.Add(new TotalFrameMonitor(m_scene));
|
||||
m_staticMonitors.Add(new EventFrameMonitor(m_scene));
|
||||
m_staticMonitors.Add(new LandFrameMonitor(m_scene));
|
||||
m_staticMonitors.Add(new LastFrameTimeMonitor(m_scene));
|
||||
|
||||
m_monitors.Add(
|
||||
m_staticMonitors.Add(
|
||||
new GenericMonitor(
|
||||
m_scene,
|
||||
"TimeDilationMonitor",
|
||||
@@ -177,7 +205,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
|
||||
m => m.Scene.StatsReporter.LastReportedSimStats[0],
|
||||
m => m.GetValue().ToString()));
|
||||
|
||||
m_monitors.Add(
|
||||
m_staticMonitors.Add(
|
||||
new GenericMonitor(
|
||||
m_scene,
|
||||
"SimFPSMonitor",
|
||||
@@ -185,7 +213,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
|
||||
m => m.Scene.StatsReporter.LastReportedSimStats[1],
|
||||
m => string.Format("{0}", m.GetValue())));
|
||||
|
||||
m_monitors.Add(
|
||||
m_staticMonitors.Add(
|
||||
new GenericMonitor(
|
||||
m_scene,
|
||||
"PhysicsFPSMonitor",
|
||||
@@ -193,7 +221,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
|
||||
m => m.Scene.StatsReporter.LastReportedSimStats[2],
|
||||
m => string.Format("{0}", m.GetValue())));
|
||||
|
||||
m_monitors.Add(
|
||||
m_staticMonitors.Add(
|
||||
new GenericMonitor(
|
||||
m_scene,
|
||||
"AgentUpdatesPerSecondMonitor",
|
||||
@@ -201,15 +229,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
|
||||
m => m.Scene.StatsReporter.LastReportedSimStats[3],
|
||||
m => string.Format("{0} per second", m.GetValue())));
|
||||
|
||||
m_monitors.Add(
|
||||
new GenericMonitor(
|
||||
m_scene,
|
||||
"ObjectUpdatesPerSecondMonitor",
|
||||
"Object Updates",
|
||||
m => m.Scene.StatsReporter.LastReportedObjectUpdates,
|
||||
m => string.Format("{0} per second", m.GetValue())));
|
||||
|
||||
m_monitors.Add(
|
||||
m_staticMonitors.Add(
|
||||
new GenericMonitor(
|
||||
m_scene,
|
||||
"ActiveObjectCountMonitor",
|
||||
@@ -217,7 +237,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
|
||||
m => m.Scene.StatsReporter.LastReportedSimStats[7],
|
||||
m => string.Format("{0}", m.GetValue())));
|
||||
|
||||
m_monitors.Add(
|
||||
m_staticMonitors.Add(
|
||||
new GenericMonitor(
|
||||
m_scene,
|
||||
"ActiveScriptsMonitor",
|
||||
@@ -225,7 +245,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
|
||||
m => m.Scene.StatsReporter.LastReportedSimStats[19],
|
||||
m => string.Format("{0}", m.GetValue())));
|
||||
|
||||
m_monitors.Add(
|
||||
m_staticMonitors.Add(
|
||||
new GenericMonitor(
|
||||
m_scene,
|
||||
"ScriptEventsPerSecondMonitor",
|
||||
@@ -233,7 +253,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
|
||||
m => m.Scene.StatsReporter.LastReportedSimStats[20],
|
||||
m => string.Format("{0} per second", m.GetValue())));
|
||||
|
||||
m_monitors.Add(
|
||||
m_staticMonitors.Add(
|
||||
new GenericMonitor(
|
||||
m_scene,
|
||||
"InPacketsPerSecondMonitor",
|
||||
@@ -241,7 +261,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
|
||||
m => m.Scene.StatsReporter.LastReportedSimStats[13],
|
||||
m => string.Format("{0} per second", m.GetValue())));
|
||||
|
||||
m_monitors.Add(
|
||||
m_staticMonitors.Add(
|
||||
new GenericMonitor(
|
||||
m_scene,
|
||||
"OutPacketsPerSecondMonitor",
|
||||
@@ -249,7 +269,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
|
||||
m => m.Scene.StatsReporter.LastReportedSimStats[14],
|
||||
m => string.Format("{0} per second", m.GetValue())));
|
||||
|
||||
m_monitors.Add(
|
||||
m_staticMonitors.Add(
|
||||
new GenericMonitor(
|
||||
m_scene,
|
||||
"UnackedBytesMonitor",
|
||||
@@ -257,7 +277,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
|
||||
m => m.Scene.StatsReporter.LastReportedSimStats[15],
|
||||
m => string.Format("{0}", m.GetValue())));
|
||||
|
||||
m_monitors.Add(
|
||||
m_staticMonitors.Add(
|
||||
new GenericMonitor(
|
||||
m_scene,
|
||||
"PendingDownloadsMonitor",
|
||||
@@ -265,7 +285,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
|
||||
m => m.Scene.StatsReporter.LastReportedSimStats[17],
|
||||
m => string.Format("{0}", m.GetValue())));
|
||||
|
||||
m_monitors.Add(
|
||||
m_staticMonitors.Add(
|
||||
new GenericMonitor(
|
||||
m_scene,
|
||||
"PendingUploadsMonitor",
|
||||
@@ -273,7 +293,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
|
||||
m => m.Scene.StatsReporter.LastReportedSimStats[18],
|
||||
m => string.Format("{0}", m.GetValue())));
|
||||
|
||||
m_monitors.Add(
|
||||
m_staticMonitors.Add(
|
||||
new GenericMonitor(
|
||||
m_scene,
|
||||
"TotalFrameTimeMonitor",
|
||||
@@ -281,7 +301,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
|
||||
m => m.Scene.StatsReporter.LastReportedSimStats[8],
|
||||
m => string.Format("{0} ms", m.GetValue())));
|
||||
|
||||
m_monitors.Add(
|
||||
m_staticMonitors.Add(
|
||||
new GenericMonitor(
|
||||
m_scene,
|
||||
"NetFrameTimeMonitor",
|
||||
@@ -289,7 +309,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
|
||||
m => m.Scene.StatsReporter.LastReportedSimStats[9],
|
||||
m => string.Format("{0} ms", m.GetValue())));
|
||||
|
||||
m_monitors.Add(
|
||||
m_staticMonitors.Add(
|
||||
new GenericMonitor(
|
||||
m_scene,
|
||||
"PhysicsFrameTimeMonitor",
|
||||
@@ -297,7 +317,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
|
||||
m => m.Scene.StatsReporter.LastReportedSimStats[10],
|
||||
m => string.Format("{0} ms", m.GetValue())));
|
||||
|
||||
m_monitors.Add(
|
||||
m_staticMonitors.Add(
|
||||
new GenericMonitor(
|
||||
m_scene,
|
||||
"SimulationFrameTimeMonitor",
|
||||
@@ -305,7 +325,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
|
||||
m => m.Scene.StatsReporter.LastReportedSimStats[12],
|
||||
m => string.Format("{0} ms", m.GetValue())));
|
||||
|
||||
m_monitors.Add(
|
||||
m_staticMonitors.Add(
|
||||
new GenericMonitor(
|
||||
m_scene,
|
||||
"AgentFrameTimeMonitor",
|
||||
@@ -313,7 +333,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
|
||||
m => m.Scene.StatsReporter.LastReportedSimStats[16],
|
||||
m => string.Format("{0} ms", m.GetValue())));
|
||||
|
||||
m_monitors.Add(
|
||||
m_staticMonitors.Add(
|
||||
new GenericMonitor(
|
||||
m_scene,
|
||||
"ImagesFrameTimeMonitor",
|
||||
@@ -321,7 +341,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
|
||||
m => m.Scene.StatsReporter.LastReportedSimStats[11],
|
||||
m => string.Format("{0} ms", m.GetValue())));
|
||||
|
||||
m_alerts.Add(new DeadlockAlert(m_monitors.Find(x => x is LastFrameTimeMonitor) as LastFrameTimeMonitor));
|
||||
m_alerts.Add(new DeadlockAlert(m_staticMonitors.Find(x => x is LastFrameTimeMonitor) as LastFrameTimeMonitor));
|
||||
|
||||
foreach (IAlert alert in m_alerts)
|
||||
{
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user