Compare commits
359 Commits
master
...
0.7.2-post
Author | SHA1 | Date |
---|---|---|
Justin Clark-Casey (justincc) | a315aee803 | |
Justin Clark-Casey (justincc) | 0c931e3657 | |
Justin Clark-Casey (justincc) | 9f4d772d6a | |
Justin Clark-Casey (justincc) | d6cf029860 | |
Justin Clark-Casey (justincc) | 083587eb32 | |
Justin Clark-Casey (justincc) | 8c8e3ad3ff | |
Justin Clark-Casey (justincc) | 91d5495e26 | |
Justin Clark-Casey (justincc) | 2030377d2c | |
Justin Clark-Casey (justincc) | 31a0f75aff | |
Justin Clark-Casey (justincc) | c1d84ffc6c | |
Justin Clark-Casey (justincc) | 6c72381732 | |
Justin Clark-Casey (justincc) | 8c271802ac | |
Justin Clark-Casey (justincc) | 20a76fd224 | |
Justin Clark-Casey (justincc) | 4473f00e63 | |
Justin Clark-Casey (justincc) | 0b5210dd6a | |
Justin Clark-Casey (justincc) | 34d4bde585 | |
Justin Clark-Casey (justincc) | 4c20c2045c | |
Justin Clark-Casey (justincc) | d9a8f5f16d | |
Justin Clark-Casey (justincc) | 79c2081741 | |
Justin Clark-Casey (justincc) | eb49c356e2 | |
Justin Clark-Casey (justincc) | 717942e81b | |
Justin Clark-Casey (justincc) | 6d47c394b2 | |
Justin Clark-Casey (justincc) | 8305c5d369 | |
Justin Clark-Casey (justincc) | 9e5f5f3d80 | |
Justin Clark-Casey (justincc) | 0a277a64a7 | |
Justin Clark-Casey (justincc) | 7dd0b7ea2f | |
Justin Clark-Casey (justincc) | cd666a3d2c | |
Justin Clark-Casey (justincc) | 681502473e | |
Justin Clark-Casey (justincc) | 0ffe293692 | |
Justin Clark-Casey (justincc) | 356e8516f0 | |
Justin Clark-Casey (justincc) | 71b11f557d | |
Justin Clark-Casey (justincc) | 26be9ed08e | |
Justin Clark-Casey (justincc) | f43d63240d | |
Justin Clark-Casey (justincc) | 5c982c98aa | |
Justin Clark-Casey (justincc) | 63f0ec9aeb | |
Justin Clark-Casey (justincc) | e90cfc17ca | |
Justin Clark-Casey (justincc) | 16d5ce16b6 | |
Justin Clark-Casey (justincc) | ab4c4a362f | |
Justin Clark-Casey (justincc) | b5971db76c | |
Justin Clark-Casey (justincc) | 0c39c9e84d | |
Justin Clark-Casey (justincc) | 0b49773ab3 | |
Justin Clark-Casey (justincc) | 820a39621e | |
Justin Clark-Casey (justincc) | 7a0f4cf8e1 | |
Justin Clark-Casey (justincc) | 2853b78f16 | |
Justin Clark-Casey (justincc) | a3ada745bd | |
Justin Clark-Casey (justincc) | ff0f90bc35 | |
Justin Clark-Casey (justincc) | 7b564b8b35 | |
Justin Clark-Casey (justincc) | 19a818017d | |
Justin Clark-Casey (justincc) | 7bc03a54e5 | |
Justin Clark-Casey (justincc) | aef6a9571c | |
Justin Clark-Casey (justincc) | 0a3b2f904e | |
Justin Clark-Casey (justincc) | 023023a5fc | |
Justin Clark-Casey (justincc) | eebcea22ba | |
Justin Clark-Casey (justincc) | 9474bdb6df | |
Justin Clark-Casey (justincc) | 4d28bac9bb | |
Justin Clark-Casey (justincc) | de746cd987 | |
Justin Clark-Casey (justincc) | 0ef16f9f5b | |
Justin Clark-Casey (justincc) | de0a45d9a3 | |
Justin Clark-Casey (justincc) | a2071e5b13 | |
Justin Clark-Casey (justincc) | 1b3ae566e8 | |
Mic Bowman | 674baa39ed | |
Justin Clark-Casey (justincc) | 1cf57c83e1 | |
Justin Clark-Casey (justincc) | e98e580900 | |
Justin Clark-Casey (justincc) | 292ab783e4 | |
Justin Clark-Casey (justincc) | 0563530bf8 | |
Justin Clark-Casey (justincc) | 2135b89c07 | |
Dan Lake | 2b19a112d9 | |
Justin Clark-Casey (justincc) | cd78f50632 | |
Justin Clark-Casey (justincc) | b300db9e0a | |
Justin Clark-Casey (justincc) | 4370f0e181 | |
Justin Clark-Casey (justincc) | 48ea503c33 | |
nebadon | 546eb88112 | |
Justin Clark-Casey (justincc) | 52710b48ac | |
Justin Clark-Casey (justincc) | cc5e28c1c1 | |
Justin Clark-Casey (justincc) | 67a2d6d855 | |
Justin Clark-Casey (justincc) | 7d426debd3 | |
Justin Clark-Casey (justincc) | 4de98ca4c8 | |
Justin Clark-Casey (justincc) | deb50cd410 | |
Justin Clark-Casey (justincc) | b3cfc5b76e | |
Justin Clark-Casey (justincc) | 27644bcce6 | |
Justin Clark-Casey (justincc) | 903da8acbd | |
Justin Clark-Casey (justincc) | cfdccdd71c | |
Justin Clark-Casey (justincc) | 93e65fb9d5 | |
Justin Clark-Casey (justincc) | af117fe4d4 | |
Justin Clark-Casey (justincc) | 986f6b39ca | |
Justin Clark-Casey (justincc) | 7a8dd539fd | |
Justin Clark-Casey (justincc) | 382cda662f | |
Justin Clark-Casey (justincc) | ede9aea45f | |
Justin Clark-Casey (justincc) | 52b8518fc2 | |
Justin Clark-Casey (justincc) | c3d16955a7 | |
Justin Clark-Casey (justincc) | 61df0da7f9 | |
Justin Clark-Casey (justincc) | f8b0427086 | |
Justin Clark-Casey (justincc) | 5b0d0ef1e9 | |
Justin Clark-Casey (justincc) | 7ca688f5c5 | |
Justin Clark-Casey (justincc) | 9dc1000c27 | |
Justin Clark-Casey (justincc) | 638afca5aa | |
Justin Clark-Casey (justincc) | 7e415e3f85 | |
Justin Clark-Casey (justincc) | 8c4e58995d | |
Justin Clark-Casey (justincc) | d26ded4788 | |
Justin Clark-Casey (justincc) | 5268334c61 | |
Justin Clark-Casey (justincc) | 6ba4cbc259 | |
Melanie | ac445463e9 | |
Justin Clark-Casey (justincc) | 1e83800d32 | |
Justin Clark-Casey (justincc) | 3d94984eee | |
Justin Clark-Casey (justincc) | fd8734b22c | |
Justin Clark-Casey (justincc) | 9b229efdc5 | |
Justin Clark-Casey (justincc) | 81daedcfe3 | |
Michelle Argus | b819771919 | |
Justin Clark-Casey (justincc) | 2f536f92c0 | |
Justin Clark-Casey (justincc) | 0b4774c50c | |
Justin Clark-Casey (justincc) | 139b0d03b6 | |
Justin Clark-Casey (justincc) | c13916d392 | |
Justin Clark-Casey (justincc) | 3ebb56734d | |
Justin Clark-Casey (justincc) | 235147c857 | |
Justin Clark-Casey (justincc) | ddb74bc68d | |
Justin Clark-Casey (justincc) | cd132966df | |
Justin Clark-Casey (justincc) | 5d4fee6eb9 | |
Justin Clark-Casey (justincc) | cc80377325 | |
Justin Clark-Casey (justincc) | 7dce33ce69 | |
Justin Clark-Casey (justincc) | 0dd45f6ca4 | |
Justin Clark-Casey (justincc) | ac3d88804f | |
Justin Clark-Casey (justincc) | f1698552f9 | |
Justin Clark-Casey (justincc) | dfeb424afd | |
Justin Clark-Casey (justincc) | 2380980975 | |
Justin Clark-Casey (justincc) | 52ec854c42 | |
Justin Clark-Casey (justincc) | 4dbfcc26a2 | |
Justin Clark-Casey (justincc) | a262d2492f | |
Justin Clark-Casey (justincc) | e5b7e2fd40 | |
Justin Clark-Casey (justincc) | 7505f23f80 | |
Justin Clark-Casey (justincc) | 7562e63ae6 | |
Justin Clark-Casey (justincc) | 7987a6da95 | |
Justin Clark-Casey (justincc) | fcd60c6b74 | |
Justin Clark-Casey (justincc) | 1e88bf78f1 | |
Justin Clark-Casey (justincc) | a819890137 | |
Justin Clark-Casey (justincc) | 5c85a98f6a | |
Justin Clark-Casey (justincc) | e58daf052d | |
Justin Clark-Casey (justincc) | 0a0e285919 | |
Justin Clark-Casey (justincc) | c693bd51a0 | |
Justin Clark-Casey (justincc) | 808ace0696 | |
Justin Clark-Casey (justincc) | 9730a862db | |
Justin Clark-Casey (justincc) | 754d6036ea | |
Justin Clark-Casey (justincc) | 476d893630 | |
Justin Clark-Casey (justincc) | 0a6374d37a | |
Justin Clark-Casey (justincc) | 0337f2e2a0 | |
Justin Clark-Casey (justincc) | 7be35d5a9a | |
Justin Clark-Casey (justincc) | 8ab2d42143 | |
Justin Clark-Casey (justincc) | dc8ce9ec5d | |
Justin Clark-Casey (justincc) | 7171913400 | |
Justin Clark-Casey (justincc) | 0cf5c0837b | |
Justin Clark-Casey (justincc) | 1edfe05c16 | |
Justin Clark-Casey (justincc) | bba4577d88 | |
Justin Clark-Casey (justincc) | 5c305494ae | |
Justin Clark-Casey (justincc) | 4b2b0d4a05 | |
Justin Clark-Casey (justincc) | 61848ebe0d | |
Justin Clark-Casey (justincc) | f48431345b | |
Justin Clark-Casey (justincc) | 9c4597a00f | |
Justin Clark-Casey (justincc) | b528150d16 | |
Justin Clark-Casey (justincc) | 4a99619bc0 | |
Justin Clark-Casey (justincc) | 5bd27b7b22 | |
Justin Clark-Casey (justincc) | 8ea97cc608 | |
Justin Clark-Casey (justincc) | 1850b778e2 | |
Justin Clark-Casey (justincc) | 5cd33f5e21 | |
Justin Clark-Casey (justincc) | cd3d5379d6 | |
Justin Clark-Casey (justincc) | 58021b5300 | |
Justin Clark-Casey (justincc) | 3b141e5eee | |
Justin Clark-Casey (justincc) | 08bc6622dd | |
Justin Clark-Casey (justincc) | c253539c04 | |
Justin Clark-Casey (justincc) | f3b45be9c0 | |
Justin Clark-Casey (justincc) | 59c19110e4 | |
Justin Clark-Casey (justincc) | 7c03fba3fc | |
Justin Clark-Casey (justincc) | 2593a446ac | |
Justin Clark-Casey (justincc) | 011c1279f5 | |
Justin Clark-Casey (justincc) | 25133cbdf6 | |
Justin Clark-Casey (justincc) | 06ed824711 | |
Justin Clark-Casey (justincc) | 63aa448608 | |
justincc | 4afb773399 | |
Justin Clark-Casey (justincc) | dafe65ad81 | |
Justin Clark-Casey (justincc) | b107a8ec2a | |
Justin Clark-Casey (justincc) | e31d7fe424 | |
justincc | cc9888f28b | |
Justin Clark-Casey (justincc) | fef3baf107 | |
Justin Clark-Casey (justincc) | 123322569d | |
Justin Clark-Casey (justincc) | 8c0d8e72aa | |
Justin Clark-Casey (justincc) | 1e69845869 | |
Justin Clark-Casey (justincc) | 1bc0d0fac6 | |
Justin Clark-Casey (justincc) | f7b5d17aa2 | |
Justin Clark-Casey (justincc) | 85170f5d5d | |
Justin Clark-Casey (justincc) | 66863fdd34 | |
Justin Clark-Casey (justincc) | 6b0553ed7c | |
Justin Clark-Casey (justincc) | 57cffcd1ec | |
Justin Clark-Casey (justincc) | 78739067d1 | |
Justin Clark-Casey (justincc) | 310c2403b0 | |
Justin Clark-Casey (justincc) | a88381ba82 | |
Justin Clark-Casey (justincc) | 1fa0c2f9b0 | |
Justin Clark-Casey (justincc) | 1069390b3e | |
Justin Clark-Casey (justincc) | 3068cc3618 | |
Justin Clark-Casey (justincc) | b5a69833f8 | |
Justin Clark-Casey (justincc) | 8b5bacc78b | |
Justin Clark-Casey (justincc) | 8f7f03e7fd | |
Justin Clark-Casey (justincc) | 80bea38c07 | |
Justin Clark-Casey (justincc) | 9742491a63 | |
Justin Clark-Casey (justincc) | acad65a832 | |
Justin Clark-Casey (justincc) | b527901556 | |
Justin Clark-Casey (justincc) | 3c9654d5d6 | |
Justin Clark-Casey (justincc) | 4be42b3f75 | |
Justin Clark-Casey (justincc) | 6a994f8c9c | |
Justin Clark-Casey (justincc) | f9e6e32ce2 | |
Melanie | 6bbf4fdc0f | |
Dan Lake | 10aee2f0ec | |
Dan Lake | 0ed6149463 | |
Justin Clark-Casey (justincc) | a64be59c3b | |
Justin Clark-Casey (justincc) | b720454950 | |
Justin Clark-Casey (justincc) | dd3dc5cd91 | |
Justin Clark-Casey (justincc) | 9cd94ac6ec | |
Justin Clark-Casey (justincc) | 2cc49d7d9a | |
Justin Clark-Casey (justincc) | 69e11af475 | |
Dan Lake | aa6915f1ba | |
Dan Lake | b36ff0fd24 | |
Justin Clark-Casey (justincc) | a16c9206b4 | |
Justin Clark-Casey (justincc) | b5b2541d1a | |
Justin Clark-Casey (justincc) | 1baadac59a | |
Justin Clark-Casey (justincc) | 88ef35cb23 | |
Justin Clark-Casey (justincc) | 05dff4987b | |
Justin Clark-Casey (justincc) | e1e0f20c7f | |
Justin Clark-Casey (justincc) | 70d559d1af | |
Justin Clark-Casey (justincc) | 6c92b48143 | |
Justin Clark-Casey (justincc) | 127626edd8 | |
Justin Clark-Casey (justincc) | aba26c098d | |
Justin Clark-Casey (justincc) | 9f19405490 | |
Justin Clark-Casey (justincc) | 871f1d0ae7 | |
Justin Clark-Casey (justincc) | 057b78bfbe | |
Justin Clark-Casey (justincc) | d4fc07aae1 | |
Justin Clark-Casey (justincc) | 750e8ec3da | |
Justin Clark-Casey (justincc) | 15142093ad | |
Justin Clark-Casey (justincc) | f050f0fc0b | |
Justin Clark-Casey (justincc) | a3c79b399e | |
Justin Clark-Casey (justincc) | 424735efee | |
Justin Clark-Casey (justincc) | d5dfbc3844 | |
Justin Clark-Casey (justincc) | c3127d1323 | |
Justin Clark-Casey (justincc) | 03c98c3b8f | |
Justin Clark-Casey (justincc) | 24e02afeac | |
Justin Clark-Casey (justincc) | 8d5606e09b | |
Justin Clark-Casey (justincc) | bd3d119a03 | |
Justin Clark-Casey (justincc) | cf2405385d | |
Justin Clark-Casey (justincc) | a6eba09dac | |
Justin Clark-Casey (justincc) | b2ca7c0927 | |
Justin Clark-Casey (justincc) | dd6c236253 | |
Justin Clark-Casey (justincc) | b2ff680cca | |
Justin Clark-Casey (justincc) | 23a9a7daa7 | |
Justin Clark-Casey (justincc) | 19fde57fca | |
Justin Clark-Casey (justincc) | a556930456 | |
Justin Clark-Casey (justincc) | 1a008b237b | |
Justin Clark-Casey (justincc) | d6456b9ea8 | |
Justin Clark-Casey (justincc) | 5980d57b7a | |
Justin Clark-Casey (justincc) | 7c409eff53 | |
Justin Clark-Casey (justincc) | 614ea5a48a | |
Justin Clark-Casey (justincc) | 8905f34e18 | |
Justin Clark-Casey (justincc) | 380f2a1719 | |
Justin Clark-Casey (justincc) | 1c66e08964 | |
Justin Clark-Casey (justincc) | af564291f2 | |
Justin Clark-Casey (justincc) | 250eed5141 | |
Justin Clark-Casey (justincc) | a2c9b3d83d | |
Justin Clark-Casey (justincc) | 3a047b2bdb | |
Justin Clark-Casey (justincc) | f8deca7f2d | |
Justin Clark-Casey (justincc) | 63a6bc93e4 | |
Justin Clark-Casey (justincc) | 50c340ef35 | |
Justin Clark-Casey (justincc) | 41e7e613a2 | |
Justin Clark-Casey (justincc) | 4d1ab38068 | |
Justin Clark-Casey (justincc) | 47c412ca1e | |
Justin Clark-Casey (justincc) | acb0a5b6c1 | |
Justin Clark-Casey (justincc) | 1b8716a99a | |
Justin Clark-Casey (justincc) | 9edbb4f77a | |
Justin Clark-Casey (justincc) | 753f11273f | |
Justin Clark-Casey (justincc) | 435aefe1bf | |
Justin Clark-Casey (justincc) | e5286b7b7c | |
Justin Clark-Casey (justincc) | aa4637db47 | |
Justin Clark-Casey (justincc) | 73c201449f | |
Justin Clark-Casey (justincc) | 36be226dc8 | |
Justin Clark-Casey (justincc) | ea5d1d0ff0 | |
Justin Clark-Casey (justincc) | 299cc2d12d | |
Justin Clark-Casey (justincc) | 4ecd3fbff1 | |
Justin Clark-Casey (justincc) | 1b32d5c6a4 | |
Justin Clark-Casey (justincc) | c404760731 | |
Justin Clark-Casey (justincc) | 7d4e224620 | |
Justin Clark-Casey (justincc) | 986ded5a72 | |
Justin Clark-Casey (justincc) | 8340bd7e20 | |
Justin Clark-Casey (justincc) | 9d59fc0587 | |
Justin Clark-Casey (justincc) | 22e1298e97 | |
Justin Clark-Casey (justincc) | 1a29ddf328 | |
Justin Clark-Casey (justincc) | 8a2c3a0267 | |
Justin Clark-Casey (justincc) | ea65d4f5ce | |
Justin Clark-Casey (justincc) | eb65f5072d | |
Justin Clark-Casey (justincc) | aad13a4c76 | |
Justin Clark-Casey (justincc) | 233127c696 | |
Justin Clark-Casey (justincc) | b7fcd6871e | |
Justin Clark-Casey (justincc) | c06cd3b2b9 | |
Justin Clark-Casey (justincc) | 31ac7571f4 | |
Justin Clark-Casey (justincc) | 2a7a5c4c90 | |
Justin Clark-Casey (justincc) | d8ad649957 | |
Justin Clark-Casey (justincc) | a1f232af2b | |
Justin Clark-Casey (justincc) | 14bddb6af9 | |
Justin Clark-Casey (justincc) | f93635fe85 | |
Justin Clark-Casey (justincc) | 3a635507cc | |
Justin Clark-Casey (justincc) | 0506ccb51a | |
Justin Clark-Casey (justincc) | 4bce90d0ab | |
Justin Clark-Casey (justincc) | 4d93ab06c9 | |
Justin Clark-Casey (justincc) | e2c807a0d0 | |
Justin Clark-Casey (justincc) | 23a9a98d5d | |
Justin Clark-Casey (justincc) | 32ba06a55c | |
Justin Clark-Casey (justincc) | 64c42a729a | |
Justin Clark-Casey (justincc) | b342fb9c0a | |
Justin Clark-Casey (justincc) | 3f70f54fa6 | |
Justin Clark-Casey (justincc) | c4ce7b8162 | |
Justin Clark-Casey (justincc) | 4c9226be7b | |
Diva Canto | 58f2c9e224 | |
Diva Canto | 8ba0cc470a | |
Justin Clark-Casey (justincc) | 2a654974c9 | |
Diva Canto | b72753dc81 | |
Justin Clark-Casey (justincc) | 2ecfa29eb6 | |
Justin Clark-Casey (justincc) | 3678b8f1f7 | |
Justin Clark-Casey (justincc) | 29a62abc6d | |
Justin Clark-Casey (justincc) | 31ef2f9a2e | |
Justin Clark-Casey (justincc) | 21e3f8e53a | |
Justin Clark-Casey (justincc) | 579aa9c6a0 | |
BlueWall | 8b374daae9 | |
Justin Clark-Casey (justincc) | 31d1b3310d | |
Pixel Tomsen | d1711519a0 | |
BlueWall | 71fa970990 | |
Justin Clark-Casey (justincc) | 6fa4f88d39 | |
Justin Clark-Casey (justincc) | 9ff3d9221b | |
Justin Clark-Casey (justincc) | 3920e56dd4 | |
Justin Clark-Casey (justincc) | 6700f1edd9 | |
Justin Clark-Casey (justincc) | e6d1182dec | |
Justin Clark-Casey (justincc) | a3316f1eac | |
Pixel Tomsen | 5f281716a9 | |
Pixel Tomsen | f90c3d0633 | |
Justin Clark-Casey (justincc) | 633d4f3e6e | |
Justin Clark-Casey (justincc) | 43bbdbe760 | |
Justin Clark-Casey (justincc) | 494e5867a3 | |
Justin Clark-Casey (justincc) | 270f0d5ae3 | |
Dan Lake | d079ee9ef1 | |
Justin Clark-Casey (justincc) | cd46bf6fad | |
Justin Clark-Casey (justincc) | bb419044ef | |
Justin Clark-Casey (justincc) | 549fdc8b11 | |
Justin Clark-Casey (justincc) | 550d1fea96 | |
Justin Clark-Casey (justincc) | 94f49e859b | |
Snoopy Pfeffer | c2586b0ea9 | |
Justin Clark-Casey (justincc) | 2905288545 | |
Justin Clark-Casey (justincc) | 353170589b | |
Justin Clark-Casey (justincc) | ee78c4d2a8 | |
Justin Clark-Casey (justincc) | 084df4b7ef | |
Justin Clark-Casey (justincc) | 53ffc7ff8c | |
Justin Clark-Casey (justincc) | d8d048cfa1 | |
Justin Clark-Casey (justincc) | a4e1d29e3c | |
Justin Clark-Casey (justincc) | 8c4dd6b330 | |
Justin Clark-Casey (justincc) | f1612997a6 | |
Justin Clark-Casey (justincc) | c574c80011 | |
Justin Clark-Casey (justincc) | 9f76bc4fff | |
Justin Clark-Casey (justincc) | 79f3de6ba8 |
|
@ -8,6 +8,7 @@
|
||||||
<target name="distbin">
|
<target name="distbin">
|
||||||
<copy file="bin/OpenSim.ini.example" tofile="bin/OpenSim.ini"/>
|
<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/StandaloneCommon.ini.example" tofile="bin/config-include/StandaloneCommon.ini"/>
|
||||||
|
<copy file="bin/config-include/FlotsamCache.ini.example" tofile="bin/config-include/FlotsamCache.ini"/>
|
||||||
<delete dir="${distbindir}"/>
|
<delete dir="${distbindir}"/>
|
||||||
<copy todir="${distbindir}">
|
<copy todir="${distbindir}">
|
||||||
<fileset>
|
<fileset>
|
||||||
|
@ -111,12 +112,15 @@
|
||||||
</exec>
|
</exec>
|
||||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.framework.serialization.tests)==0}" />
|
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.framework.serialization.tests)==0}" />
|
||||||
|
|
||||||
<!--
|
<exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.region.clientstack.lindencaps.tests">
|
||||||
|
<arg value="./bin/OpenSim.Region.ClientStack.LindenCaps.Tests.dll" />
|
||||||
|
</exec>
|
||||||
|
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.clientstack.lindencaps.tests)==0}" />
|
||||||
|
|
||||||
<exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.region.clientstack.lindenudp.tests">
|
<exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.region.clientstack.lindenudp.tests">
|
||||||
<arg value="./bin/OpenSim.Region.ClientStack.LindenUDP.Tests.dll" />
|
<arg value="./bin/OpenSim.Region.ClientStack.LindenUDP.Tests.dll" />
|
||||||
</exec>
|
</exec>
|
||||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.clientstack.lindenudp.tests)==0}" />
|
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.clientstack.lindenudp.tests)==0}" />
|
||||||
-->
|
|
||||||
|
|
||||||
<exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.region.scriptengine.tests">
|
<exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.region.scriptengine.tests">
|
||||||
<arg value="./bin/OpenSim.Region.ScriptEngine.Tests.dll" />
|
<arg value="./bin/OpenSim.Region.ScriptEngine.Tests.dll" />
|
||||||
|
@ -297,12 +301,15 @@
|
||||||
<arg value="-xml=test-results/OpenSim.Framework.Servers.Tests.dll-Results.xml" />
|
<arg value="-xml=test-results/OpenSim.Framework.Servers.Tests.dll-Results.xml" />
|
||||||
</exec>
|
</exec>
|
||||||
|
|
||||||
<!--
|
<exec program="${nunitcmd}" failonerror="false" resultproperty="testresult.opensim.region.clientstack.lindencaps.tests">
|
||||||
|
<arg value="./bin/OpenSim.Region.ClientStack.LindenCaps.Tests.dll" />
|
||||||
|
<arg value="-xml=test-results/OpenSim.Region.ClientStack.LindenCaps.Tests.dll-Results.xml" />
|
||||||
|
</exec>
|
||||||
|
|
||||||
<exec program="${nunitcmd}" failonerror="false" resultproperty="testresult.opensim.region.clientstack.lindenudp.tests">
|
<exec program="${nunitcmd}" failonerror="false" resultproperty="testresult.opensim.region.clientstack.lindenudp.tests">
|
||||||
<arg value="./bin/OpenSim.Region.ClientStack.LindenUDP.Tests.dll" />
|
<arg value="./bin/OpenSim.Region.ClientStack.LindenUDP.Tests.dll" />
|
||||||
<arg value="-xml=test-results/OpenSim.Region.ClientStack.LindenUDP.Tests.dll-Results.xml" />
|
<arg value="-xml=test-results/OpenSim.Region.ClientStack.LindenUDP.Tests.dll-Results.xml" />
|
||||||
</exec>
|
</exec>
|
||||||
-->
|
|
||||||
|
|
||||||
<exec program="${nunitcmd}" failonerror="false" resultproperty="testresult.opensim.region.scriptengine.tests">
|
<exec program="${nunitcmd}" failonerror="false" resultproperty="testresult.opensim.region.scriptengine.tests">
|
||||||
<arg value="./bin/OpenSim.Region.ScriptEngine.Tests.dll" />
|
<arg value="./bin/OpenSim.Region.ScriptEngine.Tests.dll" />
|
||||||
|
@ -332,7 +339,7 @@
|
||||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.tests)==0}" />
|
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.tests)==0}" />
|
||||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.framework.tests)==0}" />
|
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.framework.tests)==0}" />
|
||||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.framework.servers.tests)==0}" />
|
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.framework.servers.tests)==0}" />
|
||||||
<!-- <fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.clientstack.lindenudp.tests)==0}" /> -->
|
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.clientstack.lindenudp.tests)==0}" />
|
||||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.scriptengine.tests)==0}" />
|
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.scriptengine.tests)==0}" />
|
||||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.coremodules.tests)==0}" />
|
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.coremodules.tests)==0}" />
|
||||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.optionalmodules.tests)==0}" />
|
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.optionalmodules.tests)==0}" />
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -51,11 +51,10 @@ namespace OpenSim.Framework.Capabilities
|
||||||
/// supplied BaseHttpServer.
|
/// supplied BaseHttpServer.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="httpListener">base HTTP server</param>
|
/// <param name="httpListener">base HTTP server</param>
|
||||||
/// <param name="httpListenerHostname">host name of the HTTP
|
/// <param name="httpListenerHostname">host name of the HTTP server</param>
|
||||||
/// server</param>
|
|
||||||
/// <param name="httpListenerPort">HTTP port</param>
|
/// <param name="httpListenerPort">HTTP port</param>
|
||||||
public CapsHandlers(BaseHttpServer httpListener, string httpListenerHostname, uint httpListenerPort)
|
public CapsHandlers(BaseHttpServer httpListener, string httpListenerHostname, uint httpListenerPort)
|
||||||
: this (httpListener,httpListenerHostname,httpListenerPort, false)
|
: this(httpListener,httpListenerHostname,httpListenerPort, false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,14 +86,18 @@ namespace OpenSim.Framework.Capabilities
|
||||||
/// <param name="capsName">name of the capability of the cap
|
/// <param name="capsName">name of the capability of the cap
|
||||||
/// handler to be removed</param>
|
/// handler to be removed</param>
|
||||||
public void Remove(string capsName)
|
public void Remove(string capsName)
|
||||||
|
{
|
||||||
|
lock (m_capsHandlers)
|
||||||
{
|
{
|
||||||
m_httpListener.RemoveStreamHandler("POST", m_capsHandlers[capsName].Path);
|
m_httpListener.RemoveStreamHandler("POST", m_capsHandlers[capsName].Path);
|
||||||
m_httpListener.RemoveStreamHandler("GET", m_capsHandlers[capsName].Path);
|
m_httpListener.RemoveStreamHandler("GET", m_capsHandlers[capsName].Path);
|
||||||
m_capsHandlers.Remove(capsName);
|
m_capsHandlers.Remove(capsName);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public bool ContainsCap(string cap)
|
public bool ContainsCap(string cap)
|
||||||
{
|
{
|
||||||
|
lock (m_capsHandlers)
|
||||||
return m_capsHandlers.ContainsKey(cap);
|
return m_capsHandlers.ContainsKey(cap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,19 +105,22 @@ namespace OpenSim.Framework.Capabilities
|
||||||
/// The indexer allows us to treat the CapsHandlers object
|
/// The indexer allows us to treat the CapsHandlers object
|
||||||
/// in an intuitive dictionary like way.
|
/// in an intuitive dictionary like way.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <Remarks>
|
/// <remarks>
|
||||||
/// The indexer will throw an exception when you try to
|
/// The indexer will throw an exception when you try to
|
||||||
/// retrieve a cap handler for a cap that is not contained in
|
/// retrieve a cap handler for a cap that is not contained in
|
||||||
/// CapsHandlers.
|
/// CapsHandlers.
|
||||||
/// </Remarks>
|
/// </remarks>
|
||||||
public IRequestHandler this[string idx]
|
public IRequestHandler this[string idx]
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
lock (m_capsHandlers)
|
||||||
return m_capsHandlers[idx];
|
return m_capsHandlers[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
set
|
set
|
||||||
|
{
|
||||||
|
lock (m_capsHandlers)
|
||||||
{
|
{
|
||||||
if (m_capsHandlers.ContainsKey(idx))
|
if (m_capsHandlers.ContainsKey(idx))
|
||||||
{
|
{
|
||||||
|
@ -128,6 +134,7 @@ namespace OpenSim.Framework.Capabilities
|
||||||
m_httpListener.AddStreamHandler(value);
|
m_httpListener.AddStreamHandler(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Return the list of cap names for which this CapsHandlers
|
/// Return the list of cap names for which this CapsHandlers
|
||||||
|
@ -136,20 +143,22 @@ namespace OpenSim.Framework.Capabilities
|
||||||
public string[] Caps
|
public string[] Caps
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
{
|
||||||
|
lock (m_capsHandlers)
|
||||||
{
|
{
|
||||||
string[] __keys = new string[m_capsHandlers.Keys.Count];
|
string[] __keys = new string[m_capsHandlers.Keys.Count];
|
||||||
m_capsHandlers.Keys.CopyTo(__keys, 0);
|
m_capsHandlers.Keys.CopyTo(__keys, 0);
|
||||||
return __keys;
|
return __keys;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Return an LLSD-serializable Hashtable describing the
|
/// Return an LLSD-serializable Hashtable describing the
|
||||||
/// capabilities and their handler details.
|
/// capabilities and their handler details.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Hashtable CapsDetails
|
/// <param name="excludeSeed">If true, then exclude the seed cap.</param>
|
||||||
{
|
public Hashtable GetCapsDetails(bool excludeSeed)
|
||||||
get
|
|
||||||
{
|
{
|
||||||
Hashtable caps = new Hashtable();
|
Hashtable caps = new Hashtable();
|
||||||
string protocol = "http://";
|
string protocol = "http://";
|
||||||
|
@ -158,14 +167,19 @@ namespace OpenSim.Framework.Capabilities
|
||||||
protocol = "https://";
|
protocol = "https://";
|
||||||
|
|
||||||
string baseUrl = protocol + m_httpListenerHostName + ":" + m_httpListenerPort.ToString();
|
string baseUrl = protocol + m_httpListenerHostName + ":" + m_httpListenerPort.ToString();
|
||||||
|
|
||||||
|
lock (m_capsHandlers)
|
||||||
|
{
|
||||||
foreach (string capsName in m_capsHandlers.Keys)
|
foreach (string capsName in m_capsHandlers.Keys)
|
||||||
{
|
{
|
||||||
// skip SEED cap
|
if (excludeSeed && "SEED" == capsName)
|
||||||
if ("SEED" == capsName) continue;
|
continue;
|
||||||
|
|
||||||
caps[capsName] = baseUrl + m_capsHandlers[capsName].Path;
|
caps[capsName] = baseUrl + m_capsHandlers[capsName].Path;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return caps;
|
return caps;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -111,6 +111,10 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
m_log.Warn("[GETTEXTURE]: Failed to parse a texture_id from GetTexture request: " + httpRequest.Url);
|
m_log.Warn("[GETTEXTURE]: Failed to parse a texture_id from GetTexture request: " + httpRequest.Url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[GETTEXTURE]: For texture {0} sending back response {1}, data length {2}",
|
||||||
|
// textureID, httpResponse.StatusCode, httpResponse.ContentLength);
|
||||||
|
|
||||||
httpResponse.Send();
|
httpResponse.Send();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -210,7 +214,7 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
private void WriteTextureData(OSHttpRequest request, OSHttpResponse response, AssetBase texture, string format)
|
private void WriteTextureData(OSHttpRequest request, OSHttpResponse response, AssetBase texture, string format)
|
||||||
{
|
{
|
||||||
string range = request.Headers.GetOne("Range");
|
string range = request.Headers.GetOne("Range");
|
||||||
//m_log.DebugFormat("[GETTEXTURE]: Range {0}", range);
|
|
||||||
if (!String.IsNullOrEmpty(range)) // JP2's only
|
if (!String.IsNullOrEmpty(range)) // JP2's only
|
||||||
{
|
{
|
||||||
// Range request
|
// Range request
|
||||||
|
@ -222,16 +226,19 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
if (start >= texture.Data.Length)
|
if (start >= texture.Data.Length)
|
||||||
{
|
{
|
||||||
response.StatusCode = (int)System.Net.HttpStatusCode.RequestedRangeNotSatisfiable;
|
response.StatusCode = (int)System.Net.HttpStatusCode.RequestedRangeNotSatisfiable;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
end = Utils.Clamp(end, 0, texture.Data.Length - 1);
|
end = Utils.Clamp(end, 0, texture.Data.Length - 1);
|
||||||
start = Utils.Clamp(start, 0, end);
|
start = Utils.Clamp(start, 0, end);
|
||||||
int len = end - start + 1;
|
int len = end - start + 1;
|
||||||
|
|
||||||
//m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID);
|
//m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID);
|
||||||
|
|
||||||
if (len < texture.Data.Length)
|
// Always return PartialContent, even if the range covered the entire data length
|
||||||
|
// We were accidentally sending back 404 before in this situation
|
||||||
|
// https://issues.apache.org/bugzilla/show_bug.cgi?id=51878 supports sending 206 even if the
|
||||||
|
// entire range is requested, and viewer 3.2.2 (and very probably earlier) seems fine with this.
|
||||||
response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent;
|
response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent;
|
||||||
|
|
||||||
response.ContentLength = len;
|
response.ContentLength = len;
|
||||||
|
@ -240,6 +247,7 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
|
|
||||||
response.Body.Write(texture.Data, start, len);
|
response.Body.Write(texture.Data, start, len);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_log.Warn("[GETTEXTURE]: Malformed Range header: " + range);
|
m_log.Warn("[GETTEXTURE]: Malformed Range header: " + range);
|
||||||
|
@ -257,6 +265,10 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
response.ContentType = "image/" + format;
|
response.ContentType = "image/" + format;
|
||||||
response.Body.Write(texture.Data, 0, texture.Data.Length);
|
response.Body.Write(texture.Data, 0, texture.Data.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[GETTEXTURE]: For texture {0} requested range {1} responded {2} with content length {3} (actual {4})",
|
||||||
|
// texture.FullID, range, response.StatusCode, response.ContentLength, texture.Data.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool TryParseRange(string header, out int start, out int end)
|
private bool TryParseRange(string header, out int start, out int end)
|
||||||
|
@ -275,7 +287,6 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private byte[] ConvertTextureData(AssetBase texture, string format)
|
private byte[] ConvertTextureData(AssetBase texture, string format)
|
||||||
{
|
{
|
||||||
m_log.DebugFormat("[GETTEXTURE]: Converting texture {0} to {1}", texture.ID, format);
|
m_log.DebugFormat("[GETTEXTURE]: Converting texture {0} to {1}", texture.ID, format);
|
||||||
|
@ -350,7 +361,5 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,181 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
using System.Collections.Specialized;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.IO;
|
||||||
|
using System.Web;
|
||||||
|
using log4net;
|
||||||
|
using Nini.Config;
|
||||||
|
using OpenMetaverse;
|
||||||
|
using OpenMetaverse.StructuredData;
|
||||||
|
using OpenMetaverse.Imaging;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Framework.Capabilities;
|
||||||
|
using OpenSim.Framework.Servers;
|
||||||
|
using OpenSim.Framework.Servers.HttpServer;
|
||||||
|
using OpenSim.Region.Framework.Interfaces;
|
||||||
|
using OpenSim.Services.Interfaces;
|
||||||
|
using Caps = OpenSim.Framework.Capabilities.Caps;
|
||||||
|
|
||||||
|
namespace OpenSim.Capabilities.Handlers
|
||||||
|
{
|
||||||
|
public class UploadBakedTextureHandler
|
||||||
|
{
|
||||||
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
private Caps m_HostCapsObj;
|
||||||
|
private IAssetService m_assetService;
|
||||||
|
private bool m_persistBakedTextures;
|
||||||
|
|
||||||
|
public UploadBakedTextureHandler(Caps caps, IAssetService assetService, bool persistBakedTextures)
|
||||||
|
{
|
||||||
|
m_HostCapsObj = caps;
|
||||||
|
m_assetService = assetService;
|
||||||
|
m_persistBakedTextures = persistBakedTextures;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handle a request from the client for a Uri to upload a baked texture.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request"></param>
|
||||||
|
/// <param name="path"></param>
|
||||||
|
/// <param name="param"></param>
|
||||||
|
/// <param name="httpRequest"></param>
|
||||||
|
/// <param name="httpResponse"></param>
|
||||||
|
/// <returns>The upload response if the request is successful, null otherwise.</returns>
|
||||||
|
public string UploadBakedTexture(
|
||||||
|
string request, string path, string param, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string capsBase = "/CAPS/" + m_HostCapsObj.CapsObjectPath;
|
||||||
|
string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000");
|
||||||
|
|
||||||
|
BakedTextureUploader uploader =
|
||||||
|
new BakedTextureUploader(capsBase + uploaderPath, m_HostCapsObj.HttpListener);
|
||||||
|
uploader.OnUpLoad += BakedTextureUploaded;
|
||||||
|
|
||||||
|
m_HostCapsObj.HttpListener.AddStreamHandler(
|
||||||
|
new BinaryStreamHandler("POST", capsBase + uploaderPath,
|
||||||
|
uploader.uploaderCaps));
|
||||||
|
|
||||||
|
string protocol = "http://";
|
||||||
|
|
||||||
|
if (m_HostCapsObj.SSLCaps)
|
||||||
|
protocol = "https://";
|
||||||
|
|
||||||
|
string uploaderURL = protocol + m_HostCapsObj.HostName + ":" +
|
||||||
|
m_HostCapsObj.Port.ToString() + capsBase + uploaderPath;
|
||||||
|
|
||||||
|
LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse();
|
||||||
|
uploadResponse.uploader = uploaderURL;
|
||||||
|
uploadResponse.state = "upload";
|
||||||
|
|
||||||
|
return LLSDHelpers.SerialiseLLSDReply(uploadResponse);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
m_log.Error("[UPLOAD BAKED TEXTURE HANDLER]: " + e.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called when a baked texture has been successfully uploaded by a client.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="assetID"></param>
|
||||||
|
/// <param name="data"></param>
|
||||||
|
private void BakedTextureUploaded(UUID assetID, byte[] data)
|
||||||
|
{
|
||||||
|
// m_log.WarnFormat("[CAPS]: Received baked texture {0}", assetID.ToString());
|
||||||
|
|
||||||
|
AssetBase asset;
|
||||||
|
asset = new AssetBase(assetID, "Baked Texture", (sbyte)AssetType.Texture, m_HostCapsObj.AgentID.ToString());
|
||||||
|
asset.Data = data;
|
||||||
|
asset.Temporary = true;
|
||||||
|
asset.Local = !m_persistBakedTextures; // Local assets aren't persisted, non-local are
|
||||||
|
m_assetService.Store(asset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class BakedTextureUploader
|
||||||
|
{
|
||||||
|
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
public event Action<UUID, byte[]> OnUpLoad;
|
||||||
|
|
||||||
|
private string uploaderPath = String.Empty;
|
||||||
|
private UUID newAssetID;
|
||||||
|
private IHttpServer httpListener;
|
||||||
|
|
||||||
|
public BakedTextureUploader(string path, IHttpServer httpServer)
|
||||||
|
{
|
||||||
|
newAssetID = UUID.Random();
|
||||||
|
uploaderPath = path;
|
||||||
|
httpListener = httpServer;
|
||||||
|
// m_log.InfoFormat("[CAPS] baked texture upload starting for {0}",newAssetID);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handle raw uploaded baked texture data.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="data"></param>
|
||||||
|
/// <param name="path"></param>
|
||||||
|
/// <param name="param"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public string uploaderCaps(byte[] data, string path, string param)
|
||||||
|
{
|
||||||
|
Action<UUID, byte[]> handlerUpLoad = OnUpLoad;
|
||||||
|
|
||||||
|
// Don't do this asynchronously, otherwise it's possible for the client to send set appearance information
|
||||||
|
// on another thread which might send out avatar updates before the asset has been put into the asset
|
||||||
|
// service.
|
||||||
|
if (handlerUpLoad != null)
|
||||||
|
handlerUpLoad(newAssetID, data);
|
||||||
|
|
||||||
|
string res = String.Empty;
|
||||||
|
LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete();
|
||||||
|
uploadComplete.new_asset = newAssetID.ToString();
|
||||||
|
uploadComplete.new_inventory_item = UUID.Zero;
|
||||||
|
uploadComplete.state = "complete";
|
||||||
|
|
||||||
|
res = LLSDHelpers.SerialiseLLSDReply(uploadComplete);
|
||||||
|
|
||||||
|
httpListener.RemoveStreamHandler("POST", uploaderPath);
|
||||||
|
|
||||||
|
// m_log.DebugFormat("[BAKED TEXTURE UPLOADER]: baked texture upload completed for {0}", newAssetID);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -208,7 +208,86 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
containingFolder.Owner = agentID;
|
containingFolder.Owner = agentID;
|
||||||
containingFolder = m_InventoryService.GetFolder(containingFolder);
|
containingFolder = m_InventoryService.GetFolder(containingFolder);
|
||||||
if (containingFolder != null)
|
if (containingFolder != null)
|
||||||
|
{
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[WEB FETCH INV DESC HANDLER]: Retrieved folder {0} {1} for agent id {2}",
|
||||||
|
// containingFolder.Name, containingFolder.ID, agentID);
|
||||||
|
|
||||||
version = containingFolder.Version;
|
version = containingFolder.Version;
|
||||||
|
//
|
||||||
|
// if (fetchItems)
|
||||||
|
// {
|
||||||
|
// List<InventoryItemBase> linkedItemsToAdd = new List<InventoryItemBase>();
|
||||||
|
//
|
||||||
|
// foreach (InventoryItemBase item in contents.Items)
|
||||||
|
// {
|
||||||
|
// if (item.AssetType == (int)AssetType.Link)
|
||||||
|
// {
|
||||||
|
// InventoryItemBase linkedItem = m_InventoryService.GetItem(new InventoryItemBase(item.AssetID));
|
||||||
|
//
|
||||||
|
// // Take care of genuinely broken links where the target doesn't exist
|
||||||
|
// // HACK: Also, don't follow up links that just point to other links. In theory this is legitimate,
|
||||||
|
// // but no viewer has been observed to set these up and this is the lazy way of avoiding cycles
|
||||||
|
// // rather than having to keep track of every folder requested in the recursion.
|
||||||
|
// if (linkedItem != null && linkedItem.AssetType != (int)AssetType.Link)
|
||||||
|
// linkedItemsToAdd.Insert(0, linkedItem);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// foreach (InventoryItemBase linkedItem in linkedItemsToAdd)
|
||||||
|
// {
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[WEB FETCH INV DESC HANDLER]: Inserted linked item {0} for link in folder {1} for agent {2}",
|
||||||
|
// linkedItem.Name, folderID, agentID);
|
||||||
|
//
|
||||||
|
// contents.Items.Add(linkedItem);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // If the folder requested contains links, then we need to send those folders first, otherwise the links
|
||||||
|
// // will be broken in the viewer.
|
||||||
|
// HashSet<UUID> linkedItemFolderIdsToSend = new HashSet<UUID>();
|
||||||
|
// foreach (InventoryItemBase item in contents.Items)
|
||||||
|
// {
|
||||||
|
// if (item.AssetType == (int)AssetType.Link)
|
||||||
|
// {
|
||||||
|
// InventoryItemBase linkedItem = m_InventoryService.GetItem(new InventoryItemBase(item.AssetID));
|
||||||
|
//
|
||||||
|
// // Take care of genuinely broken links where the target doesn't exist
|
||||||
|
// // HACK: Also, don't follow up links that just point to other links. In theory this is legitimate,
|
||||||
|
// // but no viewer has been observed to set these up and this is the lazy way of avoiding cycles
|
||||||
|
// // rather than having to keep track of every folder requested in the recursion.
|
||||||
|
// if (linkedItem != null && linkedItem.AssetType != (int)AssetType.Link)
|
||||||
|
// {
|
||||||
|
// // We don't need to send the folder if source and destination of the link are in the same
|
||||||
|
// // folder.
|
||||||
|
// if (linkedItem.Folder != containingFolder.ID)
|
||||||
|
// linkedItemFolderIdsToSend.Add(linkedItem.Folder);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// foreach (UUID linkedItemFolderId in linkedItemFolderIdsToSend)
|
||||||
|
// {
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[WEB FETCH INV DESC HANDLER]: Recursively fetching folder {0} linked by item in folder {1} for agent {2}",
|
||||||
|
// linkedItemFolderId, folderID, agentID);
|
||||||
|
//
|
||||||
|
// int dummyVersion;
|
||||||
|
// InventoryCollection linkedCollection
|
||||||
|
// = Fetch(
|
||||||
|
// agentID, linkedItemFolderId, ownerID, fetchFolders, fetchItems, sortOrder, out dummyVersion);
|
||||||
|
//
|
||||||
|
// InventoryFolderBase linkedFolder = new InventoryFolderBase(linkedItemFolderId);
|
||||||
|
// linkedFolder.Owner = agentID;
|
||||||
|
// linkedFolder = m_InventoryService.GetFolder(linkedFolder);
|
||||||
|
//
|
||||||
|
//// contents.Folders.AddRange(linkedCollection.Folders);
|
||||||
|
//
|
||||||
|
// contents.Folders.Add(linkedFolder);
|
||||||
|
// contents.Items.AddRange(linkedCollection.Items);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -33,6 +33,7 @@ using System.IO;
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using OpenSim.Server.Base;
|
using OpenSim.Server.Base;
|
||||||
|
using OpenSim.Framework;
|
||||||
using OpenSim.Framework.Console;
|
using OpenSim.Framework.Console;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
|
|
||||||
|
|
|
@ -37,10 +37,30 @@ namespace OpenSim.Data
|
||||||
public UUID RegionID;
|
public UUID RegionID;
|
||||||
public UUID ScopeID;
|
public UUID ScopeID;
|
||||||
public string RegionName;
|
public string RegionName;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The position in meters of this region.
|
||||||
|
/// </summary>
|
||||||
public int posX;
|
public int posX;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The position in meters of this region.
|
||||||
|
/// </summary>
|
||||||
public int posY;
|
public int posY;
|
||||||
|
|
||||||
public int sizeX;
|
public int sizeX;
|
||||||
public int sizeY;
|
public int sizeY;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Return the x-coordinate of this region.
|
||||||
|
/// </summary>
|
||||||
|
public int coordX { get { return posX / (int)Constants.RegionSize; } }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Return the y-coordinate of this region.
|
||||||
|
/// </summary>
|
||||||
|
public int coordY { get { return posY / (int)Constants.RegionSize; } }
|
||||||
|
|
||||||
public Dictionary<string, object> Data;
|
public Dictionary<string, object> Data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -794,7 +794,8 @@ namespace OpenSim.Data.MySQL
|
||||||
{
|
{
|
||||||
dbcon.Open();
|
dbcon.Open();
|
||||||
|
|
||||||
using (MySqlCommand cmd = new MySqlCommand("DELETE FROM inventoryfolders WHERE folderID=?uuid", dbcon))
|
// System folders can never be deleted. Period.
|
||||||
|
using (MySqlCommand cmd = new MySqlCommand("DELETE FROM inventoryfolders WHERE folderID=?uuid and type=-1", dbcon))
|
||||||
{
|
{
|
||||||
cmd.Parameters.AddWithValue("?uuid", folderID.ToString());
|
cmd.Parameters.AddWithValue("?uuid", folderID.ToString());
|
||||||
|
|
||||||
|
|
|
@ -56,13 +56,21 @@ namespace OpenSim.Data.Null
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public FriendsData[] GetFriends(string userID)
|
public FriendsData[] GetFriends(string userID)
|
||||||
{
|
{
|
||||||
List<FriendsData> lst = m_Data.FindAll(delegate (FriendsData fdata)
|
List<FriendsData> lst = m_Data.FindAll(fdata =>
|
||||||
{
|
{
|
||||||
return fdata.PrincipalID == userID.ToString();
|
return fdata.PrincipalID == userID.ToString();
|
||||||
});
|
});
|
||||||
|
|
||||||
if (lst != null)
|
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"]; }
|
||||||
|
});
|
||||||
|
|
||||||
return lst.ToArray();
|
return lst.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
return new FriendsData[0];
|
return new FriendsData[0];
|
||||||
}
|
}
|
||||||
|
|
|
@ -311,7 +311,7 @@ namespace OpenSim.Framework
|
||||||
if (args.ContainsKey("packed_appearance") && (args["packed_appearance"].Type == OSDType.Map))
|
if (args.ContainsKey("packed_appearance") && (args["packed_appearance"].Type == OSDType.Map))
|
||||||
{
|
{
|
||||||
Appearance.Unpack((OSDMap)args["packed_appearance"]);
|
Appearance.Unpack((OSDMap)args["packed_appearance"]);
|
||||||
m_log.InfoFormat("[AGENTCIRCUITDATA] unpacked appearance");
|
// m_log.InfoFormat("[AGENTCIRCUITDATA] unpacked appearance");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -335,7 +335,7 @@ namespace OpenSim.Framework
|
||||||
|
|
||||||
public virtual OSDMap Pack()
|
public virtual OSDMap Pack()
|
||||||
{
|
{
|
||||||
m_log.InfoFormat("[CHILDAGENTDATAUPDATE] Pack data");
|
// m_log.InfoFormat("[CHILDAGENTDATAUPDATE] Pack data");
|
||||||
|
|
||||||
OSDMap args = new OSDMap();
|
OSDMap args = new OSDMap();
|
||||||
args["message_type"] = OSD.FromString("AgentData");
|
args["message_type"] = OSD.FromString("AgentData");
|
||||||
|
|
|
@ -31,19 +31,10 @@ namespace OpenSim.Framework
|
||||||
{
|
{
|
||||||
public string PhysicsEngine { get; set; }
|
public string PhysicsEngine { get; set; }
|
||||||
public string MeshEngineName { get; set; }
|
public string MeshEngineName { get; set; }
|
||||||
public bool See_into_region_from_neighbor { get; set; }
|
|
||||||
public string StorageDll { get; set; }
|
public string StorageDll { get; set; }
|
||||||
public string ClientstackDll { get; set; }
|
public string ClientstackDll { get; set; }
|
||||||
public bool PhysicalPrim { get; set; }
|
|
||||||
public string LibrariesXMLFile { get; set; }
|
public string LibrariesXMLFile { get; set; }
|
||||||
|
|
||||||
public const uint DefaultAssetServerHttpPort = 8003;
|
|
||||||
public const uint DefaultRegionHttpPort = 9000;
|
public const uint DefaultRegionHttpPort = 9000;
|
||||||
public const uint DefaultUserServerHttpPort = 8002;
|
|
||||||
public const bool DefaultUserServerHttpSSL = false;
|
|
||||||
public const uint DefaultMessageServerHttpPort = 8006;
|
|
||||||
public const bool DefaultMessageServerHttpSSL = false;
|
|
||||||
public const uint DefaultGridServerHttpPort = 8003;
|
|
||||||
public const uint DefaultInventoryServerHttpPort = 8003;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -33,7 +33,7 @@ using System.Reflection;
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
using log4net;
|
using log4net;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
using OpenSim.Framework.Console;
|
//using OpenSim.Framework.Console;
|
||||||
|
|
||||||
namespace OpenSim.Framework
|
namespace OpenSim.Framework
|
||||||
{
|
{
|
||||||
|
|
|
@ -33,12 +33,11 @@ using System.Reflection;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using log4net;
|
using log4net;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
|
||||||
namespace OpenSim.Framework.Console
|
namespace OpenSim.Framework.Console
|
||||||
{
|
{
|
||||||
public delegate void CommandDelegate(string module, string[] cmd);
|
public class Commands : ICommands
|
||||||
|
|
||||||
public class Commands
|
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Encapsulates a command that can be invoked from the console
|
/// Encapsulates a command that can be invoked from the console
|
||||||
|
@ -564,14 +563,16 @@ namespace OpenSim.Framework.Console
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A console that processes commands internally
|
/// A console that processes commands internally
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class CommandConsole : ConsoleBase
|
public class CommandConsole : ConsoleBase, ICommandConsole
|
||||||
{
|
{
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
public Commands Commands = new Commands();
|
public ICommands Commands { get; private set; }
|
||||||
|
|
||||||
public CommandConsole(string defaultPrompt) : base(defaultPrompt)
|
public CommandConsole(string defaultPrompt) : base(defaultPrompt)
|
||||||
{
|
{
|
||||||
|
Commands = new Commands();
|
||||||
|
|
||||||
Commands.AddCommand("console", false, "help", "help [<command>]",
|
Commands.AddCommand("console", false, "help", "help [<command>]",
|
||||||
"Get general command list or more detailed help on a specific command", Help);
|
"Get general command list or more detailed help on a specific command", Help);
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ namespace OpenSim.Framework.Console
|
||||||
|
|
||||||
protected string prompt = "# ";
|
protected string prompt = "# ";
|
||||||
|
|
||||||
public object ConsoleScene = null;
|
public object ConsoleScene { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The default prompt text.
|
/// The default prompt text.
|
||||||
|
|
|
@ -703,6 +703,12 @@ namespace OpenSim.Framework
|
||||||
|
|
||||||
UUID AgentId { get; }
|
UUID AgentId { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 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; }
|
||||||
|
|
||||||
UUID SessionId { get; }
|
UUID SessionId { get; }
|
||||||
|
|
||||||
UUID SecureSessionId { get; }
|
UUID SecureSessionId { get; }
|
||||||
|
@ -1011,7 +1017,7 @@ namespace OpenSim.Framework
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Set the debug level at which packet output should be printed to console.
|
/// Set the debug level at which packet output should be printed to console.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void SetDebugPacketLevel(int newDebug);
|
int DebugPacketLevel { get; set; }
|
||||||
|
|
||||||
void InPacket(object NewPack);
|
void InPacket(object NewPack);
|
||||||
void ProcessInPacket(Packet NewPack);
|
void ProcessInPacket(Packet NewPack);
|
||||||
|
@ -1096,7 +1102,14 @@ namespace OpenSim.Framework
|
||||||
void SetChildAgentThrottle(byte[] throttle);
|
void SetChildAgentThrottle(byte[] throttle);
|
||||||
|
|
||||||
void SendAvatarDataImmediate(ISceneEntity avatar);
|
void SendAvatarDataImmediate(ISceneEntity avatar);
|
||||||
void SendPrimUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags);
|
|
||||||
|
/// <summary>
|
||||||
|
/// Send a positional, velocity, etc. update to the viewer for a given entity.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="entity"></param>
|
||||||
|
/// <param name="updateFlags"></param>
|
||||||
|
void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags);
|
||||||
|
|
||||||
void ReprioritizeUpdates();
|
void ReprioritizeUpdates();
|
||||||
void FlushPrimUpdates();
|
void FlushPrimUpdates();
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
/*
|
||||||
|
* 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.Xml;
|
||||||
|
|
||||||
|
namespace OpenSim.Framework
|
||||||
|
{
|
||||||
|
public delegate void CommandDelegate(string module, string[] cmd);
|
||||||
|
|
||||||
|
public interface ICommands
|
||||||
|
{
|
||||||
|
void FromXml(XmlElement root, CommandDelegate fn);
|
||||||
|
|
||||||
|
/// <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>
|
||||||
|
/// <returns></returns>
|
||||||
|
List<string> GetHelp(string[] cmd);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Add a command to those which can be invoked from the console.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="module"></param>
|
||||||
|
/// <param name="command"></param>
|
||||||
|
/// <param name="help"></param>
|
||||||
|
/// <param name="longhelp"></param>
|
||||||
|
/// <param name="fn"></param>
|
||||||
|
void AddCommand(string module, bool shared, string command, string help, string longhelp, CommandDelegate fn);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Add a command to those which can be invoked from the console.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="module"></param>
|
||||||
|
/// <param name="command"></param>
|
||||||
|
/// <param name="help"></param>
|
||||||
|
/// <param name="longhelp"></param>
|
||||||
|
/// <param name="descriptivehelp"></param>
|
||||||
|
/// <param name="fn"></param>
|
||||||
|
void AddCommand(string module, bool shared, string command,
|
||||||
|
string help, string longhelp, string descriptivehelp,
|
||||||
|
CommandDelegate fn);
|
||||||
|
|
||||||
|
string[] FindNextOption(string[] cmd, bool term);
|
||||||
|
|
||||||
|
string[] Resolve(string[] cmd);
|
||||||
|
|
||||||
|
XmlElement GetXml(XmlDocument doc);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface ICommandConsole : IConsole
|
||||||
|
{
|
||||||
|
ICommands Commands { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Display a command prompt on the console and wait for user input
|
||||||
|
/// </summary>
|
||||||
|
void Prompt();
|
||||||
|
|
||||||
|
void RunCommand(string cmd);
|
||||||
|
|
||||||
|
string ReadLine(string p, bool isCommand, bool e);
|
||||||
|
}
|
||||||
|
}
|
|
@ -25,27 +25,29 @@
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System.IO;
|
using System;
|
||||||
using OpenMetaverse;
|
using System.Collections.Generic;
|
||||||
using OpenSim.Framework;
|
|
||||||
using OpenSim.Region.Framework.Scenes;
|
|
||||||
|
|
||||||
namespace OpenSim.Region.Examples.SimpleModule
|
namespace OpenSim.Framework
|
||||||
{
|
{
|
||||||
public class FileSystemObject : SceneObjectGroup
|
public interface IConsole
|
||||||
{
|
{
|
||||||
public FileSystemObject(FileInfo fileInfo, Vector3 pos)
|
object ConsoleScene { get; }
|
||||||
: base(UUID.Zero, pos, PrimitiveBaseShape.Default)
|
|
||||||
{
|
|
||||||
Text = fileInfo.Name;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override bool InSceneBackup
|
void Output(string text, string level);
|
||||||
{
|
void Output(string text);
|
||||||
get
|
void OutputFormat(string format, params object[] components);
|
||||||
{
|
|
||||||
return false;
|
string CmdPrompt(string p);
|
||||||
}
|
string CmdPrompt(string p, string def);
|
||||||
}
|
string CmdPrompt(string p, List<char> excludedCharacters);
|
||||||
|
string CmdPrompt(string p, string def, List<char> excludedCharacters);
|
||||||
|
|
||||||
|
// Displays a command prompt and returns a default value, user may only enter 1 of 2 options
|
||||||
|
string CmdPrompt(string prompt, string defaultresponse, List<string> options);
|
||||||
|
|
||||||
|
// Displays a prompt and waits for the user to enter a string, then returns that string
|
||||||
|
// (Done with no echo and suitable for passwords)
|
||||||
|
string PasswdPrompt(string p);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -26,22 +26,19 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
using OpenSim.Framework.Console;
|
//using OpenSim.Framework.Console;
|
||||||
using Nini.Config;
|
using Nini.Config;
|
||||||
|
|
||||||
namespace OpenSim.Framework
|
namespace OpenSim.Framework
|
||||||
{
|
{
|
||||||
public delegate void restart(RegionInfo thisRegion);
|
public delegate void restart(RegionInfo thisRegion);
|
||||||
|
|
||||||
//public delegate void regionup (RegionInfo thisRegion);
|
|
||||||
|
|
||||||
public enum RegionStatus : int
|
public enum RegionStatus : int
|
||||||
{
|
{
|
||||||
Down = 0,
|
Down = 0,
|
||||||
Up = 1,
|
Up = 1,
|
||||||
Crashed = 2,
|
Crashed = 2,
|
||||||
Starting = 3,
|
Starting = 3,
|
||||||
SlaveScene = 4
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// <value>
|
/// <value>
|
||||||
|
@ -71,12 +68,14 @@ namespace OpenSim.Framework
|
||||||
event restart OnRestart;
|
event restart OnRestart;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Register the new client with the scene. The client starts off as a child agent - the later agent crossing
|
/// Add a new client and create a presence for it. All clients except initial login clients will starts off as a child agent
|
||||||
/// will promote it to a root agent.
|
/// - the later agent crossing will promote it to a root agent.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="client"></param>
|
/// <param name="client"></param>
|
||||||
/// <param name="type">The type of agent to add.</param>
|
/// <param name="type">The type of agent to add.</param>
|
||||||
void AddNewClient(IClientAPI client, PresenceType type);
|
/// <returns>
|
||||||
|
/// The scene agent if the new client was added or if an agent that already existed.</returns>
|
||||||
|
ISceneAgent AddNewClient(IClientAPI client, PresenceType type);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Remove the given client from the scene.
|
/// Remove the given client from the scene.
|
||||||
|
@ -90,28 +89,31 @@ namespace OpenSim.Framework
|
||||||
|
|
||||||
string GetSimulatorVersion();
|
string GetSimulatorVersion();
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Is the agent denoted by the given agentID a child presence in this scene?
|
|
||||||
/// </summary>
|
|
||||||
///
|
|
||||||
/// Used by ClientView when a 'kick everyone' or 'estate message' occurs
|
|
||||||
///
|
|
||||||
/// <param name="avatarID">AvatarID to lookup</param>
|
|
||||||
/// <returns>true if the presence is a child agent, false if the presence is a root exception</returns>
|
|
||||||
/// <exception cref="System.NullReferenceException">
|
|
||||||
/// Thrown if the agent does not exist.
|
|
||||||
/// </exception>
|
|
||||||
bool PresenceChildStatus(UUID agentId);
|
|
||||||
|
|
||||||
bool TryGetScenePresence(UUID agentID, out object scenePresence);
|
bool TryGetScenePresence(UUID agentID, out object scenePresence);
|
||||||
|
|
||||||
T RequestModuleInterface<T>();
|
/// <summary>
|
||||||
T[] RequestModuleInterfaces<T>();
|
/// Register an interface to a region module. This allows module methods to be called directly as
|
||||||
|
/// well as via events. If there is already a module registered for this interface, it is not replaced
|
||||||
|
/// (is this the best behaviour?)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="mod"></param>
|
||||||
void RegisterModuleInterface<M>(M mod);
|
void RegisterModuleInterface<M>(M mod);
|
||||||
|
|
||||||
void StackModuleInterface<M>(M mod);
|
void StackModuleInterface<M>(M mod);
|
||||||
|
|
||||||
void AddCommand(object module, string command, string shorthelp, string longhelp, CommandDelegate callback);
|
/// <summary>
|
||||||
|
/// For the given interface, retrieve the region module which implements it.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>null if there is no registered module implementing that interface</returns>
|
||||||
|
T RequestModuleInterface<T>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// For the given interface, retrieve an array of region modules that implement it.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>an empty array if there are no registered modules implementing that interface</returns>
|
||||||
|
T[] RequestModuleInterfaces<T>();
|
||||||
|
|
||||||
|
// void AddCommand(object module, string command, string shorthelp, string longhelp, CommandDelegate callback);
|
||||||
|
|
||||||
ISceneObject DeserializeObject(string representation);
|
ISceneObject DeserializeObject(string representation);
|
||||||
|
|
||||||
|
|
|
@ -25,44 +25,51 @@
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System;
|
||||||
using OpenMetaverse;
|
|
||||||
|
|
||||||
namespace OpenSim.Framework
|
namespace OpenSim.Framework
|
||||||
{
|
{
|
||||||
public delegate void ExpectUserDelegate(AgentCircuitData agent);
|
/// <summary>
|
||||||
|
/// An agent in the scene.
|
||||||
|
/// </summary>
|
||||||
public delegate void UpdateNeighbours(List<RegionInfo> neighbours);
|
/// <remarks>
|
||||||
|
/// Interface is a work in progress. Please feel free to add other required properties and methods.
|
||||||
public delegate void AgentCrossing(UUID agentID, Vector3 position, bool isFlying);
|
/// </remarks>
|
||||||
|
public interface ISceneAgent : ISceneEntity
|
||||||
public delegate void PrimCrossing(UUID primID, Vector3 position, bool isPhysical);
|
|
||||||
|
|
||||||
public delegate void AcknowledgeAgentCross(UUID agentID);
|
|
||||||
|
|
||||||
public delegate void AcknowledgePrimCross(UUID PrimID);
|
|
||||||
|
|
||||||
public delegate bool CloseAgentConnection(UUID agentID);
|
|
||||||
|
|
||||||
public delegate bool ChildAgentUpdate(ChildAgentDataUpdate cAgentData);
|
|
||||||
|
|
||||||
public delegate void LogOffUser(UUID agentID, UUID regionSecret, string message);
|
|
||||||
|
|
||||||
public delegate LandData GetLandData(uint x, uint y);
|
|
||||||
|
|
||||||
public interface IRegionCommsListener
|
|
||||||
{
|
{
|
||||||
event ExpectUserDelegate OnExpectUser;
|
/// <value>
|
||||||
event GenericCall2 OnExpectChildAgent;
|
/// The client controlling this presence
|
||||||
event AgentCrossing OnAvatarCrossingIntoRegion;
|
/// </value>
|
||||||
event PrimCrossing OnPrimCrossingIntoRegion;
|
IClientAPI ControllingClient { get; }
|
||||||
event AcknowledgeAgentCross OnAcknowledgeAgentCrossed;
|
|
||||||
event AcknowledgePrimCross OnAcknowledgePrimCrossed;
|
/// <summary>
|
||||||
event UpdateNeighbours OnNeighboursUpdate;
|
/// What type of presence is this? User, NPC, etc.
|
||||||
event CloseAgentConnection OnCloseAgentConnection;
|
/// </summary>
|
||||||
event ChildAgentUpdate OnChildAgentUpdate;
|
PresenceType PresenceType { get; }
|
||||||
event LogOffUser OnLogOffUser;
|
|
||||||
event GetLandData OnGetLandData;
|
/// <summary>
|
||||||
|
/// If true, then the agent has no avatar in the scene.
|
||||||
|
/// The agent exists to relay data from a region that neighbours the current position of the user's avatar.
|
||||||
|
/// Occasionally data is relayed, such as which a user clicks an item in a neighbouring region.
|
||||||
|
/// </summary>
|
||||||
|
bool IsChildAgent { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Avatar appearance data.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
// Because appearance setting is in a module, we actually need
|
||||||
|
// to give it access to our appearance directly, otherwise we
|
||||||
|
// get a synchronization issue.
|
||||||
|
/// </remarks>
|
||||||
|
AvatarAppearance Appearance { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Send initial scene data to the client controlling this agent
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This includes scene object data and the appearance data of other avatars.
|
||||||
|
/// </remarks>
|
||||||
|
void SendInitialDataToMe();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -34,6 +34,7 @@ namespace OpenSim.Framework
|
||||||
string Name { get; set; }
|
string Name { get; set; }
|
||||||
UUID UUID { get; }
|
UUID UUID { get; }
|
||||||
uint LocalId { get; }
|
uint LocalId { get; }
|
||||||
|
|
||||||
Vector3 AbsolutePosition { get; }
|
Vector3 AbsolutePosition { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,12 @@ namespace OpenSim.Framework
|
||||||
public interface ISceneObject
|
public interface ISceneObject
|
||||||
{
|
{
|
||||||
UUID UUID { get; }
|
UUID UUID { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The owner of this object.
|
||||||
|
/// </summary>
|
||||||
|
UUID OwnerID { get; set; }
|
||||||
|
|
||||||
ISceneObject CloneForNewScene();
|
ISceneObject CloneForNewScene();
|
||||||
string ToXml2();
|
string ToXml2();
|
||||||
string ExtraToXmlString();
|
string ExtraToXmlString();
|
||||||
|
|
|
@ -25,13 +25,13 @@
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace OpenSim.Framework.Console
|
namespace OpenSim.Framework
|
||||||
{
|
{
|
||||||
public class MainConsole
|
public class MainConsole
|
||||||
{
|
{
|
||||||
private static CommandConsole instance;
|
private static ICommandConsole instance;
|
||||||
|
|
||||||
public static CommandConsole Instance
|
public static ICommandConsole Instance
|
||||||
{
|
{
|
||||||
get { return instance; }
|
get { return instance; }
|
||||||
set { instance = value; }
|
set { instance = value; }
|
|
@ -32,19 +32,9 @@ namespace OpenSim.Framework
|
||||||
{
|
{
|
||||||
public class NetworkServersInfo
|
public class NetworkServersInfo
|
||||||
{
|
{
|
||||||
public string AssetSendKey = String.Empty;
|
|
||||||
public string AssetURL = "http://127.0.0.1:" + ConfigSettings.DefaultAssetServerHttpPort.ToString() + "/";
|
|
||||||
|
|
||||||
public string GridRecvKey = String.Empty;
|
|
||||||
public string GridSendKey = String.Empty;
|
|
||||||
public string GridURL = String.Empty;
|
|
||||||
public uint HttpListenerPort = ConfigSettings.DefaultRegionHttpPort;
|
public uint HttpListenerPort = ConfigSettings.DefaultRegionHttpPort;
|
||||||
public string InventoryURL = String.Empty;
|
|
||||||
public bool secureInventoryServer = false;
|
public bool secureInventoryServer = false;
|
||||||
public bool isSandbox;
|
public bool isSandbox;
|
||||||
public string UserRecvKey = String.Empty;
|
|
||||||
public string UserSendKey = String.Empty;
|
|
||||||
public string UserURL = String.Empty;
|
|
||||||
public bool HttpUsesSSL = false;
|
public bool HttpUsesSSL = false;
|
||||||
public string HttpSSLCN = "";
|
public string HttpSSLCN = "";
|
||||||
public uint httpSSLPort = 9001;
|
public uint httpSSLPort = 9001;
|
||||||
|
@ -55,8 +45,6 @@ namespace OpenSim.Framework
|
||||||
public string cert_path = String.Empty;
|
public string cert_path = String.Empty;
|
||||||
public string cert_pass = String.Empty;
|
public string cert_pass = String.Empty;
|
||||||
|
|
||||||
public string MessagingURL = String.Empty;
|
|
||||||
|
|
||||||
public NetworkServersInfo()
|
public NetworkServersInfo()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -65,33 +53,14 @@ namespace OpenSim.Framework
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void loadFromConfiguration(IConfigSource config)
|
public void loadFromConfiguration(IConfigSource config)
|
||||||
{
|
{
|
||||||
|
|
||||||
HttpListenerPort =
|
HttpListenerPort =
|
||||||
(uint) config.Configs["Network"].GetInt("http_listener_port", (int) ConfigSettings.DefaultRegionHttpPort);
|
(uint) config.Configs["Network"].GetInt("http_listener_port", (int) ConfigSettings.DefaultRegionHttpPort);
|
||||||
httpSSLPort =
|
httpSSLPort =
|
||||||
(uint)config.Configs["Network"].GetInt("http_listener_sslport", ((int)ConfigSettings.DefaultRegionHttpPort+1));
|
(uint)config.Configs["Network"].GetInt("http_listener_sslport", ((int)ConfigSettings.DefaultRegionHttpPort+1));
|
||||||
HttpUsesSSL = config.Configs["Network"].GetBoolean("http_listener_ssl", false);
|
HttpUsesSSL = config.Configs["Network"].GetBoolean("http_listener_ssl", false);
|
||||||
HttpSSLCN = config.Configs["Network"].GetString("http_listener_cn", "localhost");
|
HttpSSLCN = config.Configs["Network"].GetString("http_listener_cn", "localhost");
|
||||||
GridURL =
|
|
||||||
config.Configs["Network"].GetString("grid_server_url",
|
|
||||||
"http://127.0.0.1:" + ConfigSettings.DefaultGridServerHttpPort.ToString());
|
|
||||||
GridSendKey = config.Configs["Network"].GetString("grid_send_key", "null");
|
|
||||||
GridRecvKey = config.Configs["Network"].GetString("grid_recv_key", "null");
|
|
||||||
UserURL =
|
|
||||||
config.Configs["Network"].GetString("user_server_url",
|
|
||||||
"http://127.0.0.1:" + ConfigSettings.DefaultUserServerHttpPort.ToString());
|
|
||||||
UserSendKey = config.Configs["Network"].GetString("user_send_key", "null");
|
|
||||||
UserRecvKey = config.Configs["Network"].GetString("user_recv_key", "null");
|
|
||||||
AssetURL = config.Configs["Network"].GetString("asset_server_url", AssetURL);
|
|
||||||
InventoryURL = config.Configs["Network"].GetString("inventory_server_url",
|
|
||||||
"http://127.0.0.1:" +
|
|
||||||
ConfigSettings.DefaultInventoryServerHttpPort.ToString());
|
|
||||||
secureInventoryServer = config.Configs["Network"].GetBoolean("secure_inventory_server", true);
|
|
||||||
|
|
||||||
MessagingURL = config.Configs["Network"].GetString("messaging_server_url", string.Empty);
|
|
||||||
|
|
||||||
// "Out of band management https"
|
// "Out of band management https"
|
||||||
ssl_listener = config.Configs["Network"].GetBoolean("https_listener",false);
|
ssl_listener = config.Configs["Network"].GetBoolean("https_listener",false);
|
||||||
|
|
|
@ -1,204 +0,0 @@
|
||||||
/*
|
|
||||||
* 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 OpenMetaverse;
|
|
||||||
|
|
||||||
namespace OpenSim.Framework
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Sandbox mode region comms listener. There is one of these per region
|
|
||||||
/// </summary>
|
|
||||||
public class RegionCommsListener : IRegionCommsListener
|
|
||||||
{
|
|
||||||
public string debugRegionName = String.Empty;
|
|
||||||
private AcknowledgeAgentCross handlerAcknowledgeAgentCrossed = null; // OnAcknowledgeAgentCrossed;
|
|
||||||
private AcknowledgePrimCross handlerAcknowledgePrimCrossed = null; // OnAcknowledgePrimCrossed;
|
|
||||||
private AgentCrossing handlerAvatarCrossingIntoRegion = null; // OnAvatarCrossingIntoRegion;
|
|
||||||
private ChildAgentUpdate handlerChildAgentUpdate = null; // OnChildAgentUpdate;
|
|
||||||
private CloseAgentConnection handlerCloseAgentConnection = null; // OnCloseAgentConnection;
|
|
||||||
private GenericCall2 handlerExpectChildAgent = null; // OnExpectChildAgent;
|
|
||||||
private ExpectUserDelegate handlerExpectUser = null; // OnExpectUser
|
|
||||||
private UpdateNeighbours handlerNeighboursUpdate = null; // OnNeighboursUpdate;
|
|
||||||
// private PrimCrossing handlerPrimCrossingIntoRegion = null; // OnPrimCrossingIntoRegion;
|
|
||||||
private LogOffUser handlerLogOffUser = null;
|
|
||||||
private GetLandData handlerGetLandData = null;
|
|
||||||
|
|
||||||
#region IRegionCommsListener Members
|
|
||||||
|
|
||||||
public event ExpectUserDelegate OnExpectUser;
|
|
||||||
public event GenericCall2 OnExpectChildAgent;
|
|
||||||
public event AgentCrossing OnAvatarCrossingIntoRegion;
|
|
||||||
public event PrimCrossing OnPrimCrossingIntoRegion;
|
|
||||||
public event UpdateNeighbours OnNeighboursUpdate;
|
|
||||||
public event AcknowledgeAgentCross OnAcknowledgeAgentCrossed;
|
|
||||||
public event AcknowledgePrimCross OnAcknowledgePrimCrossed;
|
|
||||||
public event CloseAgentConnection OnCloseAgentConnection;
|
|
||||||
public event ChildAgentUpdate OnChildAgentUpdate;
|
|
||||||
public event LogOffUser OnLogOffUser;
|
|
||||||
public event GetLandData OnGetLandData;
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="agent"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public virtual bool TriggerExpectUser(AgentCircuitData agent)
|
|
||||||
{
|
|
||||||
handlerExpectUser = OnExpectUser;
|
|
||||||
if (handlerExpectUser != null)
|
|
||||||
{
|
|
||||||
handlerExpectUser(agent);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// From User Server
|
|
||||||
public virtual void TriggerLogOffUser(UUID agentID, UUID RegionSecret, string message)
|
|
||||||
{
|
|
||||||
handlerLogOffUser = OnLogOffUser;
|
|
||||||
if (handlerLogOffUser != null)
|
|
||||||
{
|
|
||||||
handlerLogOffUser(agentID, RegionSecret, message);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual bool TriggerChildAgentUpdate(ChildAgentDataUpdate cAgentData)
|
|
||||||
{
|
|
||||||
handlerChildAgentUpdate = OnChildAgentUpdate;
|
|
||||||
if (handlerChildAgentUpdate != null)
|
|
||||||
{
|
|
||||||
handlerChildAgentUpdate(cAgentData);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual bool TriggerExpectAvatarCrossing(UUID agentID, Vector3 position, bool isFlying)
|
|
||||||
{
|
|
||||||
handlerAvatarCrossingIntoRegion = OnAvatarCrossingIntoRegion;
|
|
||||||
if (handlerAvatarCrossingIntoRegion != null)
|
|
||||||
{
|
|
||||||
handlerAvatarCrossingIntoRegion(agentID, position, isFlying);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual bool TriggerAcknowledgeAgentCrossed(UUID agentID)
|
|
||||||
{
|
|
||||||
handlerAcknowledgeAgentCrossed = OnAcknowledgeAgentCrossed;
|
|
||||||
if (handlerAcknowledgeAgentCrossed != null)
|
|
||||||
{
|
|
||||||
handlerAcknowledgeAgentCrossed(agentID);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual bool TriggerAcknowledgePrimCrossed(UUID primID)
|
|
||||||
{
|
|
||||||
handlerAcknowledgePrimCrossed = OnAcknowledgePrimCrossed;
|
|
||||||
if (handlerAcknowledgePrimCrossed != null)
|
|
||||||
{
|
|
||||||
handlerAcknowledgePrimCrossed(primID);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual bool TriggerCloseAgentConnection(UUID agentID)
|
|
||||||
{
|
|
||||||
handlerCloseAgentConnection = OnCloseAgentConnection;
|
|
||||||
if (handlerCloseAgentConnection != null)
|
|
||||||
{
|
|
||||||
handlerCloseAgentConnection(agentID);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>TODO: Doesnt take any args??</remarks>
|
|
||||||
/// <returns></returns>
|
|
||||||
public virtual bool TriggerExpectChildAgent()
|
|
||||||
{
|
|
||||||
handlerExpectChildAgent = OnExpectChildAgent;
|
|
||||||
if (handlerExpectChildAgent != null)
|
|
||||||
{
|
|
||||||
handlerExpectChildAgent();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>Added to avoid a unused compiler warning on OnNeighboursUpdate, TODO: Check me</remarks>
|
|
||||||
/// <param name="neighbours"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public virtual bool TriggerOnNeighboursUpdate(List<RegionInfo> neighbours)
|
|
||||||
{
|
|
||||||
handlerNeighboursUpdate = OnNeighboursUpdate;
|
|
||||||
if (handlerNeighboursUpdate != null)
|
|
||||||
{
|
|
||||||
handlerNeighboursUpdate(neighbours);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool TriggerTellRegionToCloseChildConnection(UUID agentID)
|
|
||||||
{
|
|
||||||
handlerCloseAgentConnection = OnCloseAgentConnection;
|
|
||||||
if (handlerCloseAgentConnection != null)
|
|
||||||
return handlerCloseAgentConnection(agentID);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LandData TriggerGetLandData(uint x, uint y)
|
|
||||||
{
|
|
||||||
handlerGetLandData = OnGetLandData;
|
|
||||||
if (handlerGetLandData != null)
|
|
||||||
return handlerGetLandData(x, y);
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -36,7 +36,7 @@ using log4net;
|
||||||
using Nini.Config;
|
using Nini.Config;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
using OpenMetaverse.StructuredData;
|
using OpenMetaverse.StructuredData;
|
||||||
using OpenSim.Framework.Console;
|
//using OpenSim.Framework.Console;
|
||||||
|
|
||||||
namespace OpenSim.Framework
|
namespace OpenSim.Framework
|
||||||
{
|
{
|
||||||
|
|
|
@ -192,6 +192,15 @@ namespace OpenSim.Framework.Servers
|
||||||
m_console.Commands.AddCommand("base", false, "show version",
|
m_console.Commands.AddCommand("base", false, "show version",
|
||||||
"show version",
|
"show version",
|
||||||
"Show server version", HandleShow);
|
"Show server version", HandleShow);
|
||||||
|
|
||||||
|
m_console.Commands.AddCommand("base", 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",
|
||||||
|
"threads show",
|
||||||
|
"Show thread status. Synonym for \"show threads\"",
|
||||||
|
(string module, string[] args) => Notice(GetThreadsReport()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,17 +243,28 @@ namespace OpenSim.Framework.Servers
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected string GetThreadsReport()
|
protected string GetThreadsReport()
|
||||||
{
|
{
|
||||||
|
// This should be a constant field.
|
||||||
|
string reportFormat = "{0,6} {1,35} {2,16} {3,10} {4,30}";
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
Watchdog.ThreadWatchdogInfo[] threads = Watchdog.GetThreads();
|
Watchdog.ThreadWatchdogInfo[] threads = Watchdog.GetThreads();
|
||||||
|
|
||||||
sb.Append(threads.Length + " threads are being tracked:" + Environment.NewLine);
|
sb.Append(threads.Length + " threads are being tracked:" + Environment.NewLine);
|
||||||
|
|
||||||
|
int timeNow = Environment.TickCount & Int32.MaxValue;
|
||||||
|
|
||||||
|
sb.AppendFormat(reportFormat, "ID", "NAME", "LAST UPDATE (MS)", "PRIORITY", "STATE");
|
||||||
|
sb.Append(Environment.NewLine);
|
||||||
|
|
||||||
foreach (Watchdog.ThreadWatchdogInfo twi in threads)
|
foreach (Watchdog.ThreadWatchdogInfo twi in threads)
|
||||||
{
|
{
|
||||||
Thread t = twi.Thread;
|
Thread t = twi.Thread;
|
||||||
|
|
||||||
sb.Append(
|
sb.AppendFormat(
|
||||||
"ID: " + t.ManagedThreadId + ", Name: " + t.Name + ", TimeRunning: "
|
reportFormat,
|
||||||
+ "Pri: " + t.Priority + ", State: " + t.ThreadState);
|
//t.ManagedThreadId, t.Name, string.Format("{0} ms", timeNow - twi.LastTick), t.Priority, t.ThreadState);
|
||||||
|
t.ManagedThreadId, t.Name, timeNow - twi.LastTick, t.Priority, t.ThreadState);
|
||||||
|
|
||||||
sb.Append(Environment.NewLine);
|
sb.Append(Environment.NewLine);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -396,6 +416,27 @@ namespace OpenSim.Framework.Servers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual void HandleThreadsAbort(string module, string[] cmd)
|
||||||
|
{
|
||||||
|
if (cmd.Length != 3)
|
||||||
|
{
|
||||||
|
MainConsole.Instance.Output("Usage: threads abort <thread-id>");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int threadId;
|
||||||
|
if (!int.TryParse(cmd[2], out threadId))
|
||||||
|
{
|
||||||
|
MainConsole.Instance.Output("ERROR: Thread id must be an integer");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Watchdog.AbortThread(threadId))
|
||||||
|
MainConsole.Instance.OutputFormat("Aborted thread with id {0}", threadId);
|
||||||
|
else
|
||||||
|
MainConsole.Instance.OutputFormat("ERROR - Thread with id {0} not found in managed threads", threadId);
|
||||||
|
}
|
||||||
|
|
||||||
protected void ShowInfo()
|
protected void ShowInfo()
|
||||||
{
|
{
|
||||||
Notice(GetVersionText());
|
Notice(GetVersionText());
|
||||||
|
|
|
@ -79,6 +79,11 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
|
|
||||||
private PollServiceRequestManager m_PollServiceManager;
|
private PollServiceRequestManager m_PollServiceManager;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Control the printing of certain debug messages.
|
||||||
|
/// </summary>
|
||||||
|
public int DebugLevel { get; set; }
|
||||||
|
|
||||||
public uint SSLPort
|
public uint SSLPort
|
||||||
{
|
{
|
||||||
get { return m_sslport; }
|
get { return m_sslport; }
|
||||||
|
@ -442,17 +447,18 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
string path = request.RawUrl;
|
string path = request.RawUrl;
|
||||||
string handlerKey = GetHandlerKey(request.HttpMethod, path);
|
string handlerKey = GetHandlerKey(request.HttpMethod, path);
|
||||||
|
|
||||||
//m_log.DebugFormat("[BASE HTTP SERVER]: Handling {0} request for {1}", request.HttpMethod, path);
|
|
||||||
|
|
||||||
if (TryGetStreamHandler(handlerKey, out requestHandler))
|
if (TryGetStreamHandler(handlerKey, out requestHandler))
|
||||||
{
|
{
|
||||||
//m_log.Debug("[BASE HTTP SERVER]: Found Stream Handler");
|
if (DebugLevel >= 1)
|
||||||
|
m_log.DebugFormat(
|
||||||
|
"[BASE HTTP SERVER]: Found stream handler for {0} {1}",
|
||||||
|
request.HttpMethod, request.Url.PathAndQuery);
|
||||||
|
|
||||||
// Okay, so this is bad, but should be considered temporary until everything is IStreamHandler.
|
// Okay, so this is bad, but should be considered temporary until everything is IStreamHandler.
|
||||||
byte[] buffer = null;
|
byte[] buffer = null;
|
||||||
|
|
||||||
response.ContentType = requestHandler.ContentType; // Lets do this defaulting before in case handler has varying content type.
|
response.ContentType = requestHandler.ContentType; // Lets do this defaulting before in case handler has varying content type.
|
||||||
|
|
||||||
|
|
||||||
if (requestHandler is IStreamedRequestHandler)
|
if (requestHandler is IStreamedRequestHandler)
|
||||||
{
|
{
|
||||||
IStreamedRequestHandler streamedRequestHandler = requestHandler as IStreamedRequestHandler;
|
IStreamedRequestHandler streamedRequestHandler = requestHandler as IStreamedRequestHandler;
|
||||||
|
@ -480,7 +486,6 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
string[] querystringkeys = request.QueryString.AllKeys;
|
string[] querystringkeys = request.QueryString.AllKeys;
|
||||||
string[] rHeaders = request.Headers.AllKeys;
|
string[] rHeaders = request.Headers.AllKeys;
|
||||||
|
|
||||||
|
|
||||||
foreach (string queryname in querystringkeys)
|
foreach (string queryname in querystringkeys)
|
||||||
{
|
{
|
||||||
keysvals.Add(queryname, request.QueryString[queryname]);
|
keysvals.Add(queryname, request.QueryString[queryname]);
|
||||||
|
@ -556,6 +561,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
{
|
{
|
||||||
m_log.Warn("[BASE HTTP SERVER]: XmlRpcRequest issue: " + e.Message);
|
m_log.Warn("[BASE HTTP SERVER]: XmlRpcRequest issue: " + e.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -566,7 +572,11 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
if (strAccept.Contains("application/llsd+xml") ||
|
if (strAccept.Contains("application/llsd+xml") ||
|
||||||
strAccept.Contains("application/llsd+json"))
|
strAccept.Contains("application/llsd+json"))
|
||||||
{
|
{
|
||||||
//m_log.Info("[Debug BASE HTTP SERVER]: Found an application/llsd+xml accept header");
|
if (DebugLevel >= 1)
|
||||||
|
m_log.DebugFormat(
|
||||||
|
"[BASE HTTP SERVER]: Found application/llsd+xml accept header handler for {0} {1}",
|
||||||
|
request.HttpMethod, request.Url.PathAndQuery);
|
||||||
|
|
||||||
HandleLLSDRequests(request, response);
|
HandleLLSDRequests(request, response);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -577,15 +587,24 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
{
|
{
|
||||||
case null:
|
case null:
|
||||||
case "text/html":
|
case "text/html":
|
||||||
// m_log.DebugFormat(
|
|
||||||
// "[BASE HTTP SERVER]: Found a text/html content type for request {0}", request.RawUrl);
|
if (DebugLevel >= 1)
|
||||||
|
m_log.DebugFormat(
|
||||||
|
"[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}",
|
||||||
|
request.ContentType, request.HttpMethod, request.Url.PathAndQuery);
|
||||||
|
|
||||||
HandleHTTPRequest(request, response);
|
HandleHTTPRequest(request, response);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case "application/llsd+xml":
|
case "application/llsd+xml":
|
||||||
case "application/xml+llsd":
|
case "application/xml+llsd":
|
||||||
case "application/llsd+json":
|
case "application/llsd+json":
|
||||||
//m_log.Info("[Debug BASE HTTP SERVER]: found a application/llsd+xml content type");
|
|
||||||
|
if (DebugLevel >= 1)
|
||||||
|
m_log.DebugFormat(
|
||||||
|
"[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}",
|
||||||
|
request.ContentType, request.HttpMethod, request.Url.PathAndQuery);
|
||||||
|
|
||||||
HandleLLSDRequests(request, response);
|
HandleLLSDRequests(request, response);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -602,7 +621,11 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
//m_log.Info("[Debug BASE HTTP SERVER]: Checking for LLSD Handler");
|
//m_log.Info("[Debug BASE HTTP SERVER]: Checking for LLSD Handler");
|
||||||
if (DoWeHaveALLSDHandler(request.RawUrl))
|
if (DoWeHaveALLSDHandler(request.RawUrl))
|
||||||
{
|
{
|
||||||
//m_log.Info("[Debug BASE HTTP SERVER]: Found LLSD Handler");
|
if (DebugLevel >= 1)
|
||||||
|
m_log.DebugFormat(
|
||||||
|
"[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}",
|
||||||
|
request.ContentType, request.HttpMethod, request.Url.PathAndQuery);
|
||||||
|
|
||||||
HandleLLSDRequests(request, response);
|
HandleLLSDRequests(request, response);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -610,12 +633,20 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
// m_log.DebugFormat("[BASE HTTP SERVER]: Checking for HTTP Handler for request {0}", request.RawUrl);
|
// m_log.DebugFormat("[BASE HTTP SERVER]: Checking for HTTP Handler for request {0}", request.RawUrl);
|
||||||
if (DoWeHaveAHTTPHandler(request.RawUrl))
|
if (DoWeHaveAHTTPHandler(request.RawUrl))
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat("[BASE HTTP SERVER]: Found HTTP Handler for request {0}", request.RawUrl);
|
if (DebugLevel >= 1)
|
||||||
|
m_log.DebugFormat(
|
||||||
|
"[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}",
|
||||||
|
request.ContentType, request.HttpMethod, request.Url.PathAndQuery);
|
||||||
|
|
||||||
HandleHTTPRequest(request, response);
|
HandleHTTPRequest(request, response);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//m_log.Info("[Debug BASE HTTP SERVER]: Generic XMLRPC");
|
if (DebugLevel >= 1)
|
||||||
|
m_log.DebugFormat(
|
||||||
|
"[BASE HTTP SERVER]: Assuming a generic XMLRPC request for {0} {1}",
|
||||||
|
request.HttpMethod, request.Url.PathAndQuery);
|
||||||
|
|
||||||
// generic login request.
|
// generic login request.
|
||||||
HandleXmlRpcRequests(request, response);
|
HandleXmlRpcRequests(request, response);
|
||||||
|
|
||||||
|
@ -872,7 +903,9 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
byte[] buf = Encoding.UTF8.GetBytes("Not found");
|
byte[] buf = Encoding.UTF8.GetBytes("Not found");
|
||||||
response.KeepAlive = false;
|
response.KeepAlive = false;
|
||||||
|
|
||||||
m_log.ErrorFormat("[BASE HTTP SERVER]: Handler not found for http request {0}", request.RawUrl);
|
m_log.ErrorFormat(
|
||||||
|
"[BASE HTTP SERVER]: Handler not found for http request {0} {1}",
|
||||||
|
request.HttpMethod, request.Url.PathAndQuery);
|
||||||
|
|
||||||
response.SendChunked = false;
|
response.SendChunked = false;
|
||||||
response.ContentLength64 = buf.Length;
|
response.ContentLength64 = buf.Length;
|
||||||
|
@ -978,7 +1011,6 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
|
|
||||||
if (llsdRequest != null)// && m_defaultLlsdHandler != null)
|
if (llsdRequest != null)// && m_defaultLlsdHandler != null)
|
||||||
{
|
{
|
||||||
|
|
||||||
LLSDMethod llsdhandler = null;
|
LLSDMethod llsdhandler = null;
|
||||||
|
|
||||||
if (TryGetLLSDHandler(request.RawUrl, out llsdhandler) && !LegacyLLSDLoginLibOMV)
|
if (TryGetLLSDHandler(request.RawUrl, out llsdhandler) && !LegacyLLSDLoginLibOMV)
|
||||||
|
@ -1002,13 +1034,14 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
llsdResponse = GenerateNoLLSDHandlerResponse();
|
llsdResponse = GenerateNoLLSDHandlerResponse();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
llsdResponse = GenerateNoLLSDHandlerResponse();
|
llsdResponse = GenerateNoLLSDHandlerResponse();
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] buffer = new byte[0];
|
byte[] buffer = new byte[0];
|
||||||
|
|
||||||
if (llsdResponse.ToString() == "shutdown404!")
|
if (llsdResponse.ToString() == "shutdown404!")
|
||||||
{
|
{
|
||||||
response.ContentType = "text/plain";
|
response.ContentType = "text/plain";
|
||||||
|
@ -1814,12 +1847,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
public void RemovePollServiceHTTPHandler(string httpMethod, string path)
|
public void RemovePollServiceHTTPHandler(string httpMethod, string path)
|
||||||
{
|
{
|
||||||
lock (m_pollHandlers)
|
lock (m_pollHandlers)
|
||||||
{
|
m_pollHandlers.Remove(path);
|
||||||
if (m_pollHandlers.ContainsKey(httpMethod))
|
|
||||||
{
|
|
||||||
m_pollHandlers.Remove(httpMethod);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RemoveHTTPHandler(httpMethod, path);
|
RemoveHTTPHandler(httpMethod, path);
|
||||||
}
|
}
|
||||||
|
@ -1843,13 +1871,8 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
public void RemoveXmlRPCHandler(string method)
|
public void RemoveXmlRPCHandler(string method)
|
||||||
{
|
{
|
||||||
lock (m_rpcHandlers)
|
lock (m_rpcHandlers)
|
||||||
{
|
|
||||||
if (m_rpcHandlers.ContainsKey(method))
|
|
||||||
{
|
|
||||||
m_rpcHandlers.Remove(method);
|
m_rpcHandlers.Remove(method);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool RemoveLLSDHandler(string path, LLSDMethod handler)
|
public bool RemoveLLSDHandler(string path, LLSDMethod handler)
|
||||||
{
|
{
|
||||||
|
|
|
@ -49,7 +49,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Add a handler for an HTTP request.
|
/// Add a handler for an HTTP request.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
///
|
/// <remarks>
|
||||||
/// This handler can actually be invoked either as
|
/// This handler can actually be invoked either as
|
||||||
///
|
///
|
||||||
/// http://<hostname>:<port>/?method=<methodName>
|
/// http://<hostname>:<port>/?method=<methodName>
|
||||||
|
@ -70,7 +70,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
/// In addition, the handler invoked by the HTTP server for any request is the one when best matches the request
|
/// In addition, the handler invoked by the HTTP server for any request is the one when best matches the request
|
||||||
/// URI. So if a handler for "/myapp/" is registered and a request for "/myapp/page" is received, then
|
/// URI. So if a handler for "/myapp/" is registered and a request for "/myapp/page" is received, then
|
||||||
/// the "/myapp/" handler is invoked if no "/myapp/page" handler exists.
|
/// the "/myapp/" handler is invoked if no "/myapp/page" handler exists.
|
||||||
///
|
/// </remarks>
|
||||||
/// <param name="methodName"></param>
|
/// <param name="methodName"></param>
|
||||||
/// <param name="handler"></param>
|
/// <param name="handler"></param>
|
||||||
/// <returns>
|
/// <returns>
|
||||||
|
|
|
@ -28,12 +28,17 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
using System.Reflection;
|
||||||
|
using log4net;
|
||||||
using HttpServer;
|
using HttpServer;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
|
||||||
namespace OpenSim.Framework.Servers.HttpServer
|
namespace OpenSim.Framework.Servers.HttpServer
|
||||||
{
|
{
|
||||||
public class PollServiceRequestManager
|
public class PollServiceRequestManager
|
||||||
{
|
{
|
||||||
|
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
private readonly BaseHttpServer m_server;
|
private readonly BaseHttpServer m_server;
|
||||||
private static Queue m_requests = Queue.Synchronized(new Queue());
|
private static Queue m_requests = Queue.Synchronized(new Queue());
|
||||||
private uint m_WorkerThreadCount = 0;
|
private uint m_WorkerThreadCount = 0;
|
||||||
|
@ -42,8 +47,6 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
private Thread m_watcherThread;
|
private Thread m_watcherThread;
|
||||||
private bool m_running = true;
|
private bool m_running = true;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public PollServiceRequestManager(BaseHttpServer pSrv, uint pWorkerThreadCount, int pTimeout)
|
public PollServiceRequestManager(BaseHttpServer pSrv, uint pWorkerThreadCount, int pTimeout)
|
||||||
{
|
{
|
||||||
m_server = pSrv;
|
m_server = pSrv;
|
||||||
|
@ -52,22 +55,27 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
m_PollServiceWorkerThreads = new PollServiceWorkerThread[m_WorkerThreadCount];
|
m_PollServiceWorkerThreads = new PollServiceWorkerThread[m_WorkerThreadCount];
|
||||||
|
|
||||||
//startup worker threads
|
//startup worker threads
|
||||||
for (uint i=0;i<m_WorkerThreadCount;i++)
|
for (uint i = 0; i < m_WorkerThreadCount; i++)
|
||||||
{
|
{
|
||||||
m_PollServiceWorkerThreads[i] = new PollServiceWorkerThread(m_server, pTimeout);
|
m_PollServiceWorkerThreads[i] = new PollServiceWorkerThread(m_server, pTimeout);
|
||||||
m_PollServiceWorkerThreads[i].ReQueue += ReQueueEvent;
|
m_PollServiceWorkerThreads[i].ReQueue += ReQueueEvent;
|
||||||
|
|
||||||
m_workerThreads[i] = new Thread(m_PollServiceWorkerThreads[i].ThreadStart);
|
m_workerThreads[i]
|
||||||
m_workerThreads[i].Name = String.Format("PollServiceWorkerThread{0}",i);
|
= Watchdog.StartThread(
|
||||||
//Can't add to thread Tracker here Referencing OpenSim.Framework creates circular reference
|
m_PollServiceWorkerThreads[i].ThreadStart,
|
||||||
m_workerThreads[i].Start();
|
String.Format("PollServiceWorkerThread{0}", i),
|
||||||
|
ThreadPriority.Normal,
|
||||||
|
false,
|
||||||
|
int.MaxValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
//start watcher threads
|
m_watcherThread
|
||||||
m_watcherThread = new Thread(ThreadStart);
|
= Watchdog.StartThread(
|
||||||
m_watcherThread.Name = "PollServiceWatcherThread";
|
this.ThreadStart,
|
||||||
m_watcherThread.Start();
|
"PollServiceWatcherThread",
|
||||||
|
ThreadPriority.Normal,
|
||||||
|
false,
|
||||||
|
1000 * 60 * 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void ReQueueEvent(PollServiceHttpRequest req)
|
internal void ReQueueEvent(PollServiceHttpRequest req)
|
||||||
|
@ -82,10 +90,11 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
m_requests.Enqueue(req);
|
m_requests.Enqueue(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ThreadStart(object o)
|
public void ThreadStart()
|
||||||
{
|
{
|
||||||
while (m_running)
|
while (m_running)
|
||||||
{
|
{
|
||||||
|
Watchdog.UpdateThread();
|
||||||
ProcessQueuedRequests();
|
ProcessQueuedRequests();
|
||||||
Thread.Sleep(1000);
|
Thread.Sleep(1000);
|
||||||
}
|
}
|
||||||
|
@ -98,12 +107,15 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
if (m_requests.Count == 0)
|
if (m_requests.Count == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// m_log.DebugFormat("[POLL SERVICE REQUEST MANAGER]: Processing {0} requests", m_requests.Count);
|
||||||
|
|
||||||
int reqperthread = (int) (m_requests.Count/m_WorkerThreadCount) + 1;
|
int reqperthread = (int) (m_requests.Count/m_WorkerThreadCount) + 1;
|
||||||
|
|
||||||
// For Each WorkerThread
|
// For Each WorkerThread
|
||||||
for (int tc = 0; tc < m_WorkerThreadCount && m_requests.Count > 0; tc++)
|
for (int tc = 0; tc < m_WorkerThreadCount && m_requests.Count > 0; tc++)
|
||||||
{
|
{
|
||||||
//Loop over number of requests each thread handles.
|
//Loop over number of requests each thread handles.
|
||||||
for (int i=0;i<reqperthread && m_requests.Count > 0;i++)
|
for (int i = 0; i < reqperthread && m_requests.Count > 0; i++)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -121,14 +133,14 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
~PollServiceRequestManager()
|
~PollServiceRequestManager()
|
||||||
{
|
{
|
||||||
foreach (object o in m_requests)
|
foreach (object o in m_requests)
|
||||||
{
|
{
|
||||||
PollServiceHttpRequest req = (PollServiceHttpRequest) o;
|
PollServiceHttpRequest req = (PollServiceHttpRequest) o;
|
||||||
m_server.DoHTTPGruntWork(req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id), new OSHttpResponse(new HttpResponse(req.HttpContext, req.Request), req.HttpContext));
|
m_server.DoHTTPGruntWork(
|
||||||
|
req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id),
|
||||||
|
new OSHttpResponse(new HttpResponse(req.HttpContext, req.Request), req.HttpContext));
|
||||||
}
|
}
|
||||||
|
|
||||||
m_requests.Clear();
|
m_requests.Clear();
|
||||||
|
|
|
@ -59,7 +59,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
m_timeout = pTimeout;
|
m_timeout = pTimeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ThreadStart(object o)
|
public void ThreadStart()
|
||||||
{
|
{
|
||||||
Run();
|
Run();
|
||||||
}
|
}
|
||||||
|
@ -69,6 +69,9 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
while (m_running)
|
while (m_running)
|
||||||
{
|
{
|
||||||
PollServiceHttpRequest req = m_request.Dequeue();
|
PollServiceHttpRequest req = m_request.Dequeue();
|
||||||
|
|
||||||
|
Watchdog.UpdateThread();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (req.PollServiceArgs.HasEvents(req.RequestID, req.PollServiceArgs.Id))
|
if (req.PollServiceArgs.HasEvents(req.RequestID, req.PollServiceArgs.Id))
|
||||||
|
|
|
@ -31,7 +31,7 @@ using System.Net;
|
||||||
using log4net;
|
using log4net;
|
||||||
using OpenSim.Framework.Servers.HttpServer;
|
using OpenSim.Framework.Servers.HttpServer;
|
||||||
|
|
||||||
namespace OpenSim.Framework
|
namespace OpenSim.Framework.Servers
|
||||||
{
|
{
|
||||||
public class MainServer
|
public class MainServer
|
||||||
{
|
{
|
|
@ -30,7 +30,7 @@ namespace OpenSim
|
||||||
public class VersionInfo
|
public class VersionInfo
|
||||||
{
|
{
|
||||||
private const string VERSION_NUMBER = "0.7.2";
|
private const string VERSION_NUMBER = "0.7.2";
|
||||||
private const Flavour VERSION_FLAVOUR = Flavour.Dev;
|
private const Flavour VERSION_FLAVOUR = Flavour.Post_Fixes;
|
||||||
|
|
||||||
public enum Flavour
|
public enum Flavour
|
||||||
{
|
{
|
||||||
|
|
|
@ -146,9 +146,9 @@ namespace OpenSim.Framework.Tests
|
||||||
Assert.IsFalse(Util.isUUID("FOOBAR67-89ab-Cdef-0123-456789AbCdEf"),
|
Assert.IsFalse(Util.isUUID("FOOBAR67-89ab-Cdef-0123-456789AbCdEf"),
|
||||||
"UUIDs with non-hex characters are recognized as correct UUIDs.");
|
"UUIDs with non-hex characters are recognized as correct UUIDs.");
|
||||||
Assert.IsFalse(Util.isUUID("01234567"),
|
Assert.IsFalse(Util.isUUID("01234567"),
|
||||||
"Too short UUIDs are regognized as correct UUIDs.");
|
"Too short UUIDs are recognized as correct UUIDs.");
|
||||||
Assert.IsFalse(Util.isUUID("01234567-89ab-Cdef-0123-456789AbCdEf0"),
|
Assert.IsFalse(Util.isUUID("01234567-89ab-Cdef-0123-456789AbCdEf0"),
|
||||||
"Too long UUIDs are regognized as correct UUIDs.");
|
"Too long UUIDs are recognized as correct UUIDs.");
|
||||||
Assert.IsFalse(Util.isUUID("01234567-89ab-Cdef-0123+456789AbCdEf"),
|
Assert.IsFalse(Util.isUUID("01234567-89ab-Cdef-0123+456789AbCdEf"),
|
||||||
"UUIDs with wrong format are recognized as correct UUIDs.");
|
"UUIDs with wrong format are recognized as correct UUIDs.");
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,6 @@ using System.Threading;
|
||||||
using log4net;
|
using log4net;
|
||||||
using Nini.Config;
|
using Nini.Config;
|
||||||
using Nwc.XmlRpc;
|
using Nwc.XmlRpc;
|
||||||
// using BclExtras;
|
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
using OpenMetaverse.StructuredData;
|
using OpenMetaverse.StructuredData;
|
||||||
using Amib.Threading;
|
using Amib.Threading;
|
||||||
|
@ -59,10 +58,12 @@ namespace OpenSim.Framework
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// None is used to execute the method in the same thread that made the call. It should only be used by regression
|
/// None is used to execute the method in the same thread that made the call. It should only be used by regression
|
||||||
/// test code that relies on predictable event ordering.
|
/// test code that relies on predictable event ordering.
|
||||||
|
/// RegressionTest is used by regression tests. It fires the call synchronously and does not catch any exceptions.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public enum FireAndForgetMethod
|
public enum FireAndForgetMethod
|
||||||
{
|
{
|
||||||
None,
|
None,
|
||||||
|
RegressionTest,
|
||||||
UnsafeQueueUserWorkItem,
|
UnsafeQueueUserWorkItem,
|
||||||
QueueUserWorkItem,
|
QueueUserWorkItem,
|
||||||
BeginInvoke,
|
BeginInvoke,
|
||||||
|
@ -91,8 +92,10 @@ namespace OpenSim.Framework
|
||||||
private static readonly DateTime unixEpoch =
|
private static readonly DateTime unixEpoch =
|
||||||
DateTime.ParseExact("1970-01-01 00:00:00 +0", "yyyy-MM-dd hh:mm:ss z", DateTimeFormatInfo.InvariantInfo).ToUniversalTime();
|
DateTime.ParseExact("1970-01-01 00:00:00 +0", "yyyy-MM-dd hh:mm:ss z", DateTimeFormatInfo.InvariantInfo).ToUniversalTime();
|
||||||
|
|
||||||
public static readonly Regex UUIDPattern
|
private static readonly string rawUUIDPattern
|
||||||
= new Regex("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$");
|
= "[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}";
|
||||||
|
public static readonly Regex PermissiveUUIDPattern = new Regex(rawUUIDPattern);
|
||||||
|
public static readonly Regex UUIDPattern = new Regex(string.Format("^{0}$", rawUUIDPattern));
|
||||||
|
|
||||||
public static FireAndForgetMethod DefaultFireAndForgetMethod = FireAndForgetMethod.SmartThreadPool;
|
public static FireAndForgetMethod DefaultFireAndForgetMethod = FireAndForgetMethod.SmartThreadPool;
|
||||||
public static FireAndForgetMethod FireAndForgetMethod = DefaultFireAndForgetMethod;
|
public static FireAndForgetMethod FireAndForgetMethod = DefaultFireAndForgetMethod;
|
||||||
|
@ -1542,11 +1545,20 @@ namespace OpenSim.Framework
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void FireAndForget(System.Threading.WaitCallback callback, object obj)
|
public static void FireAndForget(System.Threading.WaitCallback callback, object obj)
|
||||||
|
{
|
||||||
|
WaitCallback realCallback;
|
||||||
|
|
||||||
|
if (FireAndForgetMethod == FireAndForgetMethod.RegressionTest)
|
||||||
|
{
|
||||||
|
// If we're running regression tests, then we want any exceptions to rise up to the test code.
|
||||||
|
realCallback = o => { Culture.SetCurrentCulture(); callback(o); };
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
// When OpenSim interacts with a database or sends data over the wire, it must send this in en_US culture
|
// When OpenSim interacts with a database or sends data over the wire, it must send this in en_US culture
|
||||||
// so that we don't encounter problems where, for instance, data is saved with a culture that uses commas
|
// so that we don't encounter problems where, for instance, data is saved with a culture that uses commas
|
||||||
// for decimals places but is read by a culture that treats commas as number seperators.
|
// for decimals places but is read by a culture that treats commas as number seperators.
|
||||||
WaitCallback realCallback = delegate(object o)
|
realCallback = o =>
|
||||||
{
|
{
|
||||||
Culture.SetCurrentCulture();
|
Culture.SetCurrentCulture();
|
||||||
|
|
||||||
|
@ -1561,9 +1573,11 @@ namespace OpenSim.Framework
|
||||||
e.Message, e.StackTrace);
|
e.Message, e.StackTrace);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
switch (FireAndForgetMethod)
|
switch (FireAndForgetMethod)
|
||||||
{
|
{
|
||||||
|
case FireAndForgetMethod.RegressionTest:
|
||||||
case FireAndForgetMethod.None:
|
case FireAndForgetMethod.None:
|
||||||
realCallback.Invoke(obj);
|
realCallback.Invoke(obj);
|
||||||
break;
|
break;
|
||||||
|
@ -1650,13 +1664,14 @@ namespace OpenSim.Framework
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static void PrintCallStack()
|
public static void PrintCallStack()
|
||||||
{
|
{
|
||||||
StackTrace stackTrace = new StackTrace(); // get call stack
|
StackTrace stackTrace = new StackTrace(true); // get call stack
|
||||||
StackFrame[] stackFrames = stackTrace.GetFrames(); // get method calls (frames)
|
StackFrame[] stackFrames = stackTrace.GetFrames(); // get method calls (frames)
|
||||||
|
|
||||||
// write call stack method names
|
// write call stack method names
|
||||||
foreach (StackFrame stackFrame in stackFrames)
|
foreach (StackFrame stackFrame in stackFrames)
|
||||||
{
|
{
|
||||||
m_log.Debug(stackFrame.GetMethod().DeclaringType + "." + stackFrame.GetMethod().Name); // write method name
|
MethodBase mb = stackFrame.GetMethod();
|
||||||
|
m_log.DebugFormat("{0}.{1}:{2}", mb.DeclaringType, mb.Name, stackFrame.GetFileLineNumber()); // write method name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,19 +40,41 @@ namespace OpenSim.Framework
|
||||||
{
|
{
|
||||||
/// <summary>Timer interval in milliseconds for the watchdog timer</summary>
|
/// <summary>Timer interval in milliseconds for the watchdog timer</summary>
|
||||||
const double WATCHDOG_INTERVAL_MS = 2500.0d;
|
const double WATCHDOG_INTERVAL_MS = 2500.0d;
|
||||||
|
|
||||||
/// <summary>Maximum timeout in milliseconds before a thread is considered dead</summary>
|
/// <summary>Maximum timeout in milliseconds before a thread is considered dead</summary>
|
||||||
const int WATCHDOG_TIMEOUT_MS = 5000;
|
const int WATCHDOG_TIMEOUT_MS = 5000;
|
||||||
|
|
||||||
[System.Diagnostics.DebuggerDisplay("{Thread.Name}")]
|
[System.Diagnostics.DebuggerDisplay("{Thread.Name}")]
|
||||||
public class ThreadWatchdogInfo
|
public class ThreadWatchdogInfo
|
||||||
{
|
{
|
||||||
public Thread Thread;
|
public Thread Thread { get; private set; }
|
||||||
public int LastTick;
|
|
||||||
|
|
||||||
public ThreadWatchdogInfo(Thread thread)
|
/// <summary>
|
||||||
|
/// Approximate tick when this thread was started.
|
||||||
|
/// </summary>
|
||||||
|
public int StartTick { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Last time this heartbeat update was invoked
|
||||||
|
/// </summary>
|
||||||
|
public int LastTick { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Number of milliseconds before we notify that the thread is having a problem.
|
||||||
|
/// </summary>
|
||||||
|
public int Timeout { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Is this thread considered timed out?
|
||||||
|
/// </summary>
|
||||||
|
public bool IsTimedOut { get; set; }
|
||||||
|
|
||||||
|
public ThreadWatchdogInfo(Thread thread, int timeout)
|
||||||
{
|
{
|
||||||
Thread = thread;
|
Thread = thread;
|
||||||
LastTick = Environment.TickCount & Int32.MaxValue;
|
Timeout = timeout;
|
||||||
|
StartTick = Environment.TickCount & Int32.MaxValue;
|
||||||
|
LastTick = StartTick;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,7 +104,7 @@ namespace OpenSim.Framework
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Start a new thread that is tracked by the watchdog timer
|
/// Start a new thread that is tracked by the watchdog timer.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="start">The method that will be executed in a new thread</param>
|
/// <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="name">A name to give to the new thread</param>
|
||||||
|
@ -91,11 +113,37 @@ namespace OpenSim.Framework
|
||||||
/// thread, otherwise false</param>
|
/// thread, otherwise false</param>
|
||||||
/// <returns>The newly created Thread object</returns>
|
/// <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)
|
||||||
|
{
|
||||||
|
return StartThread(start, name, priority, isBackground, WATCHDOG_TIMEOUT_MS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Start a new thread that is tracked by the watchdog timer
|
||||||
|
/// </summary>
|
||||||
|
/// <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="timeout">
|
||||||
|
/// Number of milliseconds to wait until we issue a warning about timeout.
|
||||||
|
/// </para>
|
||||||
|
/// <returns>The newly created Thread object</returns>
|
||||||
|
public static Thread StartThread(
|
||||||
|
ThreadStart start, string name, ThreadPriority priority, bool isBackground, int timeout)
|
||||||
{
|
{
|
||||||
Thread thread = new Thread(start);
|
Thread thread = new Thread(start);
|
||||||
thread.Name = name;
|
thread.Name = name;
|
||||||
thread.Priority = priority;
|
thread.Priority = priority;
|
||||||
thread.IsBackground = isBackground;
|
thread.IsBackground = isBackground;
|
||||||
|
|
||||||
|
ThreadWatchdogInfo twi = new ThreadWatchdogInfo(thread, timeout);
|
||||||
|
|
||||||
|
m_log.Debug("[WATCHDOG]: Started tracking thread \"" + twi.Thread.Name + "\" (ID " + twi.Thread.ManagedThreadId + ")");
|
||||||
|
|
||||||
|
lock (m_threads)
|
||||||
|
m_threads.Add(twi.Thread.ManagedThreadId, twi);
|
||||||
|
|
||||||
thread.Start();
|
thread.Start();
|
||||||
|
|
||||||
return thread;
|
return thread;
|
||||||
|
@ -112,27 +160,40 @@ namespace OpenSim.Framework
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Stops watchdog tracking on the current thread
|
/// Stops watchdog tracking on the current thread
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>True if the thread was removed from the list of tracked
|
/// <returns>
|
||||||
/// threads, otherwise false</returns>
|
/// True if the thread was removed from the list of tracked
|
||||||
|
/// threads, otherwise false
|
||||||
|
/// </returns>
|
||||||
public static bool RemoveThread()
|
public static bool RemoveThread()
|
||||||
{
|
{
|
||||||
return RemoveThread(Thread.CurrentThread.ManagedThreadId);
|
return RemoveThread(Thread.CurrentThread.ManagedThreadId);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void AddThread(ThreadWatchdogInfo threadInfo)
|
|
||||||
{
|
|
||||||
m_log.Debug("[WATCHDOG]: Started tracking thread \"" + threadInfo.Thread.Name + "\" (ID " + threadInfo.Thread.ManagedThreadId + ")");
|
|
||||||
|
|
||||||
lock (m_threads)
|
|
||||||
m_threads.Add(threadInfo.Thread.ManagedThreadId, threadInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static bool RemoveThread(int threadID)
|
private static bool RemoveThread(int threadID)
|
||||||
{
|
{
|
||||||
lock (m_threads)
|
lock (m_threads)
|
||||||
return m_threads.Remove(threadID);
|
return m_threads.Remove(threadID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool AbortThread(int threadID)
|
||||||
|
{
|
||||||
|
lock (m_threads)
|
||||||
|
{
|
||||||
|
if (m_threads.ContainsKey(threadID))
|
||||||
|
{
|
||||||
|
ThreadWatchdogInfo twi = m_threads[threadID];
|
||||||
|
twi.Thread.Abort();
|
||||||
|
RemoveThread(threadID);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static void UpdateThread(int threadID)
|
private static void UpdateThread(int threadID)
|
||||||
{
|
{
|
||||||
ThreadWatchdogInfo threadInfo;
|
ThreadWatchdogInfo threadInfo;
|
||||||
|
@ -144,9 +205,14 @@ namespace OpenSim.Framework
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (m_threads.TryGetValue(threadID, out threadInfo))
|
if (m_threads.TryGetValue(threadID, out threadInfo))
|
||||||
|
{
|
||||||
threadInfo.LastTick = Environment.TickCount & Int32.MaxValue;
|
threadInfo.LastTick = Environment.TickCount & Int32.MaxValue;
|
||||||
|
threadInfo.IsTimedOut = false;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
AddThread(new ThreadWatchdogInfo(Thread.CurrentThread));
|
{
|
||||||
|
m_log.WarnFormat("[WATCHDOG]: Asked to update thread {0} which is not being monitored", threadID);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
}
|
}
|
||||||
|
@ -157,6 +223,7 @@ namespace OpenSim.Framework
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static ThreadWatchdogInfo[] GetThreads()
|
public static ThreadWatchdogInfo[] GetThreads()
|
||||||
{
|
{
|
||||||
|
lock (m_threads)
|
||||||
return m_threads.Values.ToArray();
|
return m_threads.Values.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,10 +241,16 @@ namespace OpenSim.Framework
|
||||||
|
|
||||||
foreach (ThreadWatchdogInfo threadInfo in m_threads.Values)
|
foreach (ThreadWatchdogInfo threadInfo in m_threads.Values)
|
||||||
{
|
{
|
||||||
if (threadInfo.Thread.ThreadState == ThreadState.Stopped || now - threadInfo.LastTick >= WATCHDOG_TIMEOUT_MS)
|
if (threadInfo.Thread.ThreadState == ThreadState.Stopped)
|
||||||
{
|
{
|
||||||
timedOut = threadInfo;
|
timedOut = threadInfo;
|
||||||
m_threads.Remove(threadInfo.Thread.ManagedThreadId);
|
RemoveThread(threadInfo.Thread.ManagedThreadId);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (!threadInfo.IsTimedOut && now - threadInfo.LastTick >= threadInfo.Timeout)
|
||||||
|
{
|
||||||
|
threadInfo.IsTimedOut = true;
|
||||||
|
timedOut = threadInfo;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,9 +39,7 @@ using System.Text;
|
||||||
using System.Web;
|
using System.Web;
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
using System.Xml.Serialization;
|
using System.Xml.Serialization;
|
||||||
|
|
||||||
using log4net;
|
using log4net;
|
||||||
using OpenSim.Framework.Servers.HttpServer;
|
|
||||||
using OpenMetaverse.StructuredData;
|
using OpenMetaverse.StructuredData;
|
||||||
|
|
||||||
namespace OpenSim.Framework
|
namespace OpenSim.Framework
|
||||||
|
@ -65,35 +63,35 @@ namespace OpenSim.Framework
|
||||||
// a "long" call for warning & debugging purposes
|
// a "long" call for warning & debugging purposes
|
||||||
public const int LongCallTime = 500;
|
public const int LongCallTime = 500;
|
||||||
|
|
||||||
/// <summary>
|
// /// <summary>
|
||||||
/// Send LLSD to an HTTP client in application/llsd+json form
|
// /// Send LLSD to an HTTP client in application/llsd+json form
|
||||||
/// </summary>
|
// /// </summary>
|
||||||
/// <param name="response">HTTP response to send the data in</param>
|
// /// <param name="response">HTTP response to send the data in</param>
|
||||||
/// <param name="body">LLSD to send to the client</param>
|
// /// <param name="body">LLSD to send to the client</param>
|
||||||
public static void SendJSONResponse(OSHttpResponse response, OSDMap body)
|
// public static void SendJSONResponse(OSHttpResponse response, OSDMap body)
|
||||||
{
|
// {
|
||||||
byte[] responseData = Encoding.UTF8.GetBytes(OSDParser.SerializeJsonString(body));
|
// byte[] responseData = Encoding.UTF8.GetBytes(OSDParser.SerializeJsonString(body));
|
||||||
|
//
|
||||||
response.ContentEncoding = Encoding.UTF8;
|
// response.ContentEncoding = Encoding.UTF8;
|
||||||
response.ContentLength = responseData.Length;
|
// response.ContentLength = responseData.Length;
|
||||||
response.ContentType = "application/llsd+json";
|
// response.ContentType = "application/llsd+json";
|
||||||
response.Body.Write(responseData, 0, responseData.Length);
|
// response.Body.Write(responseData, 0, responseData.Length);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
/// <summary>
|
// /// <summary>
|
||||||
/// Send LLSD to an HTTP client in application/llsd+xml form
|
// /// Send LLSD to an HTTP client in application/llsd+xml form
|
||||||
/// </summary>
|
// /// </summary>
|
||||||
/// <param name="response">HTTP response to send the data in</param>
|
// /// <param name="response">HTTP response to send the data in</param>
|
||||||
/// <param name="body">LLSD to send to the client</param>
|
// /// <param name="body">LLSD to send to the client</param>
|
||||||
public static void SendXMLResponse(OSHttpResponse response, OSDMap body)
|
// public static void SendXMLResponse(OSHttpResponse response, OSDMap body)
|
||||||
{
|
// {
|
||||||
byte[] responseData = OSDParser.SerializeLLSDXmlBytes(body);
|
// byte[] responseData = OSDParser.SerializeLLSDXmlBytes(body);
|
||||||
|
//
|
||||||
response.ContentEncoding = Encoding.UTF8;
|
// response.ContentEncoding = Encoding.UTF8;
|
||||||
response.ContentLength = responseData.Length;
|
// response.ContentLength = responseData.Length;
|
||||||
response.ContentType = "application/llsd+xml";
|
// response.ContentType = "application/llsd+xml";
|
||||||
response.Body.Write(responseData, 0, responseData.Length);
|
// response.Body.Write(responseData, 0, responseData.Length);
|
||||||
}
|
// }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Make a GET or GET-like request to a web service that returns LLSD
|
/// Make a GET or GET-like request to a web service that returns LLSD
|
||||||
|
@ -296,10 +294,10 @@ namespace OpenSim.Framework
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch
|
||||||
{
|
{
|
||||||
// don't need to treat this as an error... we're just guessing anyway
|
// don't need to treat this as an error... we're just guessing anyway
|
||||||
m_log.DebugFormat("[WEB UTIL] couldn't decode <{0}>: {1}",response,e.Message);
|
// m_log.DebugFormat("[WEB UTIL] couldn't decode <{0}>: {1}",response,e.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -362,10 +362,6 @@ namespace OpenSim
|
||||||
{
|
{
|
||||||
m_configSettings.PhysicsEngine = startupConfig.GetString("physics");
|
m_configSettings.PhysicsEngine = startupConfig.GetString("physics");
|
||||||
m_configSettings.MeshEngineName = startupConfig.GetString("meshing");
|
m_configSettings.MeshEngineName = startupConfig.GetString("meshing");
|
||||||
m_configSettings.PhysicalPrim = startupConfig.GetBoolean("physical_prim", true);
|
|
||||||
|
|
||||||
m_configSettings.See_into_region_from_neighbor = startupConfig.GetBoolean("see_into_this_sim_from_neighbor", true);
|
|
||||||
|
|
||||||
m_configSettings.StorageDll = startupConfig.GetString("storage_plugin");
|
m_configSettings.StorageDll = startupConfig.GetString("storage_plugin");
|
||||||
|
|
||||||
m_configSettings.ClientstackDll
|
m_configSettings.ClientstackDll
|
||||||
|
|
|
@ -37,6 +37,7 @@ using Nini.Config;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
using OpenSim.Framework.Console;
|
using OpenSim.Framework.Console;
|
||||||
|
using OpenSim.Framework.Servers;
|
||||||
using OpenSim.Framework.Statistics;
|
using OpenSim.Framework.Statistics;
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
using OpenSim.Region.Framework.Interfaces;
|
||||||
using OpenSim.Region.Framework.Scenes;
|
using OpenSim.Region.Framework.Scenes;
|
||||||
|
@ -210,28 +211,33 @@ namespace OpenSim
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void RegisterConsoleCommands()
|
private void RegisterConsoleCommands()
|
||||||
{
|
{
|
||||||
m_console.Commands.AddCommand("region", false, "clear assets",
|
|
||||||
"clear assets",
|
|
||||||
"Clear the asset cache", HandleClearAssets);
|
|
||||||
|
|
||||||
m_console.Commands.AddCommand("region", false, "force update",
|
m_console.Commands.AddCommand("region", false, "force update",
|
||||||
"force update",
|
"force update",
|
||||||
"Force the update of all objects on clients",
|
"Force the update of all objects on clients",
|
||||||
HandleForceUpdate);
|
HandleForceUpdate);
|
||||||
|
|
||||||
m_console.Commands.AddCommand("region", false, "debug packet",
|
m_console.Commands.AddCommand("region", false, "debug packet",
|
||||||
"debug packet <level>",
|
"debug packet <level> [<avatar-first-name> <avatar-last-name>]",
|
||||||
"Turn on packet debugging",
|
"Turn on packet debugging",
|
||||||
"If level > 255 then all incoming and outgoing packets are logged.\n"
|
"If level > 255 then all incoming and outgoing packets are logged.\n"
|
||||||
+ "If level <= 255 then incoming AgentUpdate and outgoing SimStats and SimulatorViewerTimeMessage packets are not logged.\n"
|
+ "If level <= 255 then incoming AgentUpdate and outgoing SimStats and SimulatorViewerTimeMessage packets are not logged.\n"
|
||||||
+ "If level <= 200 then incoming RequestImage and outgoing ImagePacket, ImageData, LayerData and CoarseLocationUpdate packets are not logged.\n"
|
+ "If level <= 200 then incoming RequestImage and outgoing ImagePacket, ImageData, LayerData and CoarseLocationUpdate packets are not logged.\n"
|
||||||
+ "If level <= 100 then incoming ViewerEffect and AgentAnimation and outgoing ViewerEffect and AvatarAnimation packets are not logged.\n"
|
+ "If level <= 100 then incoming ViewerEffect and AgentAnimation and outgoing ViewerEffect and AvatarAnimation packets are not logged.\n"
|
||||||
+ "If level <= 50 then outgoing ImprovedTerseObjectUpdate packets are not logged.\n"
|
+ "If level <= 50 then outgoing ImprovedTerseObjectUpdate packets are not logged.\n"
|
||||||
+ "If level <= 0 then no packets are logged.",
|
+ "If level <= 0 then no packets are logged.\n"
|
||||||
|
+ "If an avatar name is given then only packets from that avatar are logged",
|
||||||
|
Debug);
|
||||||
|
|
||||||
|
m_console.Commands.AddCommand("region", 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"
|
||||||
|
+ "If level >= 1 then incoming HTTP requests are logged.\n"
|
||||||
|
+ "If level <= 0 then no extra http logging is done.\n",
|
||||||
Debug);
|
Debug);
|
||||||
|
|
||||||
m_console.Commands.AddCommand("region", false, "debug scene",
|
m_console.Commands.AddCommand("region", false, "debug scene",
|
||||||
"debug scene <cripting> <collisions> <physics>",
|
"debug scene <scripting> <collisions> <physics>",
|
||||||
"Turn on scene debugging", Debug);
|
"Turn on scene debugging", Debug);
|
||||||
|
|
||||||
m_console.Commands.AddCommand("region", false, "change region",
|
m_console.Commands.AddCommand("region", false, "change region",
|
||||||
|
@ -325,7 +331,7 @@ namespace OpenSim
|
||||||
|
|
||||||
m_console.Commands.AddCommand("region", false, "backup",
|
m_console.Commands.AddCommand("region", false, "backup",
|
||||||
"backup",
|
"backup",
|
||||||
"Persist objects to the database now", RunCommand);
|
"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("region", false, "create region",
|
||||||
"create region [\"region name\"] <region_file.ini>",
|
"create region [\"region name\"] <region_file.ini>",
|
||||||
|
@ -509,11 +515,6 @@ namespace OpenSim
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleClearAssets(string module, string[] args)
|
|
||||||
{
|
|
||||||
MainConsole.Instance.Output("Not implemented.");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Force resending of all updates to all clients in active region(s)
|
/// Force resending of all updates to all clients in active region(s)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -781,6 +782,7 @@ namespace OpenSim
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "backup":
|
case "backup":
|
||||||
|
MainConsole.Instance.Output("Triggering save of pending object updates to persistent store");
|
||||||
m_sceneManager.BackupCurrentScene();
|
m_sceneManager.BackupCurrentScene();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -791,7 +793,7 @@ namespace OpenSim
|
||||||
if (m_sceneManager.TryGetScene(regRemoveName, out removeScene))
|
if (m_sceneManager.TryGetScene(regRemoveName, out removeScene))
|
||||||
RemoveRegion(removeScene, false);
|
RemoveRegion(removeScene, false);
|
||||||
else
|
else
|
||||||
MainConsole.Instance.Output("no region with that name");
|
MainConsole.Instance.Output("No region with that name");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "delete-region":
|
case "delete-region":
|
||||||
|
@ -854,22 +856,42 @@ namespace OpenSim
|
||||||
switch (args[1])
|
switch (args[1])
|
||||||
{
|
{
|
||||||
case "packet":
|
case "packet":
|
||||||
|
string name = null;
|
||||||
|
if (args.Length == 5)
|
||||||
|
name = string.Format("{0} {1}", args[3], args[4]);
|
||||||
|
|
||||||
if (args.Length > 2)
|
if (args.Length > 2)
|
||||||
{
|
{
|
||||||
int newDebug;
|
int newDebug;
|
||||||
if (int.TryParse(args[2], out newDebug))
|
if (int.TryParse(args[2], out newDebug))
|
||||||
{
|
{
|
||||||
m_sceneManager.SetDebugPacketLevelOnCurrentScene(newDebug);
|
m_sceneManager.SetDebugPacketLevelOnCurrentScene(newDebug, name);
|
||||||
|
// We provide user information elsewhere if any clients had their debug level set.
|
||||||
|
// MainConsole.Instance.OutputFormat("Debug packet level set to {0}", newDebug);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MainConsole.Instance.Output("packet debug should be 0..255");
|
MainConsole.Instance.Output("Usage: debug packet 0..255");
|
||||||
}
|
}
|
||||||
MainConsole.Instance.Output(String.Format("New packet debug: {0}", newDebug));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case "http":
|
||||||
|
if (args.Length == 3)
|
||||||
|
{
|
||||||
|
int newDebug;
|
||||||
|
if (int.TryParse(args[2], out newDebug))
|
||||||
|
{
|
||||||
|
MainServer.Instance.DebugLevel = newDebug;
|
||||||
|
MainConsole.Instance.OutputFormat("Debug http level set to {0}", newDebug);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MainConsole.Instance.Output("Usage: debug http 0..2");
|
||||||
|
break;
|
||||||
|
|
||||||
case "scene":
|
case "scene":
|
||||||
if (args.Length == 5)
|
if (args.Length == 5)
|
||||||
{
|
{
|
||||||
|
@ -892,13 +914,13 @@ namespace OpenSim
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MainConsole.Instance.Output("debug scene <scripting> <collisions> <physics> (where inside <> is true/false)");
|
MainConsole.Instance.Output("Usage: debug scene <scripting> <collisions> <physics> (where inside <> is true/false)");
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
MainConsole.Instance.Output("Unknown debug");
|
MainConsole.Instance.Output("Unknown debug command");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -462,9 +462,18 @@ namespace OpenSim
|
||||||
string password = MainConsole.Instance.PasswdPrompt("Password");
|
string password = MainConsole.Instance.PasswdPrompt("Password");
|
||||||
string email = MainConsole.Instance.CmdPrompt("Email", "");
|
string email = MainConsole.Instance.CmdPrompt("Email", "");
|
||||||
|
|
||||||
|
string rawPrincipalId = MainConsole.Instance.CmdPrompt("User ID", UUID.Random().ToString());
|
||||||
|
|
||||||
|
UUID principalId = UUID.Zero;
|
||||||
|
if (!UUID.TryParse(rawPrincipalId, out principalId))
|
||||||
|
{
|
||||||
|
m_log.ErrorFormat("[OPENSIM]: ID {0} is not a valid UUID", rawPrincipalId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
account
|
account
|
||||||
= ((UserAccountService)scene.UserAccountService).CreateUser(
|
= ((UserAccountService)scene.UserAccountService).CreateUser(
|
||||||
regionInfo.ScopeID, first, last, password, email);
|
regionInfo.ScopeID, principalId, first, last, password, email);
|
||||||
}
|
}
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
@ -650,8 +659,8 @@ namespace OpenSim
|
||||||
|
|
||||||
return new Scene(
|
return new Scene(
|
||||||
regionInfo, circuitManager, sceneGridService,
|
regionInfo, circuitManager, sceneGridService,
|
||||||
simDataService, estateDataService, m_moduleLoader, false, m_configSettings.PhysicalPrim,
|
simDataService, estateDataService, m_moduleLoader, false,
|
||||||
m_configSettings.See_into_region_from_neighbor, m_config.Source, m_version);
|
m_config.Source, m_version);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void ShutdownClientServer(RegionInfo whichRegion)
|
protected void ShutdownClientServer(RegionInfo whichRegion)
|
||||||
|
@ -719,7 +728,7 @@ namespace OpenSim
|
||||||
|
|
||||||
public string Path
|
public string Path
|
||||||
{
|
{
|
||||||
get { return "/simstatus/"; }
|
get { return "/simstatus"; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -757,7 +766,7 @@ namespace OpenSim
|
||||||
public string Path
|
public string Path
|
||||||
{
|
{
|
||||||
// This is for the OpenSimulator instance and is the osSecret hashed
|
// This is for the OpenSimulator instance and is the osSecret hashed
|
||||||
get { return "/" + osXStatsURI + "/"; }
|
get { return "/" + osXStatsURI; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -798,7 +807,7 @@ namespace OpenSim
|
||||||
public string Path
|
public string Path
|
||||||
{
|
{
|
||||||
// This is for the OpenSimulator instance and is the user provided URI
|
// This is for the OpenSimulator instance and is the user provided URI
|
||||||
get { return "/" + osUXStatsURI + "/"; }
|
get { return "/" + osUXStatsURI; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,8 +56,6 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
string assetName, string description, UUID assetID, UUID inventoryItem, UUID parentFolder,
|
string assetName, string description, UUID assetID, UUID inventoryItem, UUID parentFolder,
|
||||||
byte[] data, string inventoryType, string assetType);
|
byte[] data, string inventoryType, string assetType);
|
||||||
|
|
||||||
public delegate void UploadedBakedTexture(UUID assetID, byte[] data);
|
|
||||||
|
|
||||||
public delegate UUID UpdateItem(UUID itemID, byte[] data);
|
public delegate UUID UpdateItem(UUID itemID, byte[] data);
|
||||||
|
|
||||||
public delegate void UpdateTaskScript(UUID itemID, UUID primID, bool isScriptRunning, byte[] data, ref ArrayList errors);
|
public delegate void UpdateTaskScript(UUID itemID, UUID primID, bool isScriptRunning, byte[] data, ref ArrayList errors);
|
||||||
|
@ -97,7 +95,6 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
private static readonly string m_notecardTaskUpdatePath = "0005/";
|
private static readonly string m_notecardTaskUpdatePath = "0005/";
|
||||||
// private static readonly string m_fetchInventoryPath = "0006/";
|
// private static readonly string m_fetchInventoryPath = "0006/";
|
||||||
// private static readonly string m_remoteParcelRequestPath = "0009/";// This is in the LandManagementModule.
|
// private static readonly string m_remoteParcelRequestPath = "0009/";// This is in the LandManagementModule.
|
||||||
private static readonly string m_uploadBakedTexturePath = "0010/";// This is in the LandManagementModule.
|
|
||||||
|
|
||||||
|
|
||||||
// These are callbacks which will be setup by the scene so that we can update scene data when we
|
// These are callbacks which will be setup by the scene so that we can update scene data when we
|
||||||
|
@ -165,8 +162,6 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
IRequestHandler req = new RestStreamHandler("POST", capsBase + m_notecardTaskUpdatePath, ScriptTaskInventory);
|
IRequestHandler req = new RestStreamHandler("POST", capsBase + m_notecardTaskUpdatePath, ScriptTaskInventory);
|
||||||
m_HostCapsObj.RegisterHandler("UpdateScriptTaskInventory", req);
|
m_HostCapsObj.RegisterHandler("UpdateScriptTaskInventory", req);
|
||||||
m_HostCapsObj.RegisterHandler("UpdateScriptTask", req);
|
m_HostCapsObj.RegisterHandler("UpdateScriptTask", req);
|
||||||
m_HostCapsObj.RegisterHandler("UploadBakedTexture", new RestStreamHandler("POST", capsBase + m_uploadBakedTexturePath, UploadBakedTexture));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
@ -239,7 +234,8 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
Hashtable caps = m_HostCapsObj.CapsHandlers.CapsDetails;
|
Hashtable caps = m_HostCapsObj.CapsHandlers.GetCapsDetails(true);
|
||||||
|
|
||||||
// Add the external too
|
// Add the external too
|
||||||
foreach (KeyValuePair<string, string> kvp in m_HostCapsObj.ExternalCapsHandlers)
|
foreach (KeyValuePair<string, string> kvp in m_HostCapsObj.ExternalCapsHandlers)
|
||||||
caps[kvp.Key] = kvp.Value;
|
caps[kvp.Key] = kvp.Value;
|
||||||
|
@ -330,74 +326,6 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Handle a request from the client for a Uri to upload a baked texture.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="request"></param>
|
|
||||||
/// <param name="path"></param>
|
|
||||||
/// <param name="param"></param>
|
|
||||||
/// <param name="httpRequest"></param>
|
|
||||||
/// <param name="httpResponse"></param>
|
|
||||||
/// <returns>The upload response if the request is successful, null otherwise.</returns>
|
|
||||||
public string UploadBakedTexture(string request, string path,
|
|
||||||
string param, OSHttpRequest httpRequest,
|
|
||||||
OSHttpResponse httpResponse)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// m_log.Debug("[CAPS]: UploadBakedTexture Request in region: " + m_regionName);
|
|
||||||
|
|
||||||
string capsBase = "/CAPS/" + m_HostCapsObj.CapsObjectPath;
|
|
||||||
string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000");
|
|
||||||
|
|
||||||
BakedTextureUploader uploader =
|
|
||||||
new BakedTextureUploader(capsBase + uploaderPath, m_HostCapsObj.HttpListener);
|
|
||||||
uploader.OnUpLoad += BakedTextureUploaded;
|
|
||||||
|
|
||||||
m_HostCapsObj.HttpListener.AddStreamHandler(
|
|
||||||
new BinaryStreamHandler("POST", capsBase + uploaderPath,
|
|
||||||
uploader.uploaderCaps));
|
|
||||||
|
|
||||||
string protocol = "http://";
|
|
||||||
|
|
||||||
if (m_HostCapsObj.SSLCaps)
|
|
||||||
protocol = "https://";
|
|
||||||
|
|
||||||
string uploaderURL = protocol + m_HostCapsObj.HostName + ":" +
|
|
||||||
m_HostCapsObj.Port.ToString() + capsBase + uploaderPath;
|
|
||||||
|
|
||||||
LLSDAssetUploadResponse uploadResponse =
|
|
||||||
new LLSDAssetUploadResponse();
|
|
||||||
uploadResponse.uploader = uploaderURL;
|
|
||||||
uploadResponse.state = "upload";
|
|
||||||
|
|
||||||
return LLSDHelpers.SerialiseLLSDReply(uploadResponse);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
m_log.Error("[CAPS]: " + e.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Called when a baked texture has been successfully uploaded by a client.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="assetID"></param>
|
|
||||||
/// <param name="data"></param>
|
|
||||||
public void BakedTextureUploaded(UUID assetID, byte[] data)
|
|
||||||
{
|
|
||||||
// m_log.WarnFormat("[CAPS]: Received baked texture {0}", assetID.ToString());
|
|
||||||
|
|
||||||
AssetBase asset;
|
|
||||||
asset = new AssetBase(assetID, "Baked Texture", (sbyte)AssetType.Texture, m_HostCapsObj.AgentID.ToString());
|
|
||||||
asset.Data = data;
|
|
||||||
asset.Temporary = true;
|
|
||||||
asset.Local = !m_persistBakedTextures; // Local assets aren't persisted, non-local are
|
|
||||||
m_assetService.Store(asset);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Called when new asset data for an agent inventory item update has been uploaded.
|
/// Called when new asset data for an agent inventory item update has been uploaded.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -1067,6 +995,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
// XXX Maybe this should be some meaningful error packet
|
// XXX Maybe this should be some meaningful error packet
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
///Left this in and commented in case there are unforseen issues
|
///Left this in and commented in case there are unforseen issues
|
||||||
//private void SaveAssetToFile(string filename, byte[] data)
|
//private void SaveAssetToFile(string filename, byte[] data)
|
||||||
//{
|
//{
|
||||||
|
@ -1090,53 +1019,4 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
fs.Close();
|
fs.Close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class BakedTextureUploader
|
|
||||||
{
|
|
||||||
public event UploadedBakedTexture OnUpLoad;
|
|
||||||
private UploadedBakedTexture handlerUpLoad = null;
|
|
||||||
|
|
||||||
private string uploaderPath = String.Empty;
|
|
||||||
private UUID newAssetID;
|
|
||||||
private IHttpServer httpListener;
|
|
||||||
|
|
||||||
public BakedTextureUploader(string path, IHttpServer httpServer)
|
|
||||||
{
|
|
||||||
newAssetID = UUID.Random();
|
|
||||||
uploaderPath = path;
|
|
||||||
httpListener = httpServer;
|
|
||||||
// m_log.InfoFormat("[CAPS] baked texture upload starting for {0}",newAssetID);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Handle raw uploaded baked texture data.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="data"></param>
|
|
||||||
/// <param name="path"></param>
|
|
||||||
/// <param name="param"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public string uploaderCaps(byte[] data, string path, string param)
|
|
||||||
{
|
|
||||||
handlerUpLoad = OnUpLoad;
|
|
||||||
if (handlerUpLoad != null)
|
|
||||||
{
|
|
||||||
Util.FireAndForget(delegate(object o) { handlerUpLoad(newAssetID, data); });
|
|
||||||
}
|
|
||||||
|
|
||||||
string res = String.Empty;
|
|
||||||
LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete();
|
|
||||||
uploadComplete.new_asset = newAssetID.ToString();
|
|
||||||
uploadComplete.new_inventory_item = UUID.Zero;
|
|
||||||
uploadComplete.state = "complete";
|
|
||||||
|
|
||||||
res = LLSDHelpers.SerialiseLLSDReply(uploadComplete);
|
|
||||||
|
|
||||||
httpListener.RemoveStreamHandler("POST", uploaderPath);
|
|
||||||
|
|
||||||
// m_log.InfoFormat("[CAPS] baked texture upload completed for {0}",newAssetID);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -39,6 +39,7 @@ using OpenMetaverse.Messages.Linden;
|
||||||
using OpenMetaverse.Packets;
|
using OpenMetaverse.Packets;
|
||||||
using OpenMetaverse.StructuredData;
|
using OpenMetaverse.StructuredData;
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Framework.Console;
|
||||||
using OpenSim.Framework.Servers;
|
using OpenSim.Framework.Servers;
|
||||||
using OpenSim.Framework.Servers.HttpServer;
|
using OpenSim.Framework.Servers.HttpServer;
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
using OpenSim.Region.Framework.Interfaces;
|
||||||
|
@ -58,9 +59,15 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
public class EventQueueGetModule : IEventQueue, IRegionModule
|
public class EventQueueGetModule : IEventQueue, IRegionModule
|
||||||
{
|
{
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
protected Scene m_scene = null;
|
|
||||||
|
/// <value>
|
||||||
|
/// Debug level.
|
||||||
|
/// </value>
|
||||||
|
public int DebugLevel { get; set; }
|
||||||
|
|
||||||
|
protected Scene m_scene;
|
||||||
private IConfigSource m_gConfig;
|
private IConfigSource m_gConfig;
|
||||||
bool enabledYN = false;
|
bool enabledYN;
|
||||||
|
|
||||||
private Dictionary<UUID, int> m_ids = new Dictionary<UUID, int>();
|
private Dictionary<UUID, int> m_ids = new Dictionary<UUID, int>();
|
||||||
|
|
||||||
|
@ -97,12 +104,21 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
scene.EventManager.OnClientClosed += ClientClosed;
|
scene.EventManager.OnClientClosed += ClientClosed;
|
||||||
scene.EventManager.OnMakeChildAgent += MakeChildAgent;
|
scene.EventManager.OnMakeChildAgent += MakeChildAgent;
|
||||||
scene.EventManager.OnRegisterCaps += OnRegisterCaps;
|
scene.EventManager.OnRegisterCaps += OnRegisterCaps;
|
||||||
|
|
||||||
|
MainConsole.Instance.Commands.AddCommand(
|
||||||
|
"event queue",
|
||||||
|
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.",
|
||||||
|
HandleDebugEq);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_gConfig = null;
|
m_gConfig = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ReadConfigAndPopulate(Scene scene, IConfig startupConfig, string p)
|
private void ReadConfigAndPopulate(Scene scene, IConfig startupConfig, string p)
|
||||||
|
@ -129,6 +145,22 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
protected void HandleDebugEq(string module, string[] args)
|
||||||
|
{
|
||||||
|
int debugLevel;
|
||||||
|
|
||||||
|
if (!(args.Length == 3 && int.TryParse(args[2], out debugLevel)))
|
||||||
|
{
|
||||||
|
MainConsole.Instance.OutputFormat("Usage: debug eq [0|1]");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DebugLevel = debugLevel;
|
||||||
|
MainConsole.Instance.OutputFormat(
|
||||||
|
"Set event queue debug level to {0} in {1}", DebugLevel, m_scene.RegionInfo.RegionName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Always returns a valid queue
|
/// Always returns a valid queue
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -179,9 +211,10 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
{
|
{
|
||||||
Queue<OSD> queue = GetQueue(avatarID);
|
Queue<OSD> queue = GetQueue(avatarID);
|
||||||
if (queue != null)
|
if (queue != null)
|
||||||
|
lock (queue)
|
||||||
queue.Enqueue(ev);
|
queue.Enqueue(ev);
|
||||||
}
|
}
|
||||||
catch(NullReferenceException e)
|
catch (NullReferenceException e)
|
||||||
{
|
{
|
||||||
m_log.Error("[EVENTQUEUE] Caught exception: " + e);
|
m_log.Error("[EVENTQUEUE] Caught exception: " + e);
|
||||||
return false;
|
return false;
|
||||||
|
@ -204,7 +237,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
|
|
||||||
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;
|
int count = 0;
|
||||||
while (queues.ContainsKey(AgentID) && queues[AgentID].Count > 0 && count++ < 5)
|
while (queues.ContainsKey(AgentID) && queues[AgentID].Count > 0 && count++ < 5)
|
||||||
|
@ -216,11 +249,13 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
{
|
{
|
||||||
queues.Remove(AgentID);
|
queues.Remove(AgentID);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<UUID> removeitems = new List<UUID>();
|
List<UUID> removeitems = new List<UUID>();
|
||||||
lock (m_AvatarQueueUUIDMapping)
|
lock (m_AvatarQueueUUIDMapping)
|
||||||
{
|
{
|
||||||
foreach (UUID ky in m_AvatarQueueUUIDMapping.Keys)
|
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);
|
removeitems.Add(ky);
|
||||||
|
@ -229,11 +264,13 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
|
|
||||||
foreach (UUID ky in removeitems)
|
foreach (UUID ky in removeitems)
|
||||||
{
|
{
|
||||||
|
UUID eventQueueGetUuid = m_AvatarQueueUUIDMapping[ky];
|
||||||
m_AvatarQueueUUIDMapping.Remove(ky);
|
m_AvatarQueueUUIDMapping.Remove(ky);
|
||||||
MainServer.Instance.RemovePollServiceHTTPHandler("","/CAPS/EQG/" + ky.ToString() + "/");
|
|
||||||
|
MainServer.Instance.RemovePollServiceHTTPHandler("","/CAPS/EQG/" + eventQueueGetUuid.ToString() + "/");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
UUID searchval = UUID.Zero;
|
UUID searchval = UUID.Zero;
|
||||||
|
|
||||||
removeitems.Clear();
|
removeitems.Clear();
|
||||||
|
@ -252,7 +289,6 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
|
|
||||||
foreach (UUID ky in removeitems)
|
foreach (UUID ky in removeitems)
|
||||||
m_QueueUUIDAvatarMapping.Remove(ky);
|
m_QueueUUIDAvatarMapping.Remove(ky);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -320,7 +356,9 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
|
|
||||||
// This will persist this beyond the expiry of the caps handlers
|
// This will persist this beyond the expiry of the caps handlers
|
||||||
MainServer.Instance.AddPollServiceHTTPHandler(
|
MainServer.Instance.AddPollServiceHTTPHandler(
|
||||||
capsBase + EventQueueGetUUID.ToString() + "/", EventQueuePoll, new PollServiceEventArgs(null, HasEvents, GetEvents, NoEvents, agentID));
|
capsBase + EventQueueGetUUID.ToString() + "/",
|
||||||
|
EventQueuePoll,
|
||||||
|
new PollServiceEventArgs(null, HasEvents, GetEvents, NoEvents, agentID));
|
||||||
|
|
||||||
Random rnd = new Random(Environment.TickCount);
|
Random rnd = new Random(Environment.TickCount);
|
||||||
lock (m_ids)
|
lock (m_ids)
|
||||||
|
@ -338,12 +376,8 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
Queue<OSD> queue = GetQueue(agentID);
|
Queue<OSD> queue = GetQueue(agentID);
|
||||||
if (queue != null)
|
if (queue != null)
|
||||||
lock (queue)
|
lock (queue)
|
||||||
{
|
return queue.Count > 0;
|
||||||
if (queue.Count > 0)
|
|
||||||
return true;
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -358,8 +392,6 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
element = queue.Dequeue(); // 15s timeout
|
element = queue.Dequeue(); // 15s timeout
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int thisID = 0;
|
int thisID = 0;
|
||||||
lock (m_ids)
|
lock (m_ids)
|
||||||
thisID = m_ids[pAgentId];
|
thisID = m_ids[pAgentId];
|
||||||
|
@ -373,12 +405,31 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
}
|
}
|
||||||
else
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
array.Add(element);
|
array.Add(element);
|
||||||
|
|
||||||
lock (queue)
|
lock (queue)
|
||||||
{
|
{
|
||||||
while (queue.Count > 0)
|
while (queue.Count > 0)
|
||||||
{
|
{
|
||||||
array.Add(queue.Dequeue());
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
array.Add(element);
|
||||||
thisID++;
|
thisID++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -431,7 +482,10 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
// }
|
// }
|
||||||
|
|
||||||
Queue<OSD> queue = TryGetQueue(agentID);
|
Queue<OSD> queue = TryGetQueue(agentID);
|
||||||
OSD element = queue.Dequeue(); // 15s timeout
|
OSD element;
|
||||||
|
|
||||||
|
lock (queue)
|
||||||
|
element = queue.Dequeue(); // 15s timeout
|
||||||
|
|
||||||
Hashtable responsedata = new Hashtable();
|
Hashtable responsedata = new Hashtable();
|
||||||
|
|
||||||
|
@ -470,12 +524,34 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
array.Add(element);
|
array.Add(element);
|
||||||
|
|
||||||
|
if (element is OSDMap)
|
||||||
|
{
|
||||||
|
OSDMap ev = (OSDMap)element;
|
||||||
|
m_log.DebugFormat(
|
||||||
|
"[EVENT QUEUE GET MODULE]: Eq OUT {0} to {1}",
|
||||||
|
ev["message"], m_scene.GetScenePresence(agentID).Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
lock (queue)
|
||||||
|
{
|
||||||
while (queue.Count > 0)
|
while (queue.Count > 0)
|
||||||
{
|
{
|
||||||
array.Add(queue.Dequeue());
|
element = queue.Dequeue();
|
||||||
|
|
||||||
|
if (element is OSDMap)
|
||||||
|
{
|
||||||
|
OSDMap ev = (OSDMap)element;
|
||||||
|
m_log.DebugFormat(
|
||||||
|
"[EVENT QUEUE GET MODULE]: Eq OUT {0} to {1}",
|
||||||
|
ev["message"], m_scene.GetScenePresence(agentID).Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
array.Add(element);
|
||||||
thisID++;
|
thisID++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
OSDMap events = new OSDMap();
|
OSDMap events = new OSDMap();
|
||||||
events.Add("events", array);
|
events.Add("events", array);
|
||||||
|
@ -490,7 +566,8 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
responsedata["content_type"] = "application/xml";
|
responsedata["content_type"] = "application/xml";
|
||||||
responsedata["keepalive"] = false;
|
responsedata["keepalive"] = false;
|
||||||
responsedata["str_response_string"] = OSDParser.SerializeLLSDXmlString(events);
|
responsedata["str_response_string"] = OSDParser.SerializeLLSDXmlString(events);
|
||||||
//m_log.DebugFormat("[EVENTQUEUE]: sending response for {0} in region {1}: {2}", agentID, m_scene.RegionInfo.RegionName, responsedata["str_response_string"]);
|
|
||||||
|
m_log.DebugFormat("[EVENTQUEUE]: sending response for {0} in region {1}: {2}", agentID, m_scene.RegionInfo.RegionName, responsedata["str_response_string"]);
|
||||||
|
|
||||||
return responsedata;
|
return responsedata;
|
||||||
}
|
}
|
||||||
|
@ -520,6 +597,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
AvatarID = m_QueueUUIDAvatarMapping[capUUID];
|
AvatarID = m_QueueUUIDAvatarMapping[capUUID];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (AvatarID != UUID.Zero)
|
if (AvatarID != UUID.Zero)
|
||||||
{
|
{
|
||||||
return ProcessQueue(request, AvatarID, m_scene.CapsModule.GetCapsForUser(AvatarID));
|
return ProcessQueue(request, AvatarID, m_scene.CapsModule.GetCapsForUser(AvatarID));
|
||||||
|
@ -712,6 +790,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
OSD item = EventQueueHelper.GroupMembership(groupUpdate);
|
OSD item = EventQueueHelper.GroupMembership(groupUpdate);
|
||||||
Enqueue(item, avatarID);
|
Enqueue(item, avatarID);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void QueryReply(PlacesReplyPacket groupUpdate, UUID avatarID)
|
public void QueryReply(PlacesReplyPacket groupUpdate, UUID avatarID)
|
||||||
{
|
{
|
||||||
OSD item = EventQueueHelper.PlacesQuery(groupUpdate);
|
OSD item = EventQueueHelper.PlacesQuery(groupUpdate);
|
||||||
|
|
|
@ -25,48 +25,55 @@
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Net;
|
||||||
|
using log4net.Config;
|
||||||
|
using Nini.Config;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using OpenMetaverse;
|
||||||
using OpenMetaverse.Packets;
|
using OpenMetaverse.Packets;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Framework.Servers;
|
||||||
|
using OpenSim.Framework.Servers.HttpServer;
|
||||||
|
using OpenSim.Region.ClientStack.Linden;
|
||||||
|
using OpenSim.Region.CoreModules.Framework;
|
||||||
|
using OpenSim.Tests.Common;
|
||||||
|
using OpenSim.Tests.Common.Mock;
|
||||||
|
|
||||||
namespace OpenSim.Region.ClientStack.LindenUDP.Tests
|
namespace OpenSim.Region.ClientStack.Linden.Tests
|
||||||
{
|
{
|
||||||
public class TestLLPacketServer : LLPacketServer
|
[TestFixture]
|
||||||
|
public class EventQueueTests
|
||||||
{
|
{
|
||||||
/// <summary>
|
private TestScene m_scene;
|
||||||
/// Record counts of packets received
|
|
||||||
/// </summary>
|
|
||||||
protected Dictionary<PacketType, int> m_packetsReceived = new Dictionary<PacketType, int>();
|
|
||||||
|
|
||||||
public TestLLPacketServer(LLUDPServer networkHandler, ClientStackUserSettings userSettings)
|
[SetUp]
|
||||||
: base(networkHandler, userSettings)
|
public void SetUp()
|
||||||
{}
|
|
||||||
|
|
||||||
public override void InPacket(uint circuitCode, Packet packet)
|
|
||||||
{
|
{
|
||||||
base.InPacket(circuitCode, packet);
|
MainServer.Instance = new BaseHttpServer(9999, false, 9998, "");
|
||||||
|
|
||||||
if (m_packetsReceived.ContainsKey(packet.Type))
|
IConfigSource config = new IniConfigSource();
|
||||||
m_packetsReceived[packet.Type]++;
|
config.AddConfig("Startup");
|
||||||
else
|
config.Configs["Startup"].Set("EventQueue", "true");
|
||||||
m_packetsReceived[packet.Type] = 1;
|
|
||||||
|
CapabilitiesModule capsModule = new CapabilitiesModule();
|
||||||
|
EventQueueGetModule eqgModule = new EventQueueGetModule();
|
||||||
|
|
||||||
|
m_scene = SceneHelpers.SetupScene();
|
||||||
|
SceneHelpers.SetupSceneModules(m_scene, config, capsModule, eqgModule);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int GetTotalPacketsReceived()
|
[Test]
|
||||||
|
public void AddForClient()
|
||||||
{
|
{
|
||||||
int totalCount = 0;
|
TestHelpers.InMethod();
|
||||||
|
// log4net.Config.XmlConfigurator.Configure();
|
||||||
|
|
||||||
foreach (int count in m_packetsReceived.Values)
|
SceneHelpers.AddScenePresence(m_scene, TestHelpers.ParseTail(0x1));
|
||||||
totalCount += count;
|
|
||||||
|
|
||||||
return totalCount;
|
// TODO: Add more assertions for the other aspects of event queues
|
||||||
}
|
Assert.That(MainServer.Instance.GetPollServiceHandlerKeys().Count, Is.EqualTo(1));
|
||||||
|
|
||||||
public int GetPacketsReceivedFor(PacketType packetType)
|
|
||||||
{
|
|
||||||
if (m_packetsReceived.ContainsKey(packetType))
|
|
||||||
return m_packetsReceived[packetType];
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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;
|
||||||
|
using System.Collections.Specialized;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.IO;
|
||||||
|
using System.Web;
|
||||||
|
using log4net;
|
||||||
|
using Nini.Config;
|
||||||
|
using Mono.Addins;
|
||||||
|
using OpenMetaverse;
|
||||||
|
using OpenMetaverse.StructuredData;
|
||||||
|
using OpenMetaverse.Imaging;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Framework.Servers;
|
||||||
|
using OpenSim.Framework.Servers.HttpServer;
|
||||||
|
using OpenSim.Region.Framework.Interfaces;
|
||||||
|
using OpenSim.Region.Framework.Scenes;
|
||||||
|
using OpenSim.Services.Interfaces;
|
||||||
|
using Caps = OpenSim.Framework.Capabilities.Caps;
|
||||||
|
using OpenSim.Capabilities.Handlers;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.ClientStack.Linden
|
||||||
|
{
|
||||||
|
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
|
||||||
|
public class UploadBakedTextureModule : INonSharedRegionModule
|
||||||
|
{
|
||||||
|
// private static readonly ILog m_log =
|
||||||
|
// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// For historical reasons this is fixed, but there
|
||||||
|
/// </summary>
|
||||||
|
private static readonly string m_uploadBakedTexturePath = "0010/";// This is in the LandManagementModule.
|
||||||
|
|
||||||
|
private Scene m_scene;
|
||||||
|
private bool m_persistBakedTextures;
|
||||||
|
|
||||||
|
public void Initialise(IConfigSource source)
|
||||||
|
{
|
||||||
|
IConfig sconfig = source.Configs["Startup"];
|
||||||
|
if (sconfig != null)
|
||||||
|
m_persistBakedTextures = sconfig.GetBoolean("PersistBakedTextures", m_persistBakedTextures);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddRegion(Scene s)
|
||||||
|
{
|
||||||
|
m_scene = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveRegion(Scene s)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RegionLoaded(Scene s)
|
||||||
|
{
|
||||||
|
m_scene.EventManager.OnRegisterCaps += RegisterCaps;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PostInitialise()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Close() { }
|
||||||
|
|
||||||
|
public string Name { get { return "UploadBakedTextureModule"; } }
|
||||||
|
|
||||||
|
public Type ReplaceableInterface
|
||||||
|
{
|
||||||
|
get { return null; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RegisterCaps(UUID agentID, Caps caps)
|
||||||
|
{
|
||||||
|
caps.RegisterHandler(
|
||||||
|
"UploadBakedTexture",
|
||||||
|
new RestStreamHandler(
|
||||||
|
"POST",
|
||||||
|
"/CAPS/" + caps.CapsObjectPath + m_uploadBakedTexturePath,
|
||||||
|
new UploadBakedTextureHandler(
|
||||||
|
caps, m_scene.AssetService, m_persistBakedTextures).UploadBakedTexture));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -45,6 +45,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
private const int IMAGE_PACKET_SIZE = 1000;
|
private const int IMAGE_PACKET_SIZE = 1000;
|
||||||
private const int FIRST_PACKET_SIZE = 600;
|
private const int FIRST_PACKET_SIZE = 600;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If we've requested an asset but not received it in this ticks timeframe, then allow a duplicate
|
||||||
|
/// request from the client to trigger a fresh asset request.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// There are 10,000 ticks in a millisecond
|
||||||
|
/// </remarks>
|
||||||
|
private const int ASSET_REQUEST_TIMEOUT = 100000000;
|
||||||
|
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
public uint LastSequence;
|
public uint LastSequence;
|
||||||
|
@ -56,9 +65,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
public IAssetService AssetService;
|
public IAssetService AssetService;
|
||||||
public UUID AgentID;
|
public UUID AgentID;
|
||||||
public IInventoryAccessModule InventoryAccessModule;
|
public IInventoryAccessModule InventoryAccessModule;
|
||||||
public OpenJPEG.J2KLayerInfo[] Layers;
|
private OpenJPEG.J2KLayerInfo[] m_layers;
|
||||||
public bool IsDecoded;
|
|
||||||
public bool HasAsset;
|
/// <summary>
|
||||||
|
/// Has this request decoded the asset data?
|
||||||
|
/// </summary>
|
||||||
|
public bool IsDecoded { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Has this request received the required asset data?
|
||||||
|
/// </summary>
|
||||||
|
public bool HasAsset { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Time in milliseconds at which the asset was requested.
|
||||||
|
/// </summary>
|
||||||
|
public long AssetRequestTime { get; private set; }
|
||||||
|
|
||||||
public C5.IPriorityQueueHandle<J2KImage> PriorityQueueHandle;
|
public C5.IPriorityQueueHandle<J2KImage> PriorityQueueHandle;
|
||||||
|
|
||||||
private uint m_currentPacket;
|
private uint m_currentPacket;
|
||||||
|
@ -82,7 +105,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
/// <param name="packetsToSend">Maximum number of packets to send during this call</param>
|
/// <param name="packetsToSend">Maximum number of packets to send during this call</param>
|
||||||
/// <param name="packetsSent">Number of packets sent during this call</param>
|
/// <param name="packetsSent">Number of packets sent during this call</param>
|
||||||
/// <returns>True if the transfer completes at the current discard level, otherwise false</returns>
|
/// <returns>True if the transfer completes at the current discard level, otherwise false</returns>
|
||||||
public bool SendPackets(LLClientView client, int packetsToSend, out int packetsSent)
|
public bool SendPackets(IClientAPI client, int packetsToSend, out int packetsSent)
|
||||||
{
|
{
|
||||||
packetsSent = 0;
|
packetsSent = 0;
|
||||||
|
|
||||||
|
@ -114,17 +137,24 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
return (m_currentPacket > m_stopPacket);
|
return (m_currentPacket > m_stopPacket);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This is where we decide what we need to update
|
||||||
|
/// and assign the real discardLevel and packetNumber
|
||||||
|
/// assuming of course that the connected client might be bonkers
|
||||||
|
/// </summary>
|
||||||
public void RunUpdate()
|
public void RunUpdate()
|
||||||
{
|
{
|
||||||
//This is where we decide what we need to update
|
|
||||||
//and assign the real discardLevel and packetNumber
|
|
||||||
//assuming of course that the connected client might be bonkers
|
|
||||||
|
|
||||||
if (!HasAsset)
|
if (!HasAsset)
|
||||||
{
|
{
|
||||||
if (!m_assetRequested)
|
if (!m_assetRequested || DateTime.UtcNow.Ticks > AssetRequestTime + ASSET_REQUEST_TIMEOUT)
|
||||||
{
|
{
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[J2KIMAGE]: Requesting asset {0} from request in packet {1}, already requested? {2}, due to timeout? {3}",
|
||||||
|
// TextureID, LastSequence, m_assetRequested, DateTime.UtcNow.Ticks > AssetRequestTime + ASSET_REQUEST_TIMEOUT);
|
||||||
|
|
||||||
m_assetRequested = true;
|
m_assetRequested = true;
|
||||||
|
AssetRequestTime = DateTime.UtcNow.Ticks;
|
||||||
|
|
||||||
AssetService.Get(TextureID.ToString(), this, AssetReceived);
|
AssetService.Get(TextureID.ToString(), this, AssetReceived);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -137,6 +167,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
{
|
{
|
||||||
//Request decode
|
//Request decode
|
||||||
m_decodeRequested = true;
|
m_decodeRequested = true;
|
||||||
|
|
||||||
|
// m_log.DebugFormat("[J2KIMAGE]: Requesting decode of asset {0}", TextureID);
|
||||||
|
|
||||||
// Do we have a jpeg decoder?
|
// Do we have a jpeg decoder?
|
||||||
if (J2KDecoder != null)
|
if (J2KDecoder != null)
|
||||||
{
|
{
|
||||||
|
@ -149,7 +182,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
// Send it off to the jpeg decoder
|
// Send it off to the jpeg decoder
|
||||||
J2KDecoder.BeginDecode(TextureID, m_asset, J2KDecodedCallback);
|
J2KDecoder.BeginDecode(TextureID, m_asset, J2KDecodedCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -170,14 +202,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
if (DiscardLevel >= 0 || m_stopPacket == 0)
|
if (DiscardLevel >= 0 || m_stopPacket == 0)
|
||||||
{
|
{
|
||||||
// This shouldn't happen, but if it does, we really can't proceed
|
// This shouldn't happen, but if it does, we really can't proceed
|
||||||
if (Layers == null)
|
if (m_layers == null)
|
||||||
{
|
{
|
||||||
m_log.Warn("[J2KIMAGE]: RunUpdate() called with missing Layers. Canceling texture transfer");
|
m_log.Warn("[J2KIMAGE]: RunUpdate() called with missing Layers. Canceling texture transfer");
|
||||||
m_currentPacket = m_stopPacket;
|
m_currentPacket = m_stopPacket;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int maxDiscardLevel = Math.Max(0, Layers.Length - 1);
|
int maxDiscardLevel = Math.Max(0, m_layers.Length - 1);
|
||||||
|
|
||||||
// Treat initial texture downloads with a DiscardLevel of -1 a request for the highest DiscardLevel
|
// Treat initial texture downloads with a DiscardLevel of -1 a request for the highest DiscardLevel
|
||||||
if (DiscardLevel < 0 && m_stopPacket == 0)
|
if (DiscardLevel < 0 && m_stopPacket == 0)
|
||||||
|
@ -187,9 +219,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
DiscardLevel = (sbyte)Math.Min(DiscardLevel, maxDiscardLevel);
|
DiscardLevel = (sbyte)Math.Min(DiscardLevel, maxDiscardLevel);
|
||||||
|
|
||||||
//Calculate the m_stopPacket
|
//Calculate the m_stopPacket
|
||||||
if (Layers.Length > 0)
|
if (m_layers.Length > 0)
|
||||||
{
|
{
|
||||||
m_stopPacket = (uint)GetPacketForBytePosition(Layers[(Layers.Length - 1) - DiscardLevel].End);
|
m_stopPacket = (uint)GetPacketForBytePosition(m_layers[(m_layers.Length - 1) - DiscardLevel].End);
|
||||||
//I don't know why, but the viewer seems to expect the final packet if the file
|
//I don't know why, but the viewer seems to expect the final packet if the file
|
||||||
//is just one packet bigger.
|
//is just one packet bigger.
|
||||||
if (TexturePacketCount() == m_stopPacket + 1)
|
if (TexturePacketCount() == m_stopPacket + 1)
|
||||||
|
@ -208,7 +240,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool SendFirstPacket(LLClientView client)
|
private bool SendFirstPacket(IClientAPI client)
|
||||||
{
|
{
|
||||||
if (client == null)
|
if (client == null)
|
||||||
return false;
|
return false;
|
||||||
|
@ -243,7 +275,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool SendPacket(LLClientView client)
|
private bool SendPacket(IClientAPI client)
|
||||||
{
|
{
|
||||||
if (client == null)
|
if (client == null)
|
||||||
return false;
|
return false;
|
||||||
|
@ -328,20 +360,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
{
|
{
|
||||||
if (m_currentPacket == 0)
|
if (m_currentPacket == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (m_currentPacket == 1)
|
if (m_currentPacket == 1)
|
||||||
return FIRST_PACKET_SIZE;
|
return FIRST_PACKET_SIZE;
|
||||||
|
|
||||||
int result = FIRST_PACKET_SIZE + ((int)m_currentPacket - 2) * IMAGE_PACKET_SIZE;
|
int result = FIRST_PACKET_SIZE + ((int)m_currentPacket - 2) * IMAGE_PACKET_SIZE;
|
||||||
|
|
||||||
if (result < 0)
|
if (result < 0)
|
||||||
{
|
|
||||||
result = FIRST_PACKET_SIZE;
|
result = FIRST_PACKET_SIZE;
|
||||||
}
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void J2KDecodedCallback(UUID AssetId, OpenJPEG.J2KLayerInfo[] layers)
|
private void J2KDecodedCallback(UUID AssetId, OpenJPEG.J2KLayerInfo[] layers)
|
||||||
{
|
{
|
||||||
Layers = layers;
|
m_layers = layers;
|
||||||
IsDecoded = true;
|
IsDecoded = true;
|
||||||
RunUpdate();
|
RunUpdate();
|
||||||
}
|
}
|
||||||
|
@ -372,9 +405,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
|
||||||
private void AssetReceived(string id, Object sender, AssetBase asset)
|
private void AssetReceived(string id, Object sender, AssetBase asset)
|
||||||
{
|
{
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[J2KIMAGE]: Received asset {0} ({1} bytes)", id, asset != null ? asset.Data.Length.ToString() : "n/a");
|
||||||
|
|
||||||
UUID assetID = UUID.Zero;
|
UUID assetID = UUID.Zero;
|
||||||
if (asset != null)
|
if (asset != null)
|
||||||
|
{
|
||||||
assetID = asset.FullID;
|
assetID = asset.FullID;
|
||||||
|
}
|
||||||
else if ((InventoryAccessModule != null) && (sender != InventoryAccessModule))
|
else if ((InventoryAccessModule != null) && (sender != InventoryAccessModule))
|
||||||
{
|
{
|
||||||
// Unfortunately we need this here, there's no other way.
|
// Unfortunately we need this here, there's no other way.
|
||||||
|
@ -392,7 +430,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
}
|
}
|
||||||
|
|
||||||
AssetDataCallback(assetID, asset);
|
AssetDataCallback(assetID, asset);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,7 +64,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
/// <value>
|
/// <value>
|
||||||
/// Debug packet level. See OpenSim.RegisterConsoleCommands() for more details.
|
/// Debug packet level. See OpenSim.RegisterConsoleCommands() for more details.
|
||||||
/// </value>
|
/// </value>
|
||||||
protected int m_debugPacketLevel = 0;
|
public int DebugPacketLevel { get; set; }
|
||||||
|
|
||||||
#region Events
|
#region Events
|
||||||
|
|
||||||
|
@ -303,6 +303,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
protected static Dictionary<PacketType, PacketMethod> PacketHandlers = new Dictionary<PacketType, PacketMethod>(); //Global/static handlers for all clients
|
protected static Dictionary<PacketType, PacketMethod> PacketHandlers = new Dictionary<PacketType, PacketMethod>(); //Global/static handlers for all clients
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handles UDP texture download.
|
||||||
|
/// </summary>
|
||||||
|
public LLImageManager ImageManager { get; private set; }
|
||||||
|
|
||||||
private readonly LLUDPServer m_udpServer;
|
private readonly LLUDPServer m_udpServer;
|
||||||
private readonly LLUDPClient m_udpClient;
|
private readonly LLUDPClient m_udpClient;
|
||||||
private readonly UUID m_sessionId;
|
private readonly UUID m_sessionId;
|
||||||
|
@ -347,7 +352,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
protected Dictionary<PacketType, PacketProcessor> m_packetHandlers = new Dictionary<PacketType, PacketProcessor>();
|
protected Dictionary<PacketType, PacketProcessor> m_packetHandlers = new Dictionary<PacketType, PacketProcessor>();
|
||||||
protected Dictionary<string, GenericMessage> m_genericPacketHandlers = new Dictionary<string, GenericMessage>(); //PauPaw:Local Generic Message handlers
|
protected Dictionary<string, GenericMessage> m_genericPacketHandlers = new Dictionary<string, GenericMessage>(); //PauPaw:Local Generic Message handlers
|
||||||
protected Scene m_scene;
|
protected Scene m_scene;
|
||||||
protected LLImageManager m_imageManager;
|
|
||||||
protected string m_firstName;
|
protected string m_firstName;
|
||||||
protected string m_lastName;
|
protected string m_lastName;
|
||||||
protected Thread m_clientThread;
|
protected Thread m_clientThread;
|
||||||
|
@ -379,6 +383,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
set { m_startpos = value; }
|
set { m_startpos = value; }
|
||||||
}
|
}
|
||||||
public UUID AgentId { get { return m_agentId; } }
|
public UUID AgentId { get { return m_agentId; } }
|
||||||
|
public ISceneAgent SceneAgent { get; private set; }
|
||||||
public UUID ActiveGroupId { get { return m_activeGroupID; } }
|
public UUID ActiveGroupId { get { return m_activeGroupID; } }
|
||||||
public string ActiveGroupName { get { return m_activeGroupName; } }
|
public string ActiveGroupName { get { return m_activeGroupName; } }
|
||||||
public ulong ActiveGroupPowers { get { return m_activeGroupPowers; } }
|
public ulong ActiveGroupPowers { get { return m_activeGroupPowers; } }
|
||||||
|
@ -455,7 +460,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
|
||||||
m_assetService = m_scene.RequestModuleInterface<IAssetService>();
|
m_assetService = m_scene.RequestModuleInterface<IAssetService>();
|
||||||
m_GroupsModule = scene.RequestModuleInterface<IGroupsModule>();
|
m_GroupsModule = scene.RequestModuleInterface<IGroupsModule>();
|
||||||
m_imageManager = new LLImageManager(this, m_assetService, Scene.RequestModuleInterface<IJ2KDecoder>());
|
ImageManager = new LLImageManager(this, m_assetService, Scene.RequestModuleInterface<IJ2KDecoder>());
|
||||||
m_channelVersion = Util.StringToBytes256(scene.GetSimulatorVersion());
|
m_channelVersion = Util.StringToBytes256(scene.GetSimulatorVersion());
|
||||||
m_agentId = agentId;
|
m_agentId = agentId;
|
||||||
m_sessionId = sessionId;
|
m_sessionId = sessionId;
|
||||||
|
@ -477,11 +482,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
RegisterLocalPacketHandlers();
|
RegisterLocalPacketHandlers();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetDebugPacketLevel(int newDebug)
|
|
||||||
{
|
|
||||||
m_debugPacketLevel = newDebug;
|
|
||||||
}
|
|
||||||
|
|
||||||
#region Client Methods
|
#region Client Methods
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -500,8 +500,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
IsActive = false;
|
IsActive = false;
|
||||||
|
|
||||||
// Shutdown the image manager
|
// Shutdown the image manager
|
||||||
if (m_imageManager != null)
|
ImageManager.Close();
|
||||||
m_imageManager.Close();
|
|
||||||
|
|
||||||
// Fire the callback for this connection closing
|
// Fire the callback for this connection closing
|
||||||
if (OnConnectionClosed != null)
|
if (OnConnectionClosed != null)
|
||||||
|
@ -513,6 +512,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
|
||||||
// Remove ourselves from the scene
|
// Remove ourselves from the scene
|
||||||
m_scene.RemoveClient(AgentId, true);
|
m_scene.RemoveClient(AgentId, true);
|
||||||
|
SceneAgent = null;
|
||||||
|
|
||||||
// We can't reach into other scenes and close the connection
|
// We can't reach into other scenes and close the connection
|
||||||
// We need to do this over grid communications
|
// We need to do this over grid communications
|
||||||
|
@ -528,7 +528,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
|
||||||
public void Kick(string message)
|
public void Kick(string message)
|
||||||
{
|
{
|
||||||
if (!ChildAgentStatus())
|
if (!SceneAgent.IsChildAgent)
|
||||||
{
|
{
|
||||||
KickUserPacket kupack = (KickUserPacket)PacketPool.Instance.GetPacket(PacketType.KickUser);
|
KickUserPacket kupack = (KickUserPacket)PacketPool.Instance.GetPacket(PacketType.KickUser);
|
||||||
kupack.UserInfo.AgentID = AgentId;
|
kupack.UserInfo.AgentID = AgentId;
|
||||||
|
@ -577,8 +577,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Add a handler for the given packet type.
|
/// Add a handler for the given packet type.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>The packet is handled on its own thread. If packets must be handled in the order in which thye
|
/// <remarks>
|
||||||
/// are received then please us ethe synchronous version of this method.</remarks>
|
/// The packet is handled on its own thread. If packets must be handled in the order in which they
|
||||||
|
/// are received then please use the synchronous version of this method.
|
||||||
|
/// </remarks>
|
||||||
/// <param name="packetType"></param>
|
/// <param name="packetType"></param>
|
||||||
/// <param name="handler"></param>
|
/// <param name="handler"></param>
|
||||||
/// <returns>true if the handler was added. This is currently always the case.</returns>
|
/// <returns>true if the handler was added. This is currently always the case.</returns>
|
||||||
|
@ -692,7 +694,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
|
||||||
public virtual void Start()
|
public virtual void Start()
|
||||||
{
|
{
|
||||||
m_scene.AddNewClient(this, PresenceType.User);
|
SceneAgent = m_scene.AddNewClient(this, PresenceType.User);
|
||||||
|
|
||||||
RefreshGroupMembership();
|
RefreshGroupMembership();
|
||||||
}
|
}
|
||||||
|
@ -1963,8 +1965,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
SendBulkUpdateInventoryItem((InventoryItemBase)node);
|
SendBulkUpdateInventoryItem((InventoryItemBase)node);
|
||||||
else if (node is InventoryFolderBase)
|
else if (node is InventoryFolderBase)
|
||||||
SendBulkUpdateInventoryFolder((InventoryFolderBase)node);
|
SendBulkUpdateInventoryFolder((InventoryFolderBase)node);
|
||||||
|
else if (node != null)
|
||||||
|
m_log.ErrorFormat("[CLIENT]: {0} sent unknown inventory node named {1}", Name, node.Name);
|
||||||
else
|
else
|
||||||
m_log.ErrorFormat("[CLIENT]: Client for {0} sent unknown inventory node named {1}", Name, node.Name);
|
m_log.ErrorFormat("[CLIENT]: {0} sent null inventory node", Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void SendBulkUpdateInventoryItem(InventoryItemBase item)
|
protected void SendBulkUpdateInventoryItem(InventoryItemBase item)
|
||||||
|
@ -2444,7 +2448,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
/// <param name="Message"></param>
|
/// <param name="Message"></param>
|
||||||
public void SendBlueBoxMessage(UUID FromAvatarID, String FromAvatarName, String Message)
|
public void SendBlueBoxMessage(UUID FromAvatarID, String FromAvatarName, String Message)
|
||||||
{
|
{
|
||||||
if (!ChildAgentStatus())
|
if (!SceneAgent.IsChildAgent)
|
||||||
SendInstantMessage(new GridInstantMessage(null, FromAvatarID, FromAvatarName, AgentId, 1, Message, false, new Vector3()));
|
SendInstantMessage(new GridInstantMessage(null, FromAvatarID, FromAvatarName, AgentId, 1, Message, false, new Vector3()));
|
||||||
|
|
||||||
//SendInstantMessage(FromAvatarID, fromSessionID, Message, AgentId, SessionId, FromAvatarName, (byte)21,(uint) Util.UnixTimeSinceEpoch());
|
//SendInstantMessage(FromAvatarID, fromSessionID, Message, AgentId, SessionId, FromAvatarName, (byte)21,(uint) Util.UnixTimeSinceEpoch());
|
||||||
|
@ -3592,7 +3596,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
/// Generate one of the object update packets based on PrimUpdateFlags
|
/// Generate one of the object update packets based on PrimUpdateFlags
|
||||||
/// and broadcast the packet to clients
|
/// and broadcast the packet to clients
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void SendPrimUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
|
public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
|
||||||
{
|
{
|
||||||
//double priority = m_prioritizer.GetUpdatePriority(this, entity);
|
//double priority = m_prioritizer.GetUpdatePriority(this, entity);
|
||||||
uint priority = m_prioritizer.GetUpdatePriority(this, entity);
|
uint priority = m_prioritizer.GetUpdatePriority(this, entity);
|
||||||
|
@ -3625,7 +3629,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void ResendPrimUpdates(List<EntityUpdate> updates, OutgoingPacket oPacket)
|
private void ResendPrimUpdates(List<EntityUpdate> updates, OutgoingPacket oPacket)
|
||||||
{
|
{
|
||||||
// m_log.WarnFormat("[CLIENT] resending prim update {0}",updates[0].UpdateTime);
|
// m_log.WarnFormat("[CLIENT] resending prim updates {0}, packet sequence number {1}", updates[0].UpdateTime, oPacket.SequenceNumber);
|
||||||
|
|
||||||
// Remove the update packet from the list of packets waiting for acknowledgement
|
// Remove the update packet from the list of packets waiting for acknowledgement
|
||||||
// because we are requeuing the list of updates. They will be resent in new packets
|
// because we are requeuing the list of updates. They will be resent in new packets
|
||||||
|
@ -3931,15 +3935,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((categories & ThrottleOutPacketTypeFlags.Texture) != 0)
|
if ((categories & ThrottleOutPacketTypeFlags.Texture) != 0)
|
||||||
{
|
ImageManager.ProcessImageQueue(m_udpServer.TextureSendLimit);
|
||||||
ProcessTextureRequests();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ProcessTextureRequests()
|
|
||||||
{
|
|
||||||
if (m_imageManager != null)
|
|
||||||
m_imageManager.ProcessImageQueue(m_udpServer.TextureSendLimit);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendAssetUploadCompleteMessage(sbyte AssetType, bool Success, UUID AssetFullID)
|
public void SendAssetUploadCompleteMessage(sbyte AssetType, bool Success, UUID AssetFullID)
|
||||||
|
@ -4744,6 +4740,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
position = presence.OffsetPosition;
|
position = presence.OffsetPosition;
|
||||||
velocity = presence.Velocity;
|
velocity = presence.Velocity;
|
||||||
acceleration = Vector3.Zero;
|
acceleration = Vector3.Zero;
|
||||||
|
|
||||||
|
// Interestingly, sending this to non-zero will cause the client's avatar to start moving & accelerating
|
||||||
|
// in that direction, even though we don't model this on the server. Implementing this in the future
|
||||||
|
// may improve movement smoothness.
|
||||||
|
// acceleration = new Vector3(1, 0, 0);
|
||||||
|
|
||||||
angularVelocity = Vector3.Zero;
|
angularVelocity = Vector3.Zero;
|
||||||
rotation = presence.Rotation;
|
rotation = presence.Rotation;
|
||||||
|
|
||||||
|
@ -4854,8 +4856,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
|
||||||
data.CollisionPlane.ToBytes(objectData, 0);
|
data.CollisionPlane.ToBytes(objectData, 0);
|
||||||
data.OffsetPosition.ToBytes(objectData, 16);
|
data.OffsetPosition.ToBytes(objectData, 16);
|
||||||
//data.Velocity.ToBytes(objectData, 28);
|
// data.Velocity.ToBytes(objectData, 28);
|
||||||
//data.Acceleration.ToBytes(objectData, 40);
|
// data.Acceleration.ToBytes(objectData, 40);
|
||||||
data.Rotation.ToBytes(objectData, 52);
|
data.Rotation.ToBytes(objectData, 52);
|
||||||
//data.AngularVelocity.ToBytes(objectData, 64);
|
//data.AngularVelocity.ToBytes(objectData, 64);
|
||||||
|
|
||||||
|
@ -4880,8 +4882,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
update.Scale = new Vector3(0.45f, 0.6f, 1.9f);
|
update.Scale = new Vector3(0.45f, 0.6f, 1.9f);
|
||||||
update.Text = Utils.EmptyBytes;
|
update.Text = Utils.EmptyBytes;
|
||||||
update.TextColor = new byte[4];
|
update.TextColor = new byte[4];
|
||||||
|
|
||||||
|
// Don't send texture anim for avatars - this has no meaning for them.
|
||||||
update.TextureAnim = Utils.EmptyBytes;
|
update.TextureAnim = Utils.EmptyBytes;
|
||||||
update.TextureEntry = (data.Appearance.Texture != null) ? data.Appearance.Texture.GetBytes() : Utils.EmptyBytes;
|
|
||||||
|
// Don't send texture entry for avatars here - this is accomplished via the AvatarAppearance packet
|
||||||
|
update.TextureEntry = Utils.EmptyBytes;
|
||||||
|
// update.TextureEntry = (data.Appearance.Texture != null) ? data.Appearance.Texture.GetBytes() : Utils.EmptyBytes;
|
||||||
|
|
||||||
update.UpdateFlags = (uint)(
|
update.UpdateFlags = (uint)(
|
||||||
PrimFlags.Physics | PrimFlags.ObjectModify | PrimFlags.ObjectCopy | PrimFlags.ObjectAnyOwner |
|
PrimFlags.Physics | PrimFlags.ObjectModify | PrimFlags.ObjectCopy | PrimFlags.ObjectAnyOwner |
|
||||||
PrimFlags.ObjectYouOwner | PrimFlags.ObjectMove | PrimFlags.InventoryEmpty | PrimFlags.ObjectTransfer |
|
PrimFlags.ObjectYouOwner | PrimFlags.ObjectMove | PrimFlags.InventoryEmpty | PrimFlags.ObjectTransfer |
|
||||||
|
@ -5044,14 +5052,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// This is a utility method used by single states to not duplicate kicks and blue card of death messages.
|
|
||||||
/// </summary>
|
|
||||||
public bool ChildAgentStatus()
|
|
||||||
{
|
|
||||||
return m_scene.PresenceChildStatus(AgentId);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -7465,12 +7465,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
if ((ImageType)block.Type == ImageType.Baked)
|
if ((ImageType)block.Type == ImageType.Baked)
|
||||||
args.Priority *= 2.0f;
|
args.Priority *= 2.0f;
|
||||||
|
|
||||||
// in the end, we null this, so we have to check if it's null
|
ImageManager.EnqueueReq(args);
|
||||||
if (m_imageManager != null)
|
|
||||||
{
|
|
||||||
m_imageManager.EnqueueReq(args);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10328,6 +10325,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool HandleGroupRoleMembersRequest(IClientAPI sender, Packet Pack)
|
private bool HandleGroupRoleMembersRequest(IClientAPI sender, Packet Pack)
|
||||||
{
|
{
|
||||||
GroupRoleMembersRequestPacket groupRoleMembersRequest =
|
GroupRoleMembersRequestPacket groupRoleMembersRequest =
|
||||||
|
@ -11588,29 +11586,31 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
/// provide your own method.</param>
|
/// provide your own method.</param>
|
||||||
protected void OutPacket(Packet packet, ThrottleOutPacketType throttlePacketType, bool doAutomaticSplitting, UnackedPacketMethod method)
|
protected void OutPacket(Packet packet, ThrottleOutPacketType throttlePacketType, bool doAutomaticSplitting, UnackedPacketMethod method)
|
||||||
{
|
{
|
||||||
if (m_debugPacketLevel > 0)
|
if (DebugPacketLevel > 0)
|
||||||
{
|
{
|
||||||
bool logPacket = true;
|
bool logPacket = true;
|
||||||
|
|
||||||
if (m_debugPacketLevel <= 255
|
if (DebugPacketLevel <= 255
|
||||||
&& (packet.Type == PacketType.SimStats || packet.Type == PacketType.SimulatorViewerTimeMessage))
|
&& (packet.Type == PacketType.SimStats || packet.Type == PacketType.SimulatorViewerTimeMessage))
|
||||||
logPacket = false;
|
logPacket = false;
|
||||||
|
|
||||||
if (m_debugPacketLevel <= 200
|
if (DebugPacketLevel <= 200
|
||||||
&& (packet.Type == PacketType.ImagePacket
|
&& (packet.Type == PacketType.ImagePacket
|
||||||
|| packet.Type == PacketType.ImageData
|
|| packet.Type == PacketType.ImageData
|
||||||
|| packet.Type == PacketType.LayerData
|
|| packet.Type == PacketType.LayerData
|
||||||
|| packet.Type == PacketType.CoarseLocationUpdate))
|
|| packet.Type == PacketType.CoarseLocationUpdate))
|
||||||
logPacket = false;
|
logPacket = false;
|
||||||
|
|
||||||
if (m_debugPacketLevel <= 100 && (packet.Type == PacketType.AvatarAnimation || packet.Type == PacketType.ViewerEffect))
|
if (DebugPacketLevel <= 100 && (packet.Type == PacketType.AvatarAnimation || packet.Type == PacketType.ViewerEffect))
|
||||||
logPacket = false;
|
logPacket = false;
|
||||||
|
|
||||||
if (m_debugPacketLevel <= 50 && packet.Type == PacketType.ImprovedTerseObjectUpdate)
|
if (DebugPacketLevel <= 50 && packet.Type == PacketType.ImprovedTerseObjectUpdate)
|
||||||
logPacket = false;
|
logPacket = false;
|
||||||
|
|
||||||
if (logPacket)
|
if (logPacket)
|
||||||
m_log.DebugFormat("[CLIENT]: Packet OUT {0}", packet.Type);
|
m_log.DebugFormat(
|
||||||
|
"[CLIENT]: PACKET OUT to {0} ({1}) in {2} - {3}",
|
||||||
|
Name, SceneAgent.IsChildAgent ? "child" : "root ", m_scene.RegionInfo.RegionName, packet.Type);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_udpServer.SendPacket(m_udpClient, packet, throttlePacketType, doAutomaticSplitting, method);
|
m_udpServer.SendPacket(m_udpClient, packet, throttlePacketType, doAutomaticSplitting, method);
|
||||||
|
@ -11651,21 +11651,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
/// <param name="Pack">OpenMetaverse.packet</param>
|
/// <param name="Pack">OpenMetaverse.packet</param>
|
||||||
public void ProcessInPacket(Packet packet)
|
public void ProcessInPacket(Packet packet)
|
||||||
{
|
{
|
||||||
if (m_debugPacketLevel > 0)
|
if (DebugPacketLevel > 0)
|
||||||
{
|
{
|
||||||
bool outputPacket = true;
|
bool logPacket = true;
|
||||||
|
|
||||||
if (m_debugPacketLevel <= 255 && packet.Type == PacketType.AgentUpdate)
|
if (DebugPacketLevel <= 255 && packet.Type == PacketType.AgentUpdate)
|
||||||
outputPacket = false;
|
logPacket = false;
|
||||||
|
|
||||||
if (m_debugPacketLevel <= 200 && packet.Type == PacketType.RequestImage)
|
if (DebugPacketLevel <= 200 && packet.Type == PacketType.RequestImage)
|
||||||
outputPacket = false;
|
logPacket = false;
|
||||||
|
|
||||||
if (m_debugPacketLevel <= 100 && (packet.Type == PacketType.ViewerEffect || packet.Type == PacketType.AgentAnimation))
|
if (DebugPacketLevel <= 100 && (packet.Type == PacketType.ViewerEffect || packet.Type == PacketType.AgentAnimation))
|
||||||
outputPacket = false;
|
logPacket = false;
|
||||||
|
|
||||||
if (outputPacket)
|
if (logPacket)
|
||||||
m_log.DebugFormat("[CLIENT]: Packet IN {0}", packet.Type);
|
m_log.DebugFormat(
|
||||||
|
"[CLIENT]: PACKET IN from {0} ({1}) in {2} - {3}",
|
||||||
|
Name, SceneAgent.IsChildAgent ? "child" : "root ", m_scene.RegionInfo.RegionName, packet.Type);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ProcessPacketMethod(packet))
|
if (!ProcessPacketMethod(packet))
|
||||||
|
|
|
@ -39,6 +39,9 @@ using log4net;
|
||||||
|
|
||||||
namespace OpenSim.Region.ClientStack.LindenUDP
|
namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This class handles UDP texture requests.
|
||||||
|
/// </summary>
|
||||||
public class LLImageManager
|
public class LLImageManager
|
||||||
{
|
{
|
||||||
private sealed class J2KImageComparer : IComparer<J2KImage>
|
private sealed class J2KImageComparer : IComparer<J2KImage>
|
||||||
|
@ -52,18 +55,29 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
private bool m_shuttingdown;
|
private bool m_shuttingdown;
|
||||||
private AssetBase m_missingImage;
|
private AssetBase m_missingImage;
|
||||||
private LLClientView m_client; //Client we're assigned to
|
private IAssetService m_assetCache;
|
||||||
private IAssetService m_assetCache; //Asset Cache
|
private IJ2KDecoder m_j2kDecodeModule;
|
||||||
private IJ2KDecoder m_j2kDecodeModule; //Our J2K module
|
|
||||||
|
/// <summary>
|
||||||
|
/// Priority queue for determining which image to send first.
|
||||||
|
/// </summary>
|
||||||
private C5.IntervalHeap<J2KImage> m_priorityQueue = new C5.IntervalHeap<J2KImage>(10, new J2KImageComparer());
|
private C5.IntervalHeap<J2KImage> m_priorityQueue = new C5.IntervalHeap<J2KImage>(10, new J2KImageComparer());
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Used to control thread access to the priority queue.
|
||||||
|
/// </summary>
|
||||||
private object m_syncRoot = new object();
|
private object m_syncRoot = new object();
|
||||||
|
|
||||||
public LLClientView Client { get { return m_client; } }
|
/// <summary>
|
||||||
|
/// Client served by this image manager
|
||||||
|
/// </summary>
|
||||||
|
public IClientAPI Client { get; private set; }
|
||||||
|
|
||||||
public AssetBase MissingImage { get { return m_missingImage; } }
|
public AssetBase MissingImage { get { return m_missingImage; } }
|
||||||
|
|
||||||
public LLImageManager(LLClientView client, IAssetService pAssetCache, IJ2KDecoder pJ2kDecodeModule)
|
public LLImageManager(IClientAPI client, IAssetService pAssetCache, IJ2KDecoder pJ2kDecodeModule)
|
||||||
{
|
{
|
||||||
m_client = client;
|
Client = client;
|
||||||
m_assetCache = pAssetCache;
|
m_assetCache = pAssetCache;
|
||||||
|
|
||||||
if (pAssetCache != null)
|
if (pAssetCache != null)
|
||||||
|
@ -81,7 +95,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
/// <param name="newRequest"></param>
|
/// <param name="newRequest"></param>
|
||||||
public void EnqueueReq(TextureRequestArgs newRequest)
|
public void EnqueueReq(TextureRequestArgs newRequest)
|
||||||
{
|
{
|
||||||
//Make sure we're not shutting down..
|
|
||||||
if (!m_shuttingdown)
|
if (!m_shuttingdown)
|
||||||
{
|
{
|
||||||
J2KImage imgrequest;
|
J2KImage imgrequest;
|
||||||
|
@ -105,8 +118,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//m_log.DebugFormat("[TEX]: (UPD) ID={0}: D={1}, S={2}, P={3}",
|
// m_log.DebugFormat(
|
||||||
// newRequest.RequestedAssetID, newRequest.DiscardLevel, newRequest.PacketNumber, newRequest.Priority);
|
// "[LL IMAGE MANAGER]: Received duplicate of existing request for {0}, start packet {1} from {2}",
|
||||||
|
// newRequest.RequestedAssetID, newRequest.PacketNumber, m_client.Name);
|
||||||
|
|
||||||
|
// m_log.DebugFormat("[TEX]: (UPD) ID={0}: D={1}, S={2}, P={3}",
|
||||||
|
// newRequest.RequestedAssetID, newRequest.DiscardLevel, newRequest.PacketNumber, newRequest.Priority);
|
||||||
|
|
||||||
//Check the packet sequence to make sure this isn't older than
|
//Check the packet sequence to make sure this isn't older than
|
||||||
//one we've already received
|
//one we've already received
|
||||||
|
@ -123,11 +140,34 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
|
||||||
//Update the requested priority
|
//Update the requested priority
|
||||||
imgrequest.Priority = newRequest.Priority;
|
imgrequest.Priority = newRequest.Priority;
|
||||||
|
|
||||||
UpdateImageInQueue(imgrequest);
|
UpdateImageInQueue(imgrequest);
|
||||||
|
|
||||||
//Run an update
|
|
||||||
imgrequest.RunUpdate();
|
imgrequest.RunUpdate();
|
||||||
|
|
||||||
|
// J2KImage imgrequest2 = new J2KImage(this);
|
||||||
|
// imgrequest2.J2KDecoder = m_j2kDecodeModule;
|
||||||
|
// imgrequest2.AssetService = m_assetCache;
|
||||||
|
// imgrequest2.AgentID = m_client.AgentId;
|
||||||
|
// imgrequest2.InventoryAccessModule = m_client.Scene.RequestModuleInterface<IInventoryAccessModule>();
|
||||||
|
// imgrequest2.DiscardLevel = newRequest.DiscardLevel;
|
||||||
|
// imgrequest2.StartPacket = Math.Max(1, newRequest.PacketNumber);
|
||||||
|
// imgrequest2.Priority = newRequest.Priority;
|
||||||
|
// imgrequest2.TextureID = newRequest.RequestedAssetID;
|
||||||
|
// imgrequest2.Priority = newRequest.Priority;
|
||||||
|
//
|
||||||
|
// //Add this download to the priority queue
|
||||||
|
// AddImageToQueue(imgrequest2);
|
||||||
|
//
|
||||||
|
// imgrequest2.RunUpdate();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[LL IMAGE MANAGER]: Ignoring duplicate of existing request for {0} (sequence {1}) from {2} as its request sequence {3} is not greater",
|
||||||
|
// newRequest.RequestedAssetID, imgrequest.LastSequence, m_client.Name, newRequest.requestSequence);
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -139,14 +179,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[LL IMAGE MANAGER]: Received request for {0}, start packet {1} from {2}",
|
||||||
|
// newRequest.RequestedAssetID, newRequest.PacketNumber, m_client.Name);
|
||||||
|
|
||||||
//m_log.DebugFormat("[TEX]: (NEW) ID={0}: D={1}, S={2}, P={3}",
|
//m_log.DebugFormat("[TEX]: (NEW) ID={0}: D={1}, S={2}, P={3}",
|
||||||
// newRequest.RequestedAssetID, newRequest.DiscardLevel, newRequest.PacketNumber, newRequest.Priority);
|
// newRequest.RequestedAssetID, newRequest.DiscardLevel, newRequest.PacketNumber, newRequest.Priority);
|
||||||
|
|
||||||
imgrequest = new J2KImage(this);
|
imgrequest = new J2KImage(this);
|
||||||
imgrequest.J2KDecoder = m_j2kDecodeModule;
|
imgrequest.J2KDecoder = m_j2kDecodeModule;
|
||||||
imgrequest.AssetService = m_assetCache;
|
imgrequest.AssetService = m_assetCache;
|
||||||
imgrequest.AgentID = m_client.AgentId;
|
imgrequest.AgentID = Client.AgentId;
|
||||||
imgrequest.InventoryAccessModule = m_client.Scene.RequestModuleInterface<IInventoryAccessModule>();
|
imgrequest.InventoryAccessModule = Client.Scene.RequestModuleInterface<IInventoryAccessModule>();
|
||||||
imgrequest.DiscardLevel = newRequest.DiscardLevel;
|
imgrequest.DiscardLevel = newRequest.DiscardLevel;
|
||||||
imgrequest.StartPacket = Math.Max(1, newRequest.PacketNumber);
|
imgrequest.StartPacket = Math.Max(1, newRequest.PacketNumber);
|
||||||
imgrequest.Priority = newRequest.Priority;
|
imgrequest.Priority = newRequest.Priority;
|
||||||
|
@ -156,7 +200,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
//Add this download to the priority queue
|
//Add this download to the priority queue
|
||||||
AddImageToQueue(imgrequest);
|
AddImageToQueue(imgrequest);
|
||||||
|
|
||||||
//Run an update
|
|
||||||
imgrequest.RunUpdate();
|
imgrequest.RunUpdate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -173,12 +216,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
|
||||||
// If null was returned, the texture priority queue is currently empty
|
// If null was returned, the texture priority queue is currently empty
|
||||||
if (image == null)
|
if (image == null)
|
||||||
return false;
|
break;
|
||||||
|
|
||||||
if (image.IsDecoded)
|
if (image.IsDecoded)
|
||||||
{
|
{
|
||||||
int sent;
|
int sent;
|
||||||
bool imageDone = image.SendPackets(m_client, packetsToSend - packetsSent, out sent);
|
bool imageDone = image.SendPackets(Client, packetsToSend - packetsSent, out sent);
|
||||||
packetsSent += sent;
|
packetsSent += sent;
|
||||||
|
|
||||||
// If the send is complete, destroy any knowledge of this transfer
|
// If the send is complete, destroy any knowledge of this transfer
|
||||||
|
@ -191,10 +234,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
// written. Undecoded textures should not be going into the priority
|
// written. Undecoded textures should not be going into the priority
|
||||||
// queue, because a high priority undecoded texture will clog up the
|
// queue, because a high priority undecoded texture will clog up the
|
||||||
// pipeline for a client
|
// pipeline for a client
|
||||||
return true;
|
// m_log.DebugFormat(
|
||||||
|
// "[LL IMAGE MANAGER]: Exiting image queue processing early on encountering undecoded image {0}",
|
||||||
|
// image.TextureID);
|
||||||
|
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if (packetsSent != 0)
|
||||||
|
// m_log.DebugFormat("[LL IMAGE MANAGER]: Processed {0} packets from image queue", packetsSent);
|
||||||
|
|
||||||
return m_priorityQueue.Count > 0;
|
return m_priorityQueue.Count > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,9 +256,39 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
m_shuttingdown = true;
|
m_shuttingdown = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clear the image queue.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The number of requests cleared.</returns>
|
||||||
|
public int ClearImageQueue()
|
||||||
|
{
|
||||||
|
int requestsDeleted;
|
||||||
|
|
||||||
|
lock (m_priorityQueue)
|
||||||
|
{
|
||||||
|
requestsDeleted = m_priorityQueue.Count;
|
||||||
|
|
||||||
|
// Surprisingly, there doesn't seem to be a clear method at this time.
|
||||||
|
while (!m_priorityQueue.IsEmpty)
|
||||||
|
m_priorityQueue.DeleteMax();
|
||||||
|
}
|
||||||
|
|
||||||
|
return requestsDeleted;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns an array containing all the images in the queue.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public J2KImage[] GetImages()
|
||||||
|
{
|
||||||
|
lock (m_priorityQueue)
|
||||||
|
return m_priorityQueue.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
#region Priority Queue Helpers
|
#region Priority Queue Helpers
|
||||||
|
|
||||||
J2KImage GetHighestPriorityImage()
|
private J2KImage GetHighestPriorityImage()
|
||||||
{
|
{
|
||||||
J2KImage image = null;
|
J2KImage image = null;
|
||||||
|
|
||||||
|
@ -216,34 +296,50 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
{
|
{
|
||||||
if (m_priorityQueue.Count > 0)
|
if (m_priorityQueue.Count > 0)
|
||||||
{
|
{
|
||||||
try { image = m_priorityQueue.FindMax(); }
|
try
|
||||||
|
{
|
||||||
|
image = m_priorityQueue.FindMax();
|
||||||
|
}
|
||||||
catch (Exception) { }
|
catch (Exception) { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddImageToQueue(J2KImage image)
|
private void AddImageToQueue(J2KImage image)
|
||||||
{
|
{
|
||||||
image.PriorityQueueHandle = null;
|
image.PriorityQueueHandle = null;
|
||||||
|
|
||||||
lock (m_syncRoot)
|
lock (m_syncRoot)
|
||||||
try { m_priorityQueue.Add(ref image.PriorityQueueHandle, image); }
|
|
||||||
catch (Exception) { }
|
|
||||||
}
|
|
||||||
|
|
||||||
void RemoveImageFromQueue(J2KImage image)
|
|
||||||
{
|
{
|
||||||
lock (m_syncRoot)
|
try
|
||||||
try { m_priorityQueue.Delete(image.PriorityQueueHandle); }
|
{
|
||||||
|
m_priorityQueue.Add(ref image.PriorityQueueHandle, image);
|
||||||
|
}
|
||||||
catch (Exception) { }
|
catch (Exception) { }
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void UpdateImageInQueue(J2KImage image)
|
private void RemoveImageFromQueue(J2KImage image)
|
||||||
{
|
{
|
||||||
lock (m_syncRoot)
|
lock (m_syncRoot)
|
||||||
{
|
{
|
||||||
try { m_priorityQueue.Replace(image.PriorityQueueHandle, image); }
|
try
|
||||||
|
{
|
||||||
|
m_priorityQueue.Delete(image.PriorityQueueHandle);
|
||||||
|
}
|
||||||
|
catch (Exception) { }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateImageInQueue(J2KImage image)
|
||||||
|
{
|
||||||
|
lock (m_syncRoot)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
m_priorityQueue.Replace(image.PriorityQueueHandle, image);
|
||||||
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
image.PriorityQueueHandle = null;
|
image.PriorityQueueHandle = null;
|
||||||
|
|
|
@ -169,7 +169,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
/// <param name="circuitCode">Circuit code for this connection</param>
|
/// <param name="circuitCode">Circuit code for this connection</param>
|
||||||
/// <param name="agentID">AgentID for the connected agent</param>
|
/// <param name="agentID">AgentID for the connected agent</param>
|
||||||
/// <param name="remoteEndPoint">Remote endpoint for this connection</param>
|
/// <param name="remoteEndPoint">Remote endpoint for this connection</param>
|
||||||
public LLUDPClient(LLUDPServer server, ThrottleRates rates, TokenBucket parentThrottle, uint circuitCode, UUID agentID, IPEndPoint remoteEndPoint, int defaultRTO, int maxRTO)
|
/// <param name="defaultRTO">
|
||||||
|
/// Default retransmission timeout for unacked packets. The RTO will never drop
|
||||||
|
/// beyond this number.
|
||||||
|
/// </param>
|
||||||
|
/// <param name="maxRTO">
|
||||||
|
/// The maximum retransmission timeout for unacked packets. The RTO will never exceed this number.
|
||||||
|
/// </param>
|
||||||
|
public LLUDPClient(
|
||||||
|
LLUDPServer server, ThrottleRates rates, TokenBucket parentThrottle, uint circuitCode, UUID agentID,
|
||||||
|
IPEndPoint remoteEndPoint, int defaultRTO, int maxRTO)
|
||||||
{
|
{
|
||||||
AgentID = agentID;
|
AgentID = agentID;
|
||||||
RemoteEndPoint = remoteEndPoint;
|
RemoteEndPoint = remoteEndPoint;
|
||||||
|
@ -197,7 +206,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
m_throttleCategories[i] = new TokenBucket(m_throttleCategory, rates.GetRate(type));
|
m_throttleCategories[i] = new TokenBucket(m_throttleCategory, rates.GetRate(type));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default the retransmission timeout to three seconds
|
// Default the retransmission timeout to one second
|
||||||
RTO = m_defaultRTO;
|
RTO = m_defaultRTO;
|
||||||
|
|
||||||
// Initialize this to a sane value to prevent early disconnects
|
// Initialize this to a sane value to prevent early disconnects
|
||||||
|
@ -262,9 +271,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Return statistics information about client packet queues.
|
/// Return statistics information about client packet queues.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
///
|
/// <remarks>
|
||||||
/// FIXME: This should really be done in a more sensible manner rather than sending back a formatted string.
|
/// FIXME: This should really be done in a more sensible manner rather than sending back a formatted string.
|
||||||
///
|
/// </remarks>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public string GetStats()
|
public string GetStats()
|
||||||
{
|
{
|
||||||
|
@ -583,8 +592,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
|
||||||
RTO = rto;
|
RTO = rto;
|
||||||
|
|
||||||
//m_log.Debug("[LLUDPCLIENT]: Setting agent " + this.Agent.FullName + "'s RTO to " + RTO + "ms with an RTTVAR of " +
|
//if (RTO != rto)
|
||||||
// RTTVAR + " based on new RTT of " + r + "ms");
|
// m_log.Debug("[LLUDPCLIENT]: Setting RTO to " + RTO + "ms from " + rto + "ms with an RTTVAR of " +
|
||||||
|
//RTTVAR + " based on new RTT of " + r + "ms");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -606,8 +616,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
/// Does an early check to see if this queue empty callback is already
|
/// Does an early check to see if this queue empty callback is already
|
||||||
/// running, then asynchronously firing the event
|
/// running, then asynchronously firing the event
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="throttleIndex">Throttle category to fire the callback
|
/// <param name="categories">Throttle categories to fire the callback for</param>
|
||||||
/// for</param>
|
|
||||||
private void BeginFireQueueEmpty(ThrottleOutPacketTypeFlags categories)
|
private void BeginFireQueueEmpty(ThrottleOutPacketTypeFlags categories)
|
||||||
{
|
{
|
||||||
if (m_nextOnQueueEmpty != 0 && (Environment.TickCount & Int32.MaxValue) >= m_nextOnQueueEmpty)
|
if (m_nextOnQueueEmpty != 0 && (Environment.TickCount & Int32.MaxValue) >= m_nextOnQueueEmpty)
|
||||||
|
|
|
@ -324,7 +324,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
/// <param name="packet"></param>
|
/// <param name="packet"></param>
|
||||||
/// <param name="category"></param>
|
/// <param name="category"></param>
|
||||||
/// <param name="allowSplitting"></param>
|
/// <param name="allowSplitting"></param>
|
||||||
public void SendPacket(LLUDPClient udpClient, Packet packet, ThrottleOutPacketType category, bool allowSplitting, UnackedPacketMethod method)
|
/// <param name="method">
|
||||||
|
/// The method to call if the packet is not acked by the client. If null, then a standard
|
||||||
|
/// resend of the packet is done.
|
||||||
|
/// </param>
|
||||||
|
public virtual void SendPacket(
|
||||||
|
LLUDPClient udpClient, Packet packet, ThrottleOutPacketType category, bool allowSplitting, UnackedPacketMethod method)
|
||||||
{
|
{
|
||||||
// CoarseLocationUpdate packets cannot be split in an automated way
|
// CoarseLocationUpdate packets cannot be split in an automated way
|
||||||
if (packet.Type == PacketType.CoarseLocationUpdate && allowSplitting)
|
if (packet.Type == PacketType.CoarseLocationUpdate && allowSplitting)
|
||||||
|
@ -358,7 +363,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
/// <param name="data"></param>
|
/// <param name="data"></param>
|
||||||
/// <param name="type"></param>
|
/// <param name="type"></param>
|
||||||
/// <param name="category"></param>
|
/// <param name="category"></param>
|
||||||
public void SendPacketData(LLUDPClient udpClient, byte[] data, PacketType type, ThrottleOutPacketType category, UnackedPacketMethod method)
|
/// <param name="method">
|
||||||
|
/// The method to call if the packet is not acked by the client. If null, then a standard
|
||||||
|
/// resend of the packet is done.
|
||||||
|
/// </param>
|
||||||
|
public void SendPacketData(
|
||||||
|
LLUDPClient udpClient, byte[] data, PacketType type, ThrottleOutPacketType category, UnackedPacketMethod method)
|
||||||
{
|
{
|
||||||
int dataLength = data.Length;
|
int dataLength = data.Length;
|
||||||
bool doZerocode = (data[0] & Helpers.MSG_ZEROCODED) != 0;
|
bool doZerocode = (data[0] & Helpers.MSG_ZEROCODED) != 0;
|
||||||
|
@ -482,6 +492,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
if ((Environment.TickCount & Int32.MaxValue) - udpClient.TickLastPacketReceived > 1000 * 60)
|
if ((Environment.TickCount & Int32.MaxValue) - udpClient.TickLastPacketReceived > 1000 * 60)
|
||||||
{
|
{
|
||||||
m_log.Warn("[LLUDPSERVER]: Ack timeout, disconnecting " + udpClient.AgentID);
|
m_log.Warn("[LLUDPSERVER]: Ack timeout, disconnecting " + udpClient.AgentID);
|
||||||
|
StatsManager.SimExtraStats.AddAbnormalClientThreadTermination();
|
||||||
|
|
||||||
RemoveClient(udpClient);
|
RemoveClient(udpClient);
|
||||||
return;
|
return;
|
||||||
|
@ -601,11 +612,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
outgoingPacket.TickCount = Environment.TickCount & Int32.MaxValue;
|
outgoingPacket.TickCount = Environment.TickCount & Int32.MaxValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void PacketReceived(UDPPacketBuffer buffer)
|
public override void PacketReceived(UDPPacketBuffer buffer)
|
||||||
{
|
{
|
||||||
// Debugging/Profiling
|
// Debugging/Profiling
|
||||||
//try { Thread.CurrentThread.Name = "PacketReceived (" + m_scene.RegionInfo.RegionName + ")"; }
|
//try { Thread.CurrentThread.Name = "PacketReceived (" + m_scene.RegionInfo.RegionName + ")"; }
|
||||||
//catch (Exception) { }
|
//catch (Exception) { }
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[LLUDPSERVER]: Packet received from {0} in {1}", buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName);
|
||||||
|
|
||||||
LLUDPClient udpClient = null;
|
LLUDPClient udpClient = null;
|
||||||
Packet packet = null;
|
Packet packet = null;
|
||||||
|
@ -615,7 +628,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
#region Decoding
|
#region Decoding
|
||||||
|
|
||||||
if (buffer.DataLength < 7)
|
if (buffer.DataLength < 7)
|
||||||
|
{
|
||||||
|
// m_log.WarnFormat(
|
||||||
|
// "[LLUDPSERVER]: Dropping undersized packet with {0} bytes received from {1} in {2}",
|
||||||
|
// buffer.DataLength, buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName);
|
||||||
|
|
||||||
return; // Drop undersizd packet
|
return; // Drop undersizd packet
|
||||||
|
}
|
||||||
|
|
||||||
int headerLen = 7;
|
int headerLen = 7;
|
||||||
if (buffer.Data[6] == 0xFF)
|
if (buffer.Data[6] == 0xFF)
|
||||||
|
@ -627,7 +646,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buffer.DataLength < headerLen)
|
if (buffer.DataLength < headerLen)
|
||||||
|
{
|
||||||
|
// m_log.WarnFormat(
|
||||||
|
// "[LLUDPSERVER]: Dropping packet with malformed header received from {0} in {1}",
|
||||||
|
// buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName);
|
||||||
|
|
||||||
return; // Malformed header
|
return; // Malformed header
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -640,6 +665,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
}
|
}
|
||||||
catch (IndexOutOfRangeException)
|
catch (IndexOutOfRangeException)
|
||||||
{
|
{
|
||||||
|
// m_log.WarnFormat(
|
||||||
|
// "[LLUDPSERVER]: Dropping short packet received from {0} in {1}",
|
||||||
|
// buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName);
|
||||||
|
|
||||||
return; // Drop short packet
|
return; // Drop short packet
|
||||||
}
|
}
|
||||||
catch(Exception e)
|
catch(Exception e)
|
||||||
|
@ -877,23 +906,55 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
// DateTime startTime = DateTime.Now;
|
// DateTime startTime = DateTime.Now;
|
||||||
object[] array = (object[])o;
|
object[] array = (object[])o;
|
||||||
UDPPacketBuffer buffer = (UDPPacketBuffer)array[0];
|
UDPPacketBuffer buffer = (UDPPacketBuffer)array[0];
|
||||||
UseCircuitCodePacket packet = (UseCircuitCodePacket)array[1];
|
UseCircuitCodePacket uccp = (UseCircuitCodePacket)array[1];
|
||||||
|
|
||||||
m_log.DebugFormat("[LLUDPSERVER]: Handling UseCircuitCode request from {0}", buffer.RemoteEndPoint);
|
m_log.DebugFormat("[LLUDPSERVER]: Handling UseCircuitCode request from {0}", buffer.RemoteEndPoint);
|
||||||
|
|
||||||
IPEndPoint remoteEndPoint = (IPEndPoint)buffer.RemoteEndPoint;
|
IPEndPoint remoteEndPoint = (IPEndPoint)buffer.RemoteEndPoint;
|
||||||
|
|
||||||
|
AuthenticateResponse sessionInfo;
|
||||||
|
if (IsClientAuthorized(uccp, out sessionInfo))
|
||||||
|
{
|
||||||
// Begin the process of adding the client to the simulator
|
// Begin the process of adding the client to the simulator
|
||||||
AddNewClient((UseCircuitCodePacket)packet, remoteEndPoint);
|
IClientAPI client
|
||||||
|
= AddClient(
|
||||||
|
uccp.CircuitCode.Code,
|
||||||
|
uccp.CircuitCode.ID,
|
||||||
|
uccp.CircuitCode.SessionID,
|
||||||
|
remoteEndPoint,
|
||||||
|
sessionInfo);
|
||||||
|
|
||||||
// Send ack
|
// Send ack straight away to let the viewer know that the connection is active.
|
||||||
SendAckImmediate(remoteEndPoint, packet.Header.Sequence);
|
// 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(
|
// m_log.DebugFormat(
|
||||||
// "[LLUDPSERVER]: Handling UseCircuitCode request from {0} took {1}ms",
|
// "[LLUDPSERVER]: Handling UseCircuitCode request from {0} took {1}ms",
|
||||||
// buffer.RemoteEndPoint, (DateTime.Now - startTime).Milliseconds);
|
// buffer.RemoteEndPoint, (DateTime.Now - startTime).Milliseconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Send an ack immediately to the given endpoint.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// FIXME: Might be possible to use SendPacketData() like everything else, but this will require refactoring so
|
||||||
|
/// that we can obtain the UDPClient easily at this point.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="remoteEndpoint"></param>
|
||||||
|
/// <param name="sequenceNumber"></param>
|
||||||
private void SendAckImmediate(IPEndPoint remoteEndpoint, uint sequenceNumber)
|
private void SendAckImmediate(IPEndPoint remoteEndpoint, uint sequenceNumber)
|
||||||
{
|
{
|
||||||
PacketAckPacket ack = new PacketAckPacket();
|
PacketAckPacket ack = new PacketAckPacket();
|
||||||
|
@ -902,6 +963,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
ack.Packets[0] = new PacketAckPacket.PacketsBlock();
|
ack.Packets[0] = new PacketAckPacket.PacketsBlock();
|
||||||
ack.Packets[0].ID = sequenceNumber;
|
ack.Packets[0].ID = sequenceNumber;
|
||||||
|
|
||||||
|
SendAckImmediate(remoteEndpoint, ack);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void SendAckImmediate(IPEndPoint remoteEndpoint, PacketAckPacket ack)
|
||||||
|
{
|
||||||
byte[] packetData = ack.ToBytes();
|
byte[] packetData = ack.ToBytes();
|
||||||
int length = packetData.Length;
|
int length = packetData.Length;
|
||||||
|
|
||||||
|
@ -923,63 +989,39 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
return sessionInfo.Authorised;
|
return sessionInfo.Authorised;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AddNewClient(UseCircuitCodePacket useCircuitCode, IPEndPoint remoteEndPoint)
|
/// <summary>
|
||||||
|
/// Add a client.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="circuitCode"></param>
|
||||||
|
/// <param name="agentID"></param>
|
||||||
|
/// <param name="sessionID"></param>
|
||||||
|
/// <param name="remoteEndPoint"></param>
|
||||||
|
/// <param name="sessionInfo"></param>
|
||||||
|
/// <returns>The client if it was added. Null if the client already existed.</returns>
|
||||||
|
protected virtual IClientAPI AddClient(
|
||||||
|
uint circuitCode, UUID agentID, UUID sessionID, IPEndPoint remoteEndPoint, AuthenticateResponse sessionInfo)
|
||||||
{
|
{
|
||||||
UUID agentID = useCircuitCode.CircuitCode.ID;
|
IClientAPI client = null;
|
||||||
UUID sessionID = useCircuitCode.CircuitCode.SessionID;
|
|
||||||
uint circuitCode = useCircuitCode.CircuitCode.Code;
|
|
||||||
|
|
||||||
if (m_scene.RegionStatus != RegionStatus.SlaveScene)
|
|
||||||
{
|
|
||||||
AuthenticateResponse sessionInfo;
|
|
||||||
if (IsClientAuthorized(useCircuitCode, out sessionInfo))
|
|
||||||
{
|
|
||||||
AddClient(circuitCode, agentID, sessionID, remoteEndPoint, sessionInfo);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Don't create circuits for unauthorized clients
|
|
||||||
m_log.WarnFormat(
|
|
||||||
"[LLUDPSERVER]: Connection request for client {0} connecting with unnotified circuit code {1} from {2}",
|
|
||||||
useCircuitCode.CircuitCode.ID, useCircuitCode.CircuitCode.Code, remoteEndPoint);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Slave regions don't accept new clients
|
|
||||||
m_log.Debug("[LLUDPSERVER]: Slave region " + m_scene.RegionInfo.RegionName + " ignoring UseCircuitCode packet");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual void AddClient(uint circuitCode, UUID agentID, UUID sessionID, IPEndPoint remoteEndPoint, AuthenticateResponse sessionInfo)
|
|
||||||
{
|
|
||||||
// In priciple there shouldn't be more than one thread here, ever.
|
// In priciple there shouldn't be more than one thread here, ever.
|
||||||
// But in case that happens, we need to synchronize this piece of code
|
// But in case that happens, we need to synchronize this piece of code
|
||||||
// because it's too important
|
// because it's too important
|
||||||
lock (this)
|
lock (this)
|
||||||
{
|
{
|
||||||
IClientAPI existingClient;
|
if (!m_scene.TryGetClient(agentID, out client))
|
||||||
|
|
||||||
if (!m_scene.TryGetClient(agentID, out existingClient))
|
|
||||||
{
|
{
|
||||||
// Create the LLUDPClient
|
|
||||||
LLUDPClient udpClient = new LLUDPClient(this, ThrottleRates, m_throttle, circuitCode, agentID, remoteEndPoint, m_defaultRTO, m_maxRTO);
|
LLUDPClient udpClient = new LLUDPClient(this, ThrottleRates, m_throttle, circuitCode, agentID, remoteEndPoint, m_defaultRTO, m_maxRTO);
|
||||||
// Create the LLClientView
|
|
||||||
LLClientView client = new LLClientView(remoteEndPoint, m_scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode);
|
client = new LLClientView(remoteEndPoint, m_scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode);
|
||||||
client.OnLogout += LogoutHandler;
|
client.OnLogout += LogoutHandler;
|
||||||
|
|
||||||
client.DisableFacelights = m_disableFacelights;
|
((LLClientView)client).DisableFacelights = m_disableFacelights;
|
||||||
|
|
||||||
// Start the IClientAPI
|
|
||||||
client.Start();
|
client.Start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
return client;
|
||||||
else
|
|
||||||
{
|
|
||||||
m_log.WarnFormat("[LLUDPSERVER]: Ignoring a repeated UseCircuitCode from {0} at {1} for circuit {2}",
|
|
||||||
existingClient.AgentId, remoteEndPoint, circuitCode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RemoveClient(LLUDPClient udpClient)
|
private void RemoveClient(LLUDPClient udpClient)
|
||||||
|
@ -1108,7 +1150,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
{
|
{
|
||||||
m_log.Error("[LLUDPSERVER]: OutgoingPacketHandler loop threw an exception: " + ex.Message, ex);
|
m_log.Error("[LLUDPSERVER]: OutgoingPacketHandler loop threw an exception: " + ex.Message, ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Watchdog.RemoveThread();
|
Watchdog.RemoveThread();
|
||||||
|
|
|
@ -44,7 +44,7 @@ namespace OpenMetaverse
|
||||||
/// This method is called when an incoming packet is received
|
/// This method is called when an incoming packet is received
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="buffer">Incoming packet buffer</param>
|
/// <param name="buffer">Incoming packet buffer</param>
|
||||||
protected abstract void PacketReceived(UDPPacketBuffer buffer);
|
public abstract void PacketReceived(UDPPacketBuffer buffer);
|
||||||
|
|
||||||
/// <summary>UDP port to bind to in server mode</summary>
|
/// <summary>UDP port to bind to in server mode</summary>
|
||||||
protected int m_udpPort;
|
protected int m_udpPort;
|
||||||
|
|
|
@ -25,14 +25,15 @@
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using log4net.Config;
|
using log4net.Config;
|
||||||
using Nini.Config;
|
using Nini.Config;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using NUnit.Framework.SyntaxHelpers;
|
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
using OpenMetaverse.Packets;
|
using OpenMetaverse.Packets;
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Region.Framework.Scenes;
|
||||||
using OpenSim.Tests.Common;
|
using OpenSim.Tests.Common;
|
||||||
using OpenSim.Tests.Common.Mock;
|
using OpenSim.Tests.Common.Mock;
|
||||||
|
|
||||||
|
@ -44,89 +45,92 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class BasicCircuitTests
|
public class BasicCircuitTests
|
||||||
{
|
{
|
||||||
[SetUp]
|
[TestFixtureSetUp]
|
||||||
public void Init()
|
public void FixtureInit()
|
||||||
{
|
{
|
||||||
try
|
// Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread.
|
||||||
{
|
Util.FireAndForgetMethod = FireAndForgetMethod.RegressionTest;
|
||||||
XmlConfigurator.Configure();
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
// I don't care, just leave log4net off
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
[TestFixtureTearDown]
|
||||||
/// Add a client for testing
|
public void TearDown()
|
||||||
/// </summary>
|
|
||||||
/// <param name="scene"></param>
|
|
||||||
/// <param name="testLLUDPServer"></param>
|
|
||||||
/// <param name="testPacketServer"></param>
|
|
||||||
/// <param name="acm">Agent circuit manager used in setting up the stack</param>
|
|
||||||
protected void SetupStack(
|
|
||||||
IScene scene, out TestLLUDPServer testLLUDPServer, out TestLLPacketServer testPacketServer,
|
|
||||||
out AgentCircuitManager acm)
|
|
||||||
{
|
{
|
||||||
IConfigSource configSource = new IniConfigSource();
|
// We must set this back afterwards, otherwise later tests will fail since they're expecting multiple
|
||||||
ClientStackUserSettings userSettings = new ClientStackUserSettings();
|
// threads. Possibly, later tests should be rewritten so none of them require async stuff (which regression
|
||||||
testLLUDPServer = new TestLLUDPServer();
|
// tests really shouldn't).
|
||||||
acm = new AgentCircuitManager();
|
Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod;
|
||||||
|
|
||||||
uint port = 666;
|
|
||||||
testLLUDPServer.Initialise(null, ref port, 0, false, configSource, acm);
|
|
||||||
testPacketServer = new TestLLPacketServer(testLLUDPServer, userSettings);
|
|
||||||
testLLUDPServer.LocalScene = scene;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
// /// <summary>
|
||||||
/// Set up a client for tests which aren't concerned with this process itself and where only one client is being
|
// /// Add a client for testing
|
||||||
/// tested
|
// /// </summary>
|
||||||
/// </summary>
|
// /// <param name="scene"></param>
|
||||||
/// <param name="circuitCode"></param>
|
// /// <param name="testLLUDPServer"></param>
|
||||||
/// <param name="epSender"></param>
|
// /// <param name="testPacketServer"></param>
|
||||||
/// <param name="testLLUDPServer"></param>
|
// /// <param name="acm">Agent circuit manager used in setting up the stack</param>
|
||||||
/// <param name="acm"></param>
|
// protected void SetupStack(
|
||||||
protected void AddClient(
|
// IScene scene, out TestLLUDPServer testLLUDPServer, out TestLLPacketServer testPacketServer,
|
||||||
uint circuitCode, EndPoint epSender, TestLLUDPServer testLLUDPServer, AgentCircuitManager acm)
|
// out AgentCircuitManager acm)
|
||||||
{
|
// {
|
||||||
UUID myAgentUuid = UUID.Parse("00000000-0000-0000-0000-000000000001");
|
// IConfigSource configSource = new IniConfigSource();
|
||||||
UUID mySessionUuid = UUID.Parse("00000000-0000-0000-0000-000000000002");
|
// ClientStackUserSettings userSettings = new ClientStackUserSettings();
|
||||||
|
// testLLUDPServer = new TestLLUDPServer();
|
||||||
|
// acm = new AgentCircuitManager();
|
||||||
|
//
|
||||||
|
// uint port = 666;
|
||||||
|
// testLLUDPServer.Initialise(null, ref port, 0, false, configSource, acm);
|
||||||
|
// testPacketServer = new TestLLPacketServer(testLLUDPServer, userSettings);
|
||||||
|
// testLLUDPServer.LocalScene = scene;
|
||||||
|
// }
|
||||||
|
|
||||||
AddClient(circuitCode, epSender, myAgentUuid, mySessionUuid, testLLUDPServer, acm);
|
// /// <summary>
|
||||||
}
|
// /// Set up a client for tests which aren't concerned with this process itself and where only one client is being
|
||||||
|
// /// tested
|
||||||
|
// /// </summary>
|
||||||
|
// /// <param name="circuitCode"></param>
|
||||||
|
// /// <param name="epSender"></param>
|
||||||
|
// /// <param name="testLLUDPServer"></param>
|
||||||
|
// /// <param name="acm"></param>
|
||||||
|
// protected void AddClient(
|
||||||
|
// uint circuitCode, EndPoint epSender, TestLLUDPServer testLLUDPServer, AgentCircuitManager acm)
|
||||||
|
// {
|
||||||
|
// UUID myAgentUuid = UUID.Parse("00000000-0000-0000-0000-000000000001");
|
||||||
|
// UUID mySessionUuid = UUID.Parse("00000000-0000-0000-0000-000000000002");
|
||||||
|
//
|
||||||
|
// AddClient(circuitCode, epSender, myAgentUuid, mySessionUuid, testLLUDPServer, acm);
|
||||||
|
// }
|
||||||
|
|
||||||
/// <summary>
|
// /// <summary>
|
||||||
/// Set up a client for tests which aren't concerned with this process itself
|
// /// Set up a client for tests which aren't concerned with this process itself
|
||||||
/// </summary>
|
// /// </summary>
|
||||||
/// <param name="circuitCode"></param>
|
// /// <param name="circuitCode"></param>
|
||||||
/// <param name="epSender"></param>
|
// /// <param name="epSender"></param>
|
||||||
/// <param name="agentId"></param>
|
// /// <param name="agentId"></param>
|
||||||
/// <param name="sessionId"></param>
|
// /// <param name="sessionId"></param>
|
||||||
/// <param name="testLLUDPServer"></param>
|
// /// <param name="testLLUDPServer"></param>
|
||||||
/// <param name="acm"></param>
|
// /// <param name="acm"></param>
|
||||||
protected void AddClient(
|
// protected void AddClient(
|
||||||
uint circuitCode, EndPoint epSender, UUID agentId, UUID sessionId,
|
// uint circuitCode, EndPoint epSender, UUID agentId, UUID sessionId,
|
||||||
TestLLUDPServer testLLUDPServer, AgentCircuitManager acm)
|
// TestLLUDPServer testLLUDPServer, AgentCircuitManager acm)
|
||||||
{
|
// {
|
||||||
AgentCircuitData acd = new AgentCircuitData();
|
// AgentCircuitData acd = new AgentCircuitData();
|
||||||
acd.AgentID = agentId;
|
// acd.AgentID = agentId;
|
||||||
acd.SessionID = sessionId;
|
// acd.SessionID = sessionId;
|
||||||
|
//
|
||||||
UseCircuitCodePacket uccp = new UseCircuitCodePacket();
|
// UseCircuitCodePacket uccp = new UseCircuitCodePacket();
|
||||||
|
//
|
||||||
UseCircuitCodePacket.CircuitCodeBlock uccpCcBlock
|
// UseCircuitCodePacket.CircuitCodeBlock uccpCcBlock
|
||||||
= new UseCircuitCodePacket.CircuitCodeBlock();
|
// = new UseCircuitCodePacket.CircuitCodeBlock();
|
||||||
uccpCcBlock.Code = circuitCode;
|
// uccpCcBlock.Code = circuitCode;
|
||||||
uccpCcBlock.ID = agentId;
|
// uccpCcBlock.ID = agentId;
|
||||||
uccpCcBlock.SessionID = sessionId;
|
// uccpCcBlock.SessionID = sessionId;
|
||||||
uccp.CircuitCode = uccpCcBlock;
|
// uccp.CircuitCode = uccpCcBlock;
|
||||||
|
//
|
||||||
acm.AddNewCircuit(circuitCode, acd);
|
// acm.AddNewCircuit(circuitCode, acd);
|
||||||
|
//
|
||||||
testLLUDPServer.LoadReceive(uccp, epSender);
|
// testLLUDPServer.LoadReceive(uccp, epSender);
|
||||||
testLLUDPServer.ReceiveData(null);
|
// testLLUDPServer.ReceiveData(null);
|
||||||
}
|
// }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Build an object name packet for test purposes
|
/// Build an object name packet for test purposes
|
||||||
|
@ -148,23 +152,24 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Test adding a client to the stack
|
/// Test adding a client to the stack
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Test, LongRunning]
|
[Test]
|
||||||
public void TestAddClient()
|
public void TestAddClient()
|
||||||
{
|
{
|
||||||
TestHelper.InMethod();
|
TestHelpers.InMethod();
|
||||||
|
// XmlConfigurator.Configure();
|
||||||
|
|
||||||
|
TestScene scene = SceneHelpers.SetupScene();
|
||||||
uint myCircuitCode = 123456;
|
uint myCircuitCode = 123456;
|
||||||
UUID myAgentUuid = UUID.Parse("00000000-0000-0000-0000-000000000001");
|
UUID myAgentUuid = TestHelpers.ParseTail(0x1);
|
||||||
UUID mySessionUuid = UUID.Parse("00000000-0000-0000-0000-000000000002");
|
UUID mySessionUuid = TestHelpers.ParseTail(0x2);
|
||||||
|
IPEndPoint testEp = new IPEndPoint(IPAddress.Loopback, 999);
|
||||||
|
|
||||||
TestLLUDPServer testLLUDPServer;
|
uint port = 0;
|
||||||
TestLLPacketServer testLLPacketServer;
|
AgentCircuitManager acm = scene.AuthenticateHandler;
|
||||||
AgentCircuitManager acm;
|
|
||||||
SetupStack(new MockScene(), out testLLUDPServer, out testLLPacketServer, out acm);
|
|
||||||
|
|
||||||
AgentCircuitData acd = new AgentCircuitData();
|
TestLLUDPServer llUdpServer
|
||||||
acd.AgentID = myAgentUuid;
|
= new TestLLUDPServer(IPAddress.Any, ref port, 0, false, new IniConfigSource(), acm);
|
||||||
acd.SessionID = mySessionUuid;
|
llUdpServer.AddScene(scene);
|
||||||
|
|
||||||
UseCircuitCodePacket uccp = new UseCircuitCodePacket();
|
UseCircuitCodePacket uccp = new UseCircuitCodePacket();
|
||||||
|
|
||||||
|
@ -175,125 +180,139 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
|
||||||
uccpCcBlock.SessionID = mySessionUuid;
|
uccpCcBlock.SessionID = mySessionUuid;
|
||||||
uccp.CircuitCode = uccpCcBlock;
|
uccp.CircuitCode = uccpCcBlock;
|
||||||
|
|
||||||
EndPoint testEp = new IPEndPoint(IPAddress.Loopback, 999);
|
byte[] uccpBytes = uccp.ToBytes();
|
||||||
|
UDPPacketBuffer upb = new UDPPacketBuffer(testEp, uccpBytes.Length);
|
||||||
|
upb.DataLength = uccpBytes.Length; // God knows why this isn't set by the constructor.
|
||||||
|
Buffer.BlockCopy(uccpBytes, 0, upb.Data, 0, uccpBytes.Length);
|
||||||
|
|
||||||
testLLUDPServer.LoadReceive(uccp, testEp);
|
llUdpServer.PacketReceived(upb);
|
||||||
testLLUDPServer.ReceiveData(null);
|
|
||||||
|
|
||||||
// Circuit shouildn't exist since the circuit manager doesn't know about this circuit for authentication yet
|
// Presence shouldn't exist since the circuit manager doesn't know about this circuit for authentication yet
|
||||||
Assert.IsFalse(testLLUDPServer.HasCircuit(myCircuitCode));
|
Assert.That(scene.GetScenePresence(myAgentUuid), Is.Null);
|
||||||
|
|
||||||
|
AgentCircuitData acd = new AgentCircuitData();
|
||||||
|
acd.AgentID = myAgentUuid;
|
||||||
|
acd.SessionID = mySessionUuid;
|
||||||
|
|
||||||
acm.AddNewCircuit(myCircuitCode, acd);
|
acm.AddNewCircuit(myCircuitCode, acd);
|
||||||
|
|
||||||
testLLUDPServer.LoadReceive(uccp, testEp);
|
llUdpServer.PacketReceived(upb);
|
||||||
testLLUDPServer.ReceiveData(null);
|
|
||||||
|
|
||||||
// Should succeed now
|
// Should succeed now
|
||||||
Assert.IsTrue(testLLUDPServer.HasCircuit(myCircuitCode));
|
ScenePresence sp = scene.GetScenePresence(myAgentUuid);
|
||||||
Assert.IsFalse(testLLUDPServer.HasCircuit(101));
|
Assert.That(sp.UUID, Is.EqualTo(myAgentUuid));
|
||||||
|
|
||||||
|
Assert.That(llUdpServer.PacketsSent.Count, Is.EqualTo(1));
|
||||||
|
|
||||||
|
Packet packet = llUdpServer.PacketsSent[0];
|
||||||
|
Assert.That(packet, Is.InstanceOf(typeof(PacketAckPacket)));
|
||||||
|
|
||||||
|
PacketAckPacket ackPacket = packet as PacketAckPacket;
|
||||||
|
Assert.That(ackPacket.Packets.Length, Is.EqualTo(1));
|
||||||
|
Assert.That(ackPacket.Packets[0].ID, Is.EqualTo(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
// /// <summary>
|
||||||
/// Test removing a client from the stack
|
// /// Test removing a client from the stack
|
||||||
/// </summary>
|
// /// </summary>
|
||||||
[Test]
|
// [Test]
|
||||||
public void TestRemoveClient()
|
// public void TestRemoveClient()
|
||||||
{
|
// {
|
||||||
TestHelper.InMethod();
|
// TestHelper.InMethod();
|
||||||
|
//
|
||||||
uint myCircuitCode = 123457;
|
// uint myCircuitCode = 123457;
|
||||||
|
//
|
||||||
TestLLUDPServer testLLUDPServer;
|
// TestLLUDPServer testLLUDPServer;
|
||||||
TestLLPacketServer testLLPacketServer;
|
// TestLLPacketServer testLLPacketServer;
|
||||||
AgentCircuitManager acm;
|
// AgentCircuitManager acm;
|
||||||
SetupStack(new MockScene(), out testLLUDPServer, out testLLPacketServer, out acm);
|
// SetupStack(new MockScene(), out testLLUDPServer, out testLLPacketServer, out acm);
|
||||||
AddClient(myCircuitCode, new IPEndPoint(IPAddress.Loopback, 1000), testLLUDPServer, acm);
|
// AddClient(myCircuitCode, new IPEndPoint(IPAddress.Loopback, 1000), testLLUDPServer, acm);
|
||||||
|
//
|
||||||
testLLUDPServer.RemoveClientCircuit(myCircuitCode);
|
// testLLUDPServer.RemoveClientCircuit(myCircuitCode);
|
||||||
Assert.IsFalse(testLLUDPServer.HasCircuit(myCircuitCode));
|
// Assert.IsFalse(testLLUDPServer.HasCircuit(myCircuitCode));
|
||||||
|
//
|
||||||
// Check that removing a non-existant circuit doesn't have any bad effects
|
// // Check that removing a non-existant circuit doesn't have any bad effects
|
||||||
testLLUDPServer.RemoveClientCircuit(101);
|
// testLLUDPServer.RemoveClientCircuit(101);
|
||||||
Assert.IsFalse(testLLUDPServer.HasCircuit(101));
|
// Assert.IsFalse(testLLUDPServer.HasCircuit(101));
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
/// <summary>
|
// /// <summary>
|
||||||
/// Make sure that the client stack reacts okay to malformed packets
|
// /// Make sure that the client stack reacts okay to malformed packets
|
||||||
/// </summary>
|
// /// </summary>
|
||||||
[Test]
|
// [Test]
|
||||||
public void TestMalformedPacketSend()
|
// public void TestMalformedPacketSend()
|
||||||
{
|
// {
|
||||||
TestHelper.InMethod();
|
// TestHelper.InMethod();
|
||||||
|
//
|
||||||
uint myCircuitCode = 123458;
|
// uint myCircuitCode = 123458;
|
||||||
EndPoint testEp = new IPEndPoint(IPAddress.Loopback, 1001);
|
// EndPoint testEp = new IPEndPoint(IPAddress.Loopback, 1001);
|
||||||
MockScene scene = new MockScene();
|
// MockScene scene = new MockScene();
|
||||||
|
//
|
||||||
TestLLUDPServer testLLUDPServer;
|
// TestLLUDPServer testLLUDPServer;
|
||||||
TestLLPacketServer testLLPacketServer;
|
// TestLLPacketServer testLLPacketServer;
|
||||||
AgentCircuitManager acm;
|
// AgentCircuitManager acm;
|
||||||
SetupStack(scene, out testLLUDPServer, out testLLPacketServer, out acm);
|
// SetupStack(scene, out testLLUDPServer, out testLLPacketServer, out acm);
|
||||||
AddClient(myCircuitCode, testEp, testLLUDPServer, acm);
|
// AddClient(myCircuitCode, testEp, testLLUDPServer, acm);
|
||||||
|
//
|
||||||
byte[] data = new byte[] { 0x01, 0x02, 0x03, 0x04 };
|
// byte[] data = new byte[] { 0x01, 0x02, 0x03, 0x04 };
|
||||||
|
//
|
||||||
// Send two garbled 'packets' in succession
|
// // Send two garbled 'packets' in succession
|
||||||
testLLUDPServer.LoadReceive(data, testEp);
|
// testLLUDPServer.LoadReceive(data, testEp);
|
||||||
testLLUDPServer.LoadReceive(data, testEp);
|
// testLLUDPServer.LoadReceive(data, testEp);
|
||||||
testLLUDPServer.ReceiveData(null);
|
// testLLUDPServer.ReceiveData(null);
|
||||||
|
//
|
||||||
// Check that we are still here
|
// // Check that we are still here
|
||||||
Assert.IsTrue(testLLUDPServer.HasCircuit(myCircuitCode));
|
// Assert.IsTrue(testLLUDPServer.HasCircuit(myCircuitCode));
|
||||||
Assert.That(testLLPacketServer.GetTotalPacketsReceived(), Is.EqualTo(0));
|
// Assert.That(testLLPacketServer.GetTotalPacketsReceived(), Is.EqualTo(0));
|
||||||
|
//
|
||||||
// Check that sending a valid packet to same circuit still succeeds
|
// // Check that sending a valid packet to same circuit still succeeds
|
||||||
Assert.That(scene.ObjectNameCallsReceived, Is.EqualTo(0));
|
// Assert.That(scene.ObjectNameCallsReceived, Is.EqualTo(0));
|
||||||
|
//
|
||||||
testLLUDPServer.LoadReceive(BuildTestObjectNamePacket(1, "helloooo"), testEp);
|
// testLLUDPServer.LoadReceive(BuildTestObjectNamePacket(1, "helloooo"), testEp);
|
||||||
testLLUDPServer.ReceiveData(null);
|
// testLLUDPServer.ReceiveData(null);
|
||||||
|
//
|
||||||
Assert.That(testLLPacketServer.GetTotalPacketsReceived(), Is.EqualTo(1));
|
// Assert.That(testLLPacketServer.GetTotalPacketsReceived(), Is.EqualTo(1));
|
||||||
Assert.That(testLLPacketServer.GetPacketsReceivedFor(PacketType.ObjectName), Is.EqualTo(1));
|
// Assert.That(testLLPacketServer.GetPacketsReceivedFor(PacketType.ObjectName), Is.EqualTo(1));
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
/// <summary>
|
// /// <summary>
|
||||||
/// Test that the stack continues to work even if some client has caused a
|
// /// Test that the stack continues to work even if some client has caused a
|
||||||
/// SocketException on Socket.BeginReceive()
|
// /// SocketException on Socket.BeginReceive()
|
||||||
/// </summary>
|
// /// </summary>
|
||||||
[Test]
|
// [Test]
|
||||||
public void TestExceptionOnBeginReceive()
|
// public void TestExceptionOnBeginReceive()
|
||||||
{
|
// {
|
||||||
TestHelper.InMethod();
|
// TestHelper.InMethod();
|
||||||
|
//
|
||||||
MockScene scene = new MockScene();
|
// MockScene scene = new MockScene();
|
||||||
|
//
|
||||||
uint circuitCodeA = 130000;
|
// uint circuitCodeA = 130000;
|
||||||
EndPoint epA = new IPEndPoint(IPAddress.Loopback, 1300);
|
// EndPoint epA = new IPEndPoint(IPAddress.Loopback, 1300);
|
||||||
UUID agentIdA = UUID.Parse("00000000-0000-0000-0000-000000001300");
|
// UUID agentIdA = UUID.Parse("00000000-0000-0000-0000-000000001300");
|
||||||
UUID sessionIdA = UUID.Parse("00000000-0000-0000-0000-000000002300");
|
// UUID sessionIdA = UUID.Parse("00000000-0000-0000-0000-000000002300");
|
||||||
|
//
|
||||||
uint circuitCodeB = 130001;
|
// uint circuitCodeB = 130001;
|
||||||
EndPoint epB = new IPEndPoint(IPAddress.Loopback, 1301);
|
// EndPoint epB = new IPEndPoint(IPAddress.Loopback, 1301);
|
||||||
UUID agentIdB = UUID.Parse("00000000-0000-0000-0000-000000001301");
|
// UUID agentIdB = UUID.Parse("00000000-0000-0000-0000-000000001301");
|
||||||
UUID sessionIdB = UUID.Parse("00000000-0000-0000-0000-000000002301");
|
// UUID sessionIdB = UUID.Parse("00000000-0000-0000-0000-000000002301");
|
||||||
|
//
|
||||||
TestLLUDPServer testLLUDPServer;
|
// TestLLUDPServer testLLUDPServer;
|
||||||
TestLLPacketServer testLLPacketServer;
|
// TestLLPacketServer testLLPacketServer;
|
||||||
AgentCircuitManager acm;
|
// AgentCircuitManager acm;
|
||||||
SetupStack(scene, out testLLUDPServer, out testLLPacketServer, out acm);
|
// SetupStack(scene, out testLLUDPServer, out testLLPacketServer, out acm);
|
||||||
AddClient(circuitCodeA, epA, agentIdA, sessionIdA, testLLUDPServer, acm);
|
// AddClient(circuitCodeA, epA, agentIdA, sessionIdA, testLLUDPServer, acm);
|
||||||
AddClient(circuitCodeB, epB, agentIdB, sessionIdB, testLLUDPServer, acm);
|
// AddClient(circuitCodeB, epB, agentIdB, sessionIdB, testLLUDPServer, acm);
|
||||||
|
//
|
||||||
testLLUDPServer.LoadReceive(BuildTestObjectNamePacket(1, "packet1"), epA);
|
// testLLUDPServer.LoadReceive(BuildTestObjectNamePacket(1, "packet1"), epA);
|
||||||
testLLUDPServer.LoadReceive(BuildTestObjectNamePacket(1, "packet2"), epB);
|
// testLLUDPServer.LoadReceive(BuildTestObjectNamePacket(1, "packet2"), epB);
|
||||||
testLLUDPServer.LoadReceiveWithBeginException(epA);
|
// testLLUDPServer.LoadReceiveWithBeginException(epA);
|
||||||
testLLUDPServer.LoadReceive(BuildTestObjectNamePacket(2, "packet3"), epB);
|
// testLLUDPServer.LoadReceive(BuildTestObjectNamePacket(2, "packet3"), epB);
|
||||||
testLLUDPServer.ReceiveData(null);
|
// testLLUDPServer.ReceiveData(null);
|
||||||
|
//
|
||||||
Assert.IsFalse(testLLUDPServer.HasCircuit(circuitCodeA));
|
// Assert.IsFalse(testLLUDPServer.HasCircuit(circuitCodeA));
|
||||||
|
//
|
||||||
Assert.That(testLLPacketServer.GetTotalPacketsReceived(), Is.EqualTo(3));
|
// Assert.That(testLLPacketServer.GetTotalPacketsReceived(), Is.EqualTo(3));
|
||||||
Assert.That(testLLPacketServer.GetPacketsReceivedFor(PacketType.ObjectName), Is.EqualTo(3));
|
// Assert.That(testLLPacketServer.GetPacketsReceivedFor(PacketType.ObjectName), Is.EqualTo(3));
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,160 @@
|
||||||
|
/*
|
||||||
|
* 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.IO;
|
||||||
|
using System.Net;
|
||||||
|
using System.Reflection;
|
||||||
|
using log4net.Config;
|
||||||
|
using Nini.Config;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using OpenMetaverse;
|
||||||
|
using OpenMetaverse.Packets;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Region.CoreModules.Agent.TextureSender;
|
||||||
|
using OpenSim.Region.Framework.Scenes;
|
||||||
|
using OpenSim.Tests.Common;
|
||||||
|
using OpenSim.Tests.Common.Mock;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.ClientStack.LindenUDP.Tests
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class LLImageManagerTests
|
||||||
|
{
|
||||||
|
private AssetBase m_testImageAsset;
|
||||||
|
private Scene scene;
|
||||||
|
private LLImageManager llim;
|
||||||
|
private TestClient tc;
|
||||||
|
|
||||||
|
[TestFixtureSetUp]
|
||||||
|
public void FixtureInit()
|
||||||
|
{
|
||||||
|
using (
|
||||||
|
Stream resource
|
||||||
|
= GetType().Assembly.GetManifestResourceStream(
|
||||||
|
"OpenSim.Region.ClientStack.LindenUDP.Tests.Resources.4-tile2.jp2"))
|
||||||
|
{
|
||||||
|
using (BinaryReader br = new BinaryReader(resource))
|
||||||
|
{
|
||||||
|
m_testImageAsset
|
||||||
|
= new AssetBase(
|
||||||
|
TestHelpers.ParseTail(0x1),
|
||||||
|
"Test Image",
|
||||||
|
(sbyte)AssetType.Texture,
|
||||||
|
TestHelpers.ParseTail(0x2).ToString());
|
||||||
|
|
||||||
|
m_testImageAsset.Data = br.ReadBytes(99999999);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void SetUp()
|
||||||
|
{
|
||||||
|
UUID userId = TestHelpers.ParseTail(0x3);
|
||||||
|
|
||||||
|
J2KDecoderModule j2kdm = new J2KDecoderModule();
|
||||||
|
|
||||||
|
scene = SceneHelpers.SetupScene();
|
||||||
|
SceneHelpers.SetupSceneModules(scene, j2kdm);
|
||||||
|
|
||||||
|
tc = new TestClient(SceneHelpers.GenerateAgentData(userId), scene);
|
||||||
|
llim = new LLImageManager(tc, scene.AssetService, j2kdm);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestSendImage()
|
||||||
|
{
|
||||||
|
TestHelpers.InMethod();
|
||||||
|
// XmlConfigurator.Configure();
|
||||||
|
|
||||||
|
scene.AssetService.Store(m_testImageAsset);
|
||||||
|
|
||||||
|
TextureRequestArgs args = new TextureRequestArgs();
|
||||||
|
args.RequestedAssetID = m_testImageAsset.FullID;
|
||||||
|
args.DiscardLevel = 0;
|
||||||
|
args.PacketNumber = 1;
|
||||||
|
args.Priority = 5;
|
||||||
|
args.requestSequence = 1;
|
||||||
|
|
||||||
|
llim.EnqueueReq(args);
|
||||||
|
llim.ProcessImageQueue(20);
|
||||||
|
|
||||||
|
Assert.That(tc.SentImageDataPackets.Count, Is.EqualTo(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestDiscardImage()
|
||||||
|
{
|
||||||
|
TestHelpers.InMethod();
|
||||||
|
// XmlConfigurator.Configure();
|
||||||
|
|
||||||
|
scene.AssetService.Store(m_testImageAsset);
|
||||||
|
|
||||||
|
TextureRequestArgs args = new TextureRequestArgs();
|
||||||
|
args.RequestedAssetID = m_testImageAsset.FullID;
|
||||||
|
args.DiscardLevel = 0;
|
||||||
|
args.PacketNumber = 1;
|
||||||
|
args.Priority = 5;
|
||||||
|
args.requestSequence = 1;
|
||||||
|
llim.EnqueueReq(args);
|
||||||
|
|
||||||
|
// Now create a discard request
|
||||||
|
TextureRequestArgs discardArgs = new TextureRequestArgs();
|
||||||
|
discardArgs.RequestedAssetID = m_testImageAsset.FullID;
|
||||||
|
discardArgs.DiscardLevel = -1;
|
||||||
|
discardArgs.PacketNumber = 1;
|
||||||
|
discardArgs.Priority = 0;
|
||||||
|
discardArgs.requestSequence = 2;
|
||||||
|
llim.EnqueueReq(discardArgs);
|
||||||
|
|
||||||
|
llim.ProcessImageQueue(20);
|
||||||
|
|
||||||
|
Assert.That(tc.SentImageDataPackets.Count, Is.EqualTo(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestMissingImage()
|
||||||
|
{
|
||||||
|
TestHelpers.InMethod();
|
||||||
|
// XmlConfigurator.Configure();
|
||||||
|
|
||||||
|
TextureRequestArgs args = new TextureRequestArgs();
|
||||||
|
args.RequestedAssetID = m_testImageAsset.FullID;
|
||||||
|
args.DiscardLevel = 0;
|
||||||
|
args.PacketNumber = 1;
|
||||||
|
args.Priority = 5;
|
||||||
|
args.requestSequence = 1;
|
||||||
|
|
||||||
|
llim.EnqueueReq(args);
|
||||||
|
llim.ProcessImageQueue(20);
|
||||||
|
|
||||||
|
Assert.That(tc.SentImageDataPackets.Count, Is.EqualTo(0));
|
||||||
|
Assert.That(tc.SentImageNotInDatabasePackets.Count, Is.EqualTo(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -25,6 +25,7 @@
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
using System.Net;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
using OpenSim.Region.Framework.Scenes;
|
using OpenSim.Region.Framework.Scenes;
|
||||||
|
@ -52,15 +53,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
|
||||||
public override void Update() {}
|
public override void Update() {}
|
||||||
public override void LoadWorldMap() {}
|
public override void LoadWorldMap() {}
|
||||||
|
|
||||||
public override void AddNewClient(IClientAPI client)
|
public override ISceneAgent AddNewClient(IClientAPI client, PresenceType type)
|
||||||
{
|
{
|
||||||
client.OnObjectName += RecordObjectNameCall;
|
client.OnObjectName += RecordObjectNameCall;
|
||||||
|
|
||||||
|
// FIXME
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void RemoveClient(UUID agentID) {}
|
public override void RemoveClient(UUID agentID, bool someReason) {}
|
||||||
public override void CloseAllAgents(uint circuitcode) {}
|
// public override void CloseAllAgents(uint circuitcode) {}
|
||||||
|
public override bool CheckClient(UUID clientId, IPEndPoint endPoint) { return true; }
|
||||||
public override void OtherRegionUp(GridRegion otherRegion) { }
|
public override void OtherRegionUp(GridRegion otherRegion) { }
|
||||||
|
|
||||||
|
public override bool TryGetScenePresence(UUID uuid, out ScenePresence sp) { sp = null; return false; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Doesn't really matter what the call is - we're using this to test that a packet has actually been received
|
/// Doesn't really matter what the call is - we're using this to test that a packet has actually been received
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -27,7 +27,6 @@
|
||||||
|
|
||||||
using Nini.Config;
|
using Nini.Config;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using NUnit.Framework.SyntaxHelpers;
|
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
using OpenMetaverse.Packets;
|
using OpenMetaverse.Packets;
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
|
@ -42,65 +41,65 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class PacketHandlerTests
|
public class PacketHandlerTests
|
||||||
{
|
{
|
||||||
[Test]
|
// [Test]
|
||||||
/// <summary>
|
// /// <summary>
|
||||||
/// More a placeholder, really
|
// /// More a placeholder, really
|
||||||
/// </summary>
|
// /// </summary>
|
||||||
public void InPacketTest()
|
// public void InPacketTest()
|
||||||
{
|
// {
|
||||||
TestHelper.InMethod();
|
// TestHelper.InMethod();
|
||||||
|
//
|
||||||
AgentCircuitData agent = new AgentCircuitData();
|
// AgentCircuitData agent = new AgentCircuitData();
|
||||||
agent.AgentID = UUID.Random();
|
// agent.AgentID = UUID.Random();
|
||||||
agent.firstname = "testfirstname";
|
// agent.firstname = "testfirstname";
|
||||||
agent.lastname = "testlastname";
|
// agent.lastname = "testlastname";
|
||||||
agent.SessionID = UUID.Zero;
|
// agent.SessionID = UUID.Zero;
|
||||||
agent.SecureSessionID = UUID.Zero;
|
// agent.SecureSessionID = UUID.Zero;
|
||||||
agent.circuitcode = 123;
|
// agent.circuitcode = 123;
|
||||||
agent.BaseFolder = UUID.Zero;
|
// agent.BaseFolder = UUID.Zero;
|
||||||
agent.InventoryFolder = UUID.Zero;
|
// agent.InventoryFolder = UUID.Zero;
|
||||||
agent.startpos = Vector3.Zero;
|
// agent.startpos = Vector3.Zero;
|
||||||
agent.CapsPath = "http://wibble.com";
|
// agent.CapsPath = "http://wibble.com";
|
||||||
|
//
|
||||||
TestLLUDPServer testLLUDPServer;
|
// TestLLUDPServer testLLUDPServer;
|
||||||
TestLLPacketServer testLLPacketServer;
|
// TestLLPacketServer testLLPacketServer;
|
||||||
AgentCircuitManager acm;
|
// AgentCircuitManager acm;
|
||||||
IScene scene = new MockScene();
|
// IScene scene = new MockScene();
|
||||||
SetupStack(scene, out testLLUDPServer, out testLLPacketServer, out acm);
|
// SetupStack(scene, out testLLUDPServer, out testLLPacketServer, out acm);
|
||||||
|
//
|
||||||
TestClient testClient = new TestClient(agent, scene);
|
// TestClient testClient = new TestClient(agent, scene);
|
||||||
|
//
|
||||||
LLPacketHandler packetHandler
|
// LLPacketHandler packetHandler
|
||||||
= new LLPacketHandler(testClient, testLLPacketServer, new ClientStackUserSettings());
|
// = new LLPacketHandler(testClient, testLLPacketServer, new ClientStackUserSettings());
|
||||||
|
//
|
||||||
packetHandler.InPacket(new AgentAnimationPacket());
|
// packetHandler.InPacket(new AgentAnimationPacket());
|
||||||
LLQueItem receivedPacket = packetHandler.PacketQueue.Dequeue();
|
// LLQueItem receivedPacket = packetHandler.PacketQueue.Dequeue();
|
||||||
|
//
|
||||||
Assert.That(receivedPacket, Is.Not.Null);
|
// Assert.That(receivedPacket, Is.Not.Null);
|
||||||
Assert.That(receivedPacket.Incoming, Is.True);
|
// Assert.That(receivedPacket.Incoming, Is.True);
|
||||||
Assert.That(receivedPacket.Packet, Is.TypeOf(typeof(AgentAnimationPacket)));
|
// Assert.That(receivedPacket.Packet, Is.TypeOf(typeof(AgentAnimationPacket)));
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
/// <summary>
|
// /// <summary>
|
||||||
/// Add a client for testing
|
// /// Add a client for testing
|
||||||
/// </summary>
|
// /// </summary>
|
||||||
/// <param name="scene"></param>
|
// /// <param name="scene"></param>
|
||||||
/// <param name="testLLUDPServer"></param>
|
// /// <param name="testLLUDPServer"></param>
|
||||||
/// <param name="testPacketServer"></param>
|
// /// <param name="testPacketServer"></param>
|
||||||
/// <param name="acm">Agent circuit manager used in setting up the stack</param>
|
// /// <param name="acm">Agent circuit manager used in setting up the stack</param>
|
||||||
protected void SetupStack(
|
// protected void SetupStack(
|
||||||
IScene scene, out TestLLUDPServer testLLUDPServer, out TestLLPacketServer testPacketServer,
|
// IScene scene, out TestLLUDPServer testLLUDPServer, out TestLLPacketServer testPacketServer,
|
||||||
out AgentCircuitManager acm)
|
// out AgentCircuitManager acm)
|
||||||
{
|
// {
|
||||||
IConfigSource configSource = new IniConfigSource();
|
// IConfigSource configSource = new IniConfigSource();
|
||||||
ClientStackUserSettings userSettings = new ClientStackUserSettings();
|
// ClientStackUserSettings userSettings = new ClientStackUserSettings();
|
||||||
testLLUDPServer = new TestLLUDPServer();
|
// testLLUDPServer = new TestLLUDPServer();
|
||||||
acm = new AgentCircuitManager();
|
// acm = new AgentCircuitManager();
|
||||||
|
//
|
||||||
uint port = 666;
|
// uint port = 666;
|
||||||
testLLUDPServer.Initialise(null, ref port, 0, false, configSource, acm);
|
// testLLUDPServer.Initialise(null, ref port, 0, false, configSource, acm);
|
||||||
testPacketServer = new TestLLPacketServer(testLLUDPServer, userSettings);
|
// testPacketServer = new TestLLPacketServer(testLLUDPServer, userSettings);
|
||||||
testLLUDPServer.LocalScene = scene;
|
// testLLUDPServer.LocalScene = scene;
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
|
@ -29,105 +29,113 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
|
using Nini.Config;
|
||||||
using OpenMetaverse.Packets;
|
using OpenMetaverse.Packets;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
|
||||||
namespace OpenSim.Region.ClientStack.LindenUDP.Tests
|
namespace OpenSim.Region.ClientStack.LindenUDP.Tests
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This class enables synchronous testing of the LLUDPServer by allowing us to load our own data into the end
|
/// This class enables regression testing of the LLUDPServer by allowing us to intercept outgoing data.
|
||||||
/// receive event
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class TestLLUDPServer : LLUDPServer
|
public class TestLLUDPServer : LLUDPServer
|
||||||
{
|
{
|
||||||
/// <summary>
|
public List<Packet> PacketsSent { get; private set; }
|
||||||
/// The chunks of data to pass to the LLUDPServer when it calls EndReceive
|
|
||||||
/// </summary>
|
|
||||||
protected Queue<ChunkSenderTuple> m_chunksToLoad = new Queue<ChunkSenderTuple>();
|
|
||||||
|
|
||||||
protected override void BeginReceive()
|
public TestLLUDPServer(IPAddress listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port, IConfigSource configSource, AgentCircuitManager circuitManager)
|
||||||
|
: base(listenIP, ref port, proxyPortOffsetParm, allow_alternate_port, configSource, circuitManager)
|
||||||
{
|
{
|
||||||
if (m_chunksToLoad.Count > 0 && m_chunksToLoad.Peek().BeginReceiveException)
|
PacketsSent = new List<Packet>();
|
||||||
{
|
|
||||||
ChunkSenderTuple tuple = m_chunksToLoad.Dequeue();
|
|
||||||
reusedEpSender = tuple.Sender;
|
|
||||||
throw new SocketException();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool EndReceive(out int numBytes, IAsyncResult result, ref EndPoint epSender)
|
public override void SendAckImmediate(IPEndPoint remoteEndpoint, PacketAckPacket ack)
|
||||||
{
|
{
|
||||||
numBytes = 0;
|
PacketsSent.Add(ack);
|
||||||
|
|
||||||
//m_log.Debug("Queue size " + m_chunksToLoad.Count);
|
|
||||||
|
|
||||||
if (m_chunksToLoad.Count <= 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
ChunkSenderTuple tuple = m_chunksToLoad.Dequeue();
|
|
||||||
RecvBuffer = tuple.Data;
|
|
||||||
numBytes = tuple.Data.Length;
|
|
||||||
epSender = tuple.Sender;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void SendPacketTo(byte[] buffer, int size, SocketFlags flags, uint circuitcode)
|
public override void SendPacket(
|
||||||
|
LLUDPClient udpClient, Packet packet, ThrottleOutPacketType category, bool allowSplitting, UnackedPacketMethod method)
|
||||||
{
|
{
|
||||||
// Don't do anything just yet
|
PacketsSent.Add(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
//// /// <summary>
|
||||||
/// Signal that this chunk should throw an exception on Socket.BeginReceive()
|
//// /// The chunks of data to pass to the LLUDPServer when it calls EndReceive
|
||||||
/// </summary>
|
//// /// </summary>
|
||||||
/// <param name="epSender"></param>
|
//// protected Queue<ChunkSenderTuple> m_chunksToLoad = new Queue<ChunkSenderTuple>();
|
||||||
public void LoadReceiveWithBeginException(EndPoint epSender)
|
//
|
||||||
{
|
//// protected override void BeginReceive()
|
||||||
ChunkSenderTuple tuple = new ChunkSenderTuple(epSender);
|
//// {
|
||||||
tuple.BeginReceiveException = true;
|
//// if (m_chunksToLoad.Count > 0 && m_chunksToLoad.Peek().BeginReceiveException)
|
||||||
m_chunksToLoad.Enqueue(tuple);
|
//// {
|
||||||
}
|
//// ChunkSenderTuple tuple = m_chunksToLoad.Dequeue();
|
||||||
|
//// reusedEpSender = tuple.Sender;
|
||||||
/// <summary>
|
//// throw new SocketException();
|
||||||
/// Load some data to be received by the LLUDPServer on the next receive call
|
//// }
|
||||||
/// </summary>
|
//// }
|
||||||
/// <param name="data"></param>
|
//
|
||||||
/// <param name="epSender"></param>
|
//// protected override bool EndReceive(out int numBytes, IAsyncResult result, ref EndPoint epSender)
|
||||||
public void LoadReceive(byte[] data, EndPoint epSender)
|
//// {
|
||||||
{
|
//// numBytes = 0;
|
||||||
m_chunksToLoad.Enqueue(new ChunkSenderTuple(data, epSender));
|
////
|
||||||
}
|
//// //m_log.Debug("Queue size " + m_chunksToLoad.Count);
|
||||||
|
////
|
||||||
/// <summary>
|
//// if (m_chunksToLoad.Count <= 0)
|
||||||
/// Load a packet to be received by the LLUDPServer on the next receive call
|
//// return false;
|
||||||
/// </summary>
|
////
|
||||||
/// <param name="packet"></param>
|
//// ChunkSenderTuple tuple = m_chunksToLoad.Dequeue();
|
||||||
public void LoadReceive(Packet packet, EndPoint epSender)
|
//// RecvBuffer = tuple.Data;
|
||||||
{
|
//// numBytes = tuple.Data.Length;
|
||||||
LoadReceive(packet.ToBytes(), epSender);
|
//// epSender = tuple.Sender;
|
||||||
}
|
////
|
||||||
|
//// return true;
|
||||||
/// <summary>
|
//// }
|
||||||
/// Calls the protected asynchronous result method. This fires out all data chunks currently queued for send
|
//
|
||||||
/// </summary>
|
//// public override void SendPacketTo(byte[] buffer, int size, SocketFlags flags, uint circuitcode)
|
||||||
/// <param name="result"></param>
|
//// {
|
||||||
public void ReceiveData(IAsyncResult result)
|
//// // Don't do anything just yet
|
||||||
{
|
//// }
|
||||||
while (m_chunksToLoad.Count > 0)
|
//
|
||||||
OnReceivedData(result);
|
// /// <summary>
|
||||||
}
|
// /// Signal that this chunk should throw an exception on Socket.BeginReceive()
|
||||||
|
// /// </summary>
|
||||||
/// <summary>
|
// /// <param name="epSender"></param>
|
||||||
/// Has a circuit with the given code been established?
|
// public void LoadReceiveWithBeginException(EndPoint epSender)
|
||||||
/// </summary>
|
// {
|
||||||
/// <param name="circuitCode"></param>
|
// ChunkSenderTuple tuple = new ChunkSenderTuple(epSender);
|
||||||
/// <returns></returns>
|
// tuple.BeginReceiveException = true;
|
||||||
public bool HasCircuit(uint circuitCode)
|
// m_chunksToLoad.Enqueue(tuple);
|
||||||
{
|
// }
|
||||||
lock (clientCircuits_reverse)
|
//
|
||||||
{
|
// /// <summary>
|
||||||
return clientCircuits_reverse.ContainsKey(circuitCode);
|
// /// Load some data to be received by the LLUDPServer on the next receive call
|
||||||
}
|
// /// </summary>
|
||||||
}
|
// /// <param name="data"></param>
|
||||||
|
// /// <param name="epSender"></param>
|
||||||
|
// public void LoadReceive(byte[] data, EndPoint epSender)
|
||||||
|
// {
|
||||||
|
// m_chunksToLoad.Enqueue(new ChunkSenderTuple(data, epSender));
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /// <summary>
|
||||||
|
// /// Load a packet to be received by the LLUDPServer on the next receive call
|
||||||
|
// /// </summary>
|
||||||
|
// /// <param name="packet"></param>
|
||||||
|
// public void LoadReceive(Packet packet, EndPoint epSender)
|
||||||
|
// {
|
||||||
|
// LoadReceive(packet.ToBytes(), epSender);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /// <summary>
|
||||||
|
// /// Calls the protected asynchronous result method. This fires out all data chunks currently queued for send
|
||||||
|
// /// </summary>
|
||||||
|
// /// <param name="result"></param>
|
||||||
|
// public void ReceiveData(IAsyncResult result)
|
||||||
|
// {
|
||||||
|
// // Doesn't work the same way anymore
|
||||||
|
//// while (m_chunksToLoad.Count > 0)
|
||||||
|
//// OnReceivedData(result);
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -118,12 +118,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
/// Returns a list of all of the packets with a TickCount older than
|
/// Returns a list of all of the packets with a TickCount older than
|
||||||
/// the specified timeout
|
/// the specified timeout
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This function is not thread safe, and cannot be called
|
||||||
|
/// multiple times concurrently
|
||||||
|
/// </remarks>
|
||||||
/// <param name="timeoutMS">Number of ticks (milliseconds) before a
|
/// <param name="timeoutMS">Number of ticks (milliseconds) before a
|
||||||
/// packet is considered expired</param>
|
/// packet is considered expired
|
||||||
/// <returns>A list of all expired packets according to the given
|
/// </param>
|
||||||
/// expiration timeout</returns>
|
/// <returns>
|
||||||
/// <remarks>This function is not thread safe, and cannot be called
|
/// A list of all expired packets according to the given
|
||||||
/// multiple times concurrently</remarks>
|
/// expiration timeout
|
||||||
|
/// </returns>
|
||||||
public List<OutgoingPacket> GetExpiredPackets(int timeoutMS)
|
public List<OutgoingPacket> GetExpiredPackets(int timeoutMS)
|
||||||
{
|
{
|
||||||
ProcessQueues();
|
ProcessQueues();
|
||||||
|
@ -159,6 +164,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//if (expiredPackets != null)
|
||||||
|
// m_log.DebugFormat("[UNACKED PACKET COLLECTION]: Found {0} expired packets on timeout of {1}", expiredPackets.Count, timeoutMS);
|
||||||
|
|
||||||
return expiredPackets;
|
return expiredPackets;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,6 +182,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
PendingAck pendingAcknowledgement;
|
PendingAck pendingAcknowledgement;
|
||||||
while (m_pendingAcknowledgements.TryDequeue(out pendingAcknowledgement))
|
while (m_pendingAcknowledgements.TryDequeue(out pendingAcknowledgement))
|
||||||
{
|
{
|
||||||
|
//m_log.DebugFormat("[UNACKED PACKET COLLECTION]: Processing ack {0}", pendingAcknowledgement.SequenceNumber);
|
||||||
OutgoingPacket ackedPacket;
|
OutgoingPacket ackedPacket;
|
||||||
if (m_packets.TryGetValue(pendingAcknowledgement.SequenceNumber, out ackedPacket))
|
if (m_packets.TryGetValue(pendingAcknowledgement.SequenceNumber, out ackedPacket))
|
||||||
{
|
{
|
||||||
|
@ -196,6 +205,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
ackedPacket.Client.UpdateRoundTrip(rtt);
|
ackedPacket.Client.UpdateRoundTrip(rtt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//m_log.WarnFormat("[UNACKED PACKET COLLECTION]: Could not find packet with sequence number {0} to ack", pendingAcknowledgement.SequenceNumber);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -103,6 +103,10 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
|
||||||
// If it's cached, return the cached results
|
// If it's cached, return the cached results
|
||||||
if (m_decodedCache.TryGetValue(assetID, out result))
|
if (m_decodedCache.TryGetValue(assetID, out result))
|
||||||
{
|
{
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[J2KDecoderModule]: Returning existing cached {0} layers j2k decode for {1}",
|
||||||
|
// result.Length, assetID);
|
||||||
|
|
||||||
callback(assetID, result);
|
callback(assetID, result);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -129,18 +133,20 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
|
||||||
|
|
||||||
// Do Decode!
|
// Do Decode!
|
||||||
if (decode)
|
if (decode)
|
||||||
DoJ2KDecode(assetID, j2kData);
|
Decode(assetID, j2kData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
public bool Decode(UUID assetID, byte[] j2kData)
|
||||||
/// Provides a synchronous decode so that caller can be assured that this executes before the next line
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="assetID"></param>
|
|
||||||
/// <param name="j2kData"></param>
|
|
||||||
public void Decode(UUID assetID, byte[] j2kData)
|
|
||||||
{
|
{
|
||||||
DoJ2KDecode(assetID, j2kData);
|
OpenJPEG.J2KLayerInfo[] layers;
|
||||||
|
int components;
|
||||||
|
return Decode(assetID, j2kData, out layers, out components);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Decode(UUID assetID, byte[] j2kData, out OpenJPEG.J2KLayerInfo[] layers, out int components)
|
||||||
|
{
|
||||||
|
return DoJ2KDecode(assetID, j2kData, out layers, out components);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion IJ2KDecoder
|
#endregion IJ2KDecoder
|
||||||
|
@ -150,11 +156,21 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="assetID">UUID of Asset</param>
|
/// <param name="assetID">UUID of Asset</param>
|
||||||
/// <param name="j2kData">JPEG2000 data</param>
|
/// <param name="j2kData">JPEG2000 data</param>
|
||||||
private void DoJ2KDecode(UUID assetID, byte[] j2kData)
|
/// <param name="layers">layer data</param>
|
||||||
|
/// <param name="components">number of components</param>
|
||||||
|
/// <returns>true if decode was successful. false otherwise.</returns>
|
||||||
|
private bool DoJ2KDecode(UUID assetID, byte[] j2kData, out OpenJPEG.J2KLayerInfo[] layers, out int components)
|
||||||
{
|
{
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[J2KDecoderModule]: Doing J2K decoding of {0} bytes for asset {1}", j2kData.Length, assetID);
|
||||||
|
|
||||||
|
bool decodedSuccessfully = true;
|
||||||
|
|
||||||
//int DecodeTime = 0;
|
//int DecodeTime = 0;
|
||||||
//DecodeTime = Environment.TickCount;
|
//DecodeTime = Environment.TickCount;
|
||||||
OpenJPEG.J2KLayerInfo[] layers;
|
|
||||||
|
// We don't get this from CSJ2K. Is it relevant?
|
||||||
|
components = 0;
|
||||||
|
|
||||||
if (!TryLoadCacheForAsset(assetID, out layers))
|
if (!TryLoadCacheForAsset(assetID, out layers))
|
||||||
{
|
{
|
||||||
|
@ -189,14 +205,15 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
m_log.Warn("[J2KDecoderModule]: CSJ2K threw an exception decoding texture " + assetID + ": " + ex.Message);
|
m_log.Warn("[J2KDecoderModule]: CSJ2K threw an exception decoding texture " + assetID + ": " + ex.Message);
|
||||||
|
decodedSuccessfully = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int components;
|
|
||||||
if (!OpenJPEG.DecodeLayerBoundaries(j2kData, out layers, out components))
|
if (!OpenJPEG.DecodeLayerBoundaries(j2kData, out layers, out components))
|
||||||
{
|
{
|
||||||
m_log.Warn("[J2KDecoderModule]: OpenJPEG failed to decode texture " + assetID);
|
m_log.Warn("[J2KDecoderModule]: OpenJPEG failed to decode texture " + assetID);
|
||||||
|
decodedSuccessfully = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,6 +222,7 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
|
||||||
m_log.Warn("[J2KDecoderModule]: Failed to decode layer data for texture " + assetID + ", guessing sane defaults");
|
m_log.Warn("[J2KDecoderModule]: Failed to decode layer data for texture " + assetID + ", guessing sane defaults");
|
||||||
// Layer decoding completely failed. Guess at sane defaults for the layer boundaries
|
// Layer decoding completely failed. Guess at sane defaults for the layer boundaries
|
||||||
layers = CreateDefaultLayers(j2kData.Length);
|
layers = CreateDefaultLayers(j2kData.Length);
|
||||||
|
decodedSuccessfully = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cache Decoded layers
|
// Cache Decoded layers
|
||||||
|
@ -224,6 +242,8 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
|
||||||
m_notifyList.Remove(assetID);
|
m_notifyList.Remove(assetID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return decodedSuccessfully;
|
||||||
}
|
}
|
||||||
|
|
||||||
private OpenJPEG.J2KLayerInfo[] CreateDefaultLayers(int j2kLength)
|
private OpenJPEG.J2KLayerInfo[] CreateDefaultLayers(int j2kLength)
|
||||||
|
|
|
@ -75,7 +75,7 @@ namespace OpenSim.Region.CoreModules.Asset.Tests
|
||||||
TestHelpers.InMethod();
|
TestHelpers.InMethod();
|
||||||
// log4net.Config.XmlConfigurator.Configure();
|
// log4net.Config.XmlConfigurator.Configure();
|
||||||
|
|
||||||
AssetBase asset = AssetHelpers.CreateAsset();
|
AssetBase asset = AssetHelpers.CreateNotecardAsset();
|
||||||
asset.ID = TestHelpers.ParseTail(0x1).ToString();
|
asset.ID = TestHelpers.ParseTail(0x1).ToString();
|
||||||
|
|
||||||
// Check we don't get anything before the asset is put in the cache
|
// Check we don't get anything before the asset is put in the cache
|
||||||
|
@ -96,7 +96,7 @@ namespace OpenSim.Region.CoreModules.Asset.Tests
|
||||||
TestHelpers.InMethod();
|
TestHelpers.InMethod();
|
||||||
// log4net.Config.XmlConfigurator.Configure();
|
// log4net.Config.XmlConfigurator.Configure();
|
||||||
|
|
||||||
AssetBase asset = AssetHelpers.CreateAsset();
|
AssetBase asset = AssetHelpers.CreateNotecardAsset();
|
||||||
asset.ID = TestHelpers.ParseTail(0x2).ToString();
|
asset.ID = TestHelpers.ParseTail(0x2).ToString();
|
||||||
|
|
||||||
m_cache.Store(asset);
|
m_cache.Store(asset);
|
||||||
|
@ -113,7 +113,7 @@ namespace OpenSim.Region.CoreModules.Asset.Tests
|
||||||
TestHelpers.InMethod();
|
TestHelpers.InMethod();
|
||||||
// log4net.Config.XmlConfigurator.Configure();
|
// log4net.Config.XmlConfigurator.Configure();
|
||||||
|
|
||||||
AssetBase asset = AssetHelpers.CreateAsset();
|
AssetBase asset = AssetHelpers.CreateNotecardAsset();
|
||||||
asset.ID = TestHelpers.ParseTail(0x2).ToString();
|
asset.ID = TestHelpers.ParseTail(0x2).ToString();
|
||||||
|
|
||||||
m_cache.Store(asset);
|
m_cache.Store(asset);
|
||||||
|
|
|
@ -615,7 +615,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||||
so.AttachedAvatar = UUID.Zero;
|
so.AttachedAvatar = UUID.Zero;
|
||||||
rootPart.SetParentLocalId(0);
|
rootPart.SetParentLocalId(0);
|
||||||
so.ClearPartAttachmentData();
|
so.ClearPartAttachmentData();
|
||||||
rootPart.ApplyPhysics(rootPart.GetEffectiveObjectFlags(), rootPart.VolumeDetectActive, m_scene.m_physicalPrim);
|
rootPart.ApplyPhysics(rootPart.GetEffectiveObjectFlags(), rootPart.VolumeDetectActive);
|
||||||
so.HasGroupChanged = true;
|
so.HasGroupChanged = true;
|
||||||
rootPart.Rezzed = DateTime.Now;
|
rootPart.Rezzed = DateTime.Now;
|
||||||
rootPart.RemFlag(PrimFlags.TemporaryOnRez);
|
rootPart.RemFlag(PrimFlags.TemporaryOnRez);
|
||||||
|
@ -764,10 +764,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||||
so.AttachedAvatar = avatar.UUID;
|
so.AttachedAvatar = avatar.UUID;
|
||||||
|
|
||||||
if (so.RootPart.PhysActor != null)
|
if (so.RootPart.PhysActor != null)
|
||||||
{
|
so.RootPart.RemoveFromPhysics();
|
||||||
m_scene.PhysicsScene.RemovePrim(so.RootPart.PhysActor);
|
|
||||||
so.RootPart.PhysActor = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
so.AbsolutePosition = attachOffset;
|
so.AbsolutePosition = attachOffset;
|
||||||
so.RootPart.AttachedPos = attachOffset;
|
so.RootPart.AttachedPos = attachOffset;
|
||||||
|
|
|
@ -115,22 +115,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Check for the existence of the baked texture assets.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="client"></param>
|
|
||||||
public bool ValidateBakedTextureCache(IClientAPI client)
|
public bool ValidateBakedTextureCache(IClientAPI client)
|
||||||
{
|
|
||||||
return ValidateBakedTextureCache(client, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Check for the existence of the baked texture assets. Request a rebake
|
|
||||||
/// unless checkonly is true.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="client"></param>
|
|
||||||
/// <param name="checkonly"></param>
|
|
||||||
private bool ValidateBakedTextureCache(IClientAPI client, bool checkonly)
|
|
||||||
{
|
{
|
||||||
ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
|
ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
|
||||||
if (sp == null)
|
if (sp == null)
|
||||||
|
@ -164,17 +149,8 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||||
|
|
||||||
defonly = false; // found a non-default texture reference
|
defonly = false; // found a non-default texture reference
|
||||||
|
|
||||||
if (!CheckBakedTextureAsset(client, face.TextureID, idx))
|
if (m_scene.AssetService.Get(face.TextureID.ToString()) == null)
|
||||||
{
|
|
||||||
// the asset didn't exist if we are only checking, then we found a bad
|
|
||||||
// one and we're done otherwise, ask for a rebake
|
|
||||||
if (checkonly)
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
m_log.InfoFormat("[AVFACTORY]: missing baked texture {0}, requesting rebake", face.TextureID);
|
|
||||||
|
|
||||||
client.SendRebakeAvatarTextures(face.TextureID);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_log.DebugFormat("[AVFACTORY]: Completed texture check for {0}", client.AgentId);
|
m_log.DebugFormat("[AVFACTORY]: Completed texture check for {0}", client.AgentId);
|
||||||
|
@ -183,6 +159,53 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||||
return (defonly ? false : true);
|
return (defonly ? false : true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int RequestRebake(IScenePresence sp, bool missingTexturesOnly)
|
||||||
|
{
|
||||||
|
int texturesRebaked = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++)
|
||||||
|
{
|
||||||
|
int idx = AvatarAppearance.BAKE_INDICES[i];
|
||||||
|
Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx];
|
||||||
|
|
||||||
|
// if there is no texture entry, skip it
|
||||||
|
if (face == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[AVFACTORY]: Looking for texture {0}, id {1} for {2} {3}",
|
||||||
|
// face.TextureID, idx, client.Name, client.AgentId);
|
||||||
|
|
||||||
|
// if the texture is one of the "defaults" then skip it
|
||||||
|
// this should probably be more intelligent (skirt texture doesnt matter
|
||||||
|
// if the avatar isnt wearing a skirt) but if any of the main baked
|
||||||
|
// textures is default then the rest should be as well
|
||||||
|
if (face.TextureID == UUID.Zero || face.TextureID == AppearanceManager.DEFAULT_AVATAR_TEXTURE)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (missingTexturesOnly)
|
||||||
|
{
|
||||||
|
if (m_scene.AssetService.Get(face.TextureID.ToString()) != null)
|
||||||
|
continue;
|
||||||
|
else
|
||||||
|
m_log.DebugFormat(
|
||||||
|
"[AVFACTORY]: Missing baked texture {0} ({1}) for {2}, requesting rebake.",
|
||||||
|
face.TextureID, idx, sp.Name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_log.DebugFormat(
|
||||||
|
"[AVFACTORY]: Requesting rebake of {0} ({1}) for {2}.",
|
||||||
|
face.TextureID, idx, sp.Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
texturesRebaked++;
|
||||||
|
sp.ControllingClient.SendRebakeAvatarTextures(face.TextureID);
|
||||||
|
}
|
||||||
|
|
||||||
|
return texturesRebaked;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Set appearance data (texture asset IDs and slider settings) received from the client
|
/// Set appearance data (texture asset IDs and slider settings) received from the client
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -230,14 +253,14 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||||
{
|
{
|
||||||
changed = sp.Appearance.SetTextureEntries(textureEntry) || changed;
|
changed = sp.Appearance.SetTextureEntries(textureEntry) || changed;
|
||||||
|
|
||||||
m_log.InfoFormat("[AVFACTORY]: received texture update for {0}", client.AgentId);
|
if (!ValidateBakedTextureCache(sp.ControllingClient))
|
||||||
Util.FireAndForget(delegate(object o) { ValidateBakedTextureCache(client, false); });
|
RequestRebake(sp, true);
|
||||||
|
|
||||||
// This appears to be set only in the final stage of the appearance
|
// 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
|
// update transaction. In theory, we should be able to do an immediate
|
||||||
// appearance send and save here.
|
// appearance send and save here.
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// save only if there were changes, send no matter what (doesn't hurt to send twice)
|
// save only if there were changes, send no matter what (doesn't hurt to send twice)
|
||||||
if (changed)
|
if (changed)
|
||||||
QueueAppearanceSave(client.AgentId);
|
QueueAppearanceSave(client.AgentId);
|
||||||
|
@ -385,7 +408,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void QueueAppearanceSend(UUID agentid)
|
public void QueueAppearanceSend(UUID agentid)
|
||||||
{
|
{
|
||||||
// m_log.WarnFormat("[AVFACTORY]: Queue appearance send for {0}", agentid);
|
// m_log.DebugFormat("[AVFACTORY]: Queue appearance send for {0}", agentid);
|
||||||
|
|
||||||
// 10000 ticks per millisecond, 1000 milliseconds per second
|
// 10000 ticks per millisecond, 1000 milliseconds per second
|
||||||
long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_sendtime * 1000 * 10000);
|
long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_sendtime * 1000 * 10000);
|
||||||
|
@ -444,10 +467,17 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||||
Dictionary<UUID, long> sends = new Dictionary<UUID, long>(m_sendqueue);
|
Dictionary<UUID, long> sends = new Dictionary<UUID, long>(m_sendqueue);
|
||||||
foreach (KeyValuePair<UUID, long> kvp in sends)
|
foreach (KeyValuePair<UUID, long> kvp in sends)
|
||||||
{
|
{
|
||||||
if (kvp.Value < now)
|
// We have to load the key and value into local parameters to avoid a race condition if we loop
|
||||||
|
// around and load kvp with a different value before FireAndForget has launched its thread.
|
||||||
|
UUID avatarID = kvp.Key;
|
||||||
|
long sendTime = kvp.Value;
|
||||||
|
|
||||||
|
// m_log.DebugFormat("[AVFACTORY]: Handling queued appearance updates for {0}, update delta to now is {1}", avatarID, sendTime - now);
|
||||||
|
|
||||||
|
if (sendTime < now)
|
||||||
{
|
{
|
||||||
Util.FireAndForget(delegate(object o) { SendAppearance(kvp.Key); });
|
Util.FireAndForget(o => SendAppearance(avatarID));
|
||||||
m_sendqueue.Remove(kvp.Key);
|
m_sendqueue.Remove(avatarID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -457,17 +487,25 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||||
Dictionary<UUID, long> saves = new Dictionary<UUID, long>(m_savequeue);
|
Dictionary<UUID, long> saves = new Dictionary<UUID, long>(m_savequeue);
|
||||||
foreach (KeyValuePair<UUID, long> kvp in saves)
|
foreach (KeyValuePair<UUID, long> kvp in saves)
|
||||||
{
|
{
|
||||||
if (kvp.Value < now)
|
// We have to load the key and value into local parameters to avoid a race condition if we loop
|
||||||
|
// around and load kvp with a different value before FireAndForget has launched its thread.
|
||||||
|
UUID avatarID = kvp.Key;
|
||||||
|
long sendTime = kvp.Value;
|
||||||
|
|
||||||
|
if (sendTime < now)
|
||||||
{
|
{
|
||||||
Util.FireAndForget(delegate(object o) { SaveAppearance(kvp.Key); });
|
Util.FireAndForget(o => SaveAppearance(avatarID));
|
||||||
m_savequeue.Remove(kvp.Key);
|
m_savequeue.Remove(avatarID);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We must lock both queues here so that QueueAppearanceSave() or *Send() don't m_updateTimer.Start() on
|
||||||
|
// another thread inbetween the first count calls and m_updateTimer.Stop() on this thread.
|
||||||
|
lock (m_sendqueue)
|
||||||
if (m_savequeue.Count == 0 && m_sendqueue.Count == 0)
|
if (m_savequeue.Count == 0 && m_sendqueue.Count == 0)
|
||||||
m_updateTimer.Stop();
|
m_updateTimer.Stop();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
@ -535,6 +573,8 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||||
|
|
||||||
public bool SendAppearance(UUID agentId)
|
public bool SendAppearance(UUID agentId)
|
||||||
{
|
{
|
||||||
|
// m_log.DebugFormat("[AVFACTORY]: Sending appearance for {0}", agentId);
|
||||||
|
|
||||||
ScenePresence sp = m_scene.GetScenePresence(agentId);
|
ScenePresence sp = m_scene.GetScenePresence(agentId);
|
||||||
if (sp == null)
|
if (sp == null)
|
||||||
{
|
{
|
||||||
|
|
|
@ -279,12 +279,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
|
||||||
|
|
||||||
HashSet<UUID> receiverIDs = new HashSet<UUID>();
|
HashSet<UUID> receiverIDs = new HashSet<UUID>();
|
||||||
|
|
||||||
((Scene)c.Scene).ForEachScenePresence(
|
((Scene)c.Scene).ForEachRootScenePresence(
|
||||||
delegate(ScenePresence presence)
|
delegate(ScenePresence presence)
|
||||||
{
|
{
|
||||||
// ignore chat from child agents
|
|
||||||
if (presence.IsChildAgent) return;
|
|
||||||
|
|
||||||
IClientAPI client = presence.ControllingClient;
|
IClientAPI client = presence.ControllingClient;
|
||||||
|
|
||||||
// don't forward SayOwner chat from objects to
|
// don't forward SayOwner chat from objects to
|
||||||
|
|
|
@ -98,9 +98,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog
|
||||||
|
|
||||||
public void SendGeneralAlert(string message)
|
public void SendGeneralAlert(string message)
|
||||||
{
|
{
|
||||||
m_scene.ForEachScenePresence(delegate(ScenePresence presence)
|
m_scene.ForEachRootScenePresence(delegate(ScenePresence presence)
|
||||||
{
|
{
|
||||||
if (!presence.IsChildAgent)
|
|
||||||
presence.ControllingClient.SendAlertMessage(message);
|
presence.ControllingClient.SendAlertMessage(message);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -163,9 +162,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog
|
||||||
public void SendNotificationToUsersInRegion(
|
public void SendNotificationToUsersInRegion(
|
||||||
UUID fromAvatarID, string fromAvatarName, string message)
|
UUID fromAvatarID, string fromAvatarName, string message)
|
||||||
{
|
{
|
||||||
m_scene.ForEachScenePresence(delegate(ScenePresence presence)
|
m_scene.ForEachRootScenePresence(delegate(ScenePresence presence)
|
||||||
{
|
{
|
||||||
if (!presence.IsChildAgent)
|
|
||||||
presence.ControllingClient.SendBlueBoxMessage(fromAvatarID, fromAvatarName, message);
|
presence.ControllingClient.SendBlueBoxMessage(fromAvatarID, fromAvatarName, message);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -201,7 +199,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
OpenSim.Framework.Console.MainConsole.Instance.Output(
|
MainConsole.Instance.Output(
|
||||||
"Usage: alert <message> | alert-user <first> <last> <message>");
|
"Usage: alert <message> | alert-user <first> <last> <message>");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,7 @@ using OpenMetaverse;
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
using OpenSim.Framework.Servers.HttpServer;
|
using OpenSim.Framework.Servers.HttpServer;
|
||||||
using OpenSim.Framework.Communications;
|
using OpenSim.Framework.Communications;
|
||||||
|
using OpenSim.Framework.Servers;
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
using OpenSim.Region.Framework.Interfaces;
|
||||||
using OpenSim.Region.Framework.Scenes;
|
using OpenSim.Region.Framework.Scenes;
|
||||||
using OpenSim.Services.Interfaces;
|
using OpenSim.Services.Interfaces;
|
||||||
|
@ -78,10 +79,20 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
protected IFriendsService m_FriendsService = null;
|
protected IFriendsService m_FriendsService = null;
|
||||||
protected FriendsSimConnector m_FriendsSimConnector;
|
protected FriendsSimConnector m_FriendsSimConnector;
|
||||||
|
|
||||||
protected Dictionary<UUID, UserFriendData> m_Friends =
|
/// <summary>
|
||||||
new Dictionary<UUID, UserFriendData>();
|
/// Cache friends lists for users.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This is a complex and error-prone thing to do. At the moment, we assume that the efficiency gained in
|
||||||
|
/// permissions checks outweighs the disadvantages of that complexity.
|
||||||
|
/// </remarks>
|
||||||
|
protected Dictionary<UUID, UserFriendData> m_Friends = new Dictionary<UUID, UserFriendData>();
|
||||||
|
|
||||||
protected HashSet<UUID> m_NeedsListOfFriends = new HashSet<UUID>();
|
/// <summary>
|
||||||
|
/// Maintain a record of viewers that need to be sent notifications for friends that are online. This only
|
||||||
|
/// needs to be done on login. Subsequent online/offline friend changes are sent by a different mechanism.
|
||||||
|
/// </summary>
|
||||||
|
protected HashSet<UUID> m_NeedsListOfOnlineFriends = new HashSet<UUID>();
|
||||||
|
|
||||||
protected IPresenceService PresenceService
|
protected IPresenceService PresenceService
|
||||||
{
|
{
|
||||||
|
@ -164,6 +175,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
|
|
||||||
// Instantiate the request handler
|
// Instantiate the request handler
|
||||||
IHttpServer server = MainServer.GetHttpServer((uint)mPort);
|
IHttpServer server = MainServer.GetHttpServer((uint)mPort);
|
||||||
|
|
||||||
|
if (server != null)
|
||||||
server.AddStreamHandler(new FriendsRequestHandler(this));
|
server.AddStreamHandler(new FriendsRequestHandler(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,6 +199,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
{
|
{
|
||||||
if (!m_Enabled)
|
if (!m_Enabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_log.DebugFormat("[FRIENDS MODULE]: AddRegion on {0}", Name);
|
m_log.DebugFormat("[FRIENDS MODULE]: AddRegion on {0}", Name);
|
||||||
|
|
||||||
m_Scenes.Add(scene);
|
m_Scenes.Add(scene);
|
||||||
|
@ -238,16 +252,25 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
client.OnInstantMessage += OnInstantMessage;
|
client.OnInstantMessage += OnInstantMessage;
|
||||||
client.OnApproveFriendRequest += OnApproveFriendRequest;
|
client.OnApproveFriendRequest += OnApproveFriendRequest;
|
||||||
client.OnDenyFriendRequest += OnDenyFriendRequest;
|
client.OnDenyFriendRequest += OnDenyFriendRequest;
|
||||||
client.OnTerminateFriendship += OnTerminateFriendship;
|
client.OnTerminateFriendship += (thisClient, agentID, exfriendID) => RemoveFriendship(thisClient, exfriendID);
|
||||||
client.OnGrantUserRights += OnGrantUserRights;
|
client.OnGrantUserRights += OnGrantUserRights;
|
||||||
|
|
||||||
Util.FireAndForget(delegate { FetchFriendslist(client); });
|
// 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
|
||||||
|
// to GetFriends() will wait until CacheFriends() completes. Locks are insufficient.
|
||||||
|
CacheFriends(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Fetch the friends list or increment the refcount for the existing
|
/// <summary>
|
||||||
/// friends list
|
/// Cache the friends list or increment the refcount for the existing friends list.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="client">
|
||||||
|
/// </param>
|
||||||
|
/// <returns>
|
||||||
/// Returns true if the list was fetched, false if it wasn't
|
/// Returns true if the list was fetched, false if it wasn't
|
||||||
protected virtual bool FetchFriendslist(IClientAPI client)
|
/// </returns>
|
||||||
|
protected virtual bool CacheFriends(IClientAPI client)
|
||||||
{
|
{
|
||||||
UUID agentID = client.AgentId;
|
UUID agentID = client.AgentId;
|
||||||
lock (m_Friends)
|
lock (m_Friends)
|
||||||
|
@ -294,7 +317,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
|
|
||||||
private void OnMakeRootAgent(ScenePresence sp)
|
private void OnMakeRootAgent(ScenePresence sp)
|
||||||
{
|
{
|
||||||
RefetchFriends(sp.ControllingClient);
|
RecacheFriends(sp.ControllingClient);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnClientLogin(IClientAPI client)
|
private void OnClientLogin(IClientAPI client)
|
||||||
|
@ -306,8 +329,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
StatusChange(agentID, true);
|
StatusChange(agentID, true);
|
||||||
|
|
||||||
// Register that we need to send the list of online friends to this user
|
// Register that we need to send the list of online friends to this user
|
||||||
lock (m_NeedsListOfFriends)
|
lock (m_NeedsListOfOnlineFriends)
|
||||||
m_NeedsListOfFriends.Add(agentID);
|
m_NeedsListOfOnlineFriends.Add(agentID);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual bool SendFriendsOnlineIfNeeded(IClientAPI client)
|
public virtual bool SendFriendsOnlineIfNeeded(IClientAPI client)
|
||||||
|
@ -315,9 +338,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
UUID agentID = client.AgentId;
|
UUID agentID = client.AgentId;
|
||||||
|
|
||||||
// Check if the online friends list is needed
|
// Check if the online friends list is needed
|
||||||
lock (m_NeedsListOfFriends)
|
lock (m_NeedsListOfOnlineFriends)
|
||||||
{
|
{
|
||||||
if (!m_NeedsListOfFriends.Remove(agentID))
|
if (!m_NeedsListOfOnlineFriends.Remove(agentID))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -325,7 +348,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
List<UUID> online = GetOnlineFriends(agentID);
|
List<UUID> online = GetOnlineFriends(agentID);
|
||||||
if (online.Count > 0)
|
if (online.Count > 0)
|
||||||
{
|
{
|
||||||
m_log.DebugFormat("[FRIENDS MODULE]: User {0} in region {1} has {2} friends online", client.AgentId, client.Scene.RegionInfo.RegionName, online.Count);
|
m_log.DebugFormat(
|
||||||
|
"[FRIENDS MODULE]: User {0} in region {1} has {2} friends online",
|
||||||
|
client.Name, client.Scene.RegionInfo.RegionName, online.Count);
|
||||||
|
|
||||||
client.SendAgentOnline(online.ToArray());
|
client.SendAgentOnline(online.ToArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -575,19 +601,24 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
|
|
||||||
private void OnApproveFriendRequest(IClientAPI client, UUID agentID, UUID friendID, List<UUID> callingCardFolders)
|
private void OnApproveFriendRequest(IClientAPI client, UUID agentID, UUID friendID, List<UUID> callingCardFolders)
|
||||||
{
|
{
|
||||||
m_log.DebugFormat("[FRIENDS]: {0} accepted friendship from {1}", agentID, friendID);
|
m_log.DebugFormat("[FRIENDS]: {0} accepted friendship from {1}", client.AgentId, friendID);
|
||||||
|
|
||||||
StoreFriendships(agentID, friendID);
|
AddFriendship(client, friendID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddFriendship(IClientAPI client, UUID friendID)
|
||||||
|
{
|
||||||
|
StoreFriendships(client.AgentId, friendID);
|
||||||
|
|
||||||
// Update the local cache
|
// Update the local cache
|
||||||
RefetchFriends(client);
|
RecacheFriends(client);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Notify the friend
|
// Notify the friend
|
||||||
//
|
//
|
||||||
|
|
||||||
// Try Local
|
// Try Local
|
||||||
if (LocalFriendshipApproved(agentID, client.Name, friendID))
|
if (LocalFriendshipApproved(client.AgentId, client.Name, friendID))
|
||||||
{
|
{
|
||||||
client.SendAgentOnline(new UUID[] { friendID });
|
client.SendAgentOnline(new UUID[] { friendID });
|
||||||
return;
|
return;
|
||||||
|
@ -601,7 +632,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
if (friendSession != null)
|
if (friendSession != null)
|
||||||
{
|
{
|
||||||
GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID);
|
GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID);
|
||||||
m_FriendsSimConnector.FriendshipApproved(region, agentID, client.Name, friendID);
|
m_FriendsSimConnector.FriendshipApproved(region, client.AgentId, client.Name, friendID);
|
||||||
client.SendAgentOnline(new UUID[] { friendID });
|
client.SendAgentOnline(new UUID[] { friendID });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -636,13 +667,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnTerminateFriendship(IClientAPI client, UUID agentID, UUID exfriendID)
|
public void RemoveFriendship(IClientAPI client, UUID exfriendID)
|
||||||
{
|
{
|
||||||
if (!DeleteFriendship(agentID, exfriendID))
|
if (!DeleteFriendship(client.AgentId, exfriendID))
|
||||||
client.SendAlertMessage("Unable to terminate friendship on this sim.");
|
client.SendAlertMessage("Unable to terminate friendship on this sim.");
|
||||||
|
|
||||||
// Update local cache
|
// Update local cache
|
||||||
RefetchFriends(client);
|
RecacheFriends(client);
|
||||||
|
|
||||||
client.SendTerminateFriend(exfriendID);
|
client.SendTerminateFriend(exfriendID);
|
||||||
|
|
||||||
|
@ -661,7 +692,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
if (friendSession != null)
|
if (friendSession != null)
|
||||||
{
|
{
|
||||||
GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID);
|
GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID);
|
||||||
m_FriendsSimConnector.FriendshipTerminated(region, agentID, exfriendID);
|
m_FriendsSimConnector.FriendshipTerminated(region, client.AgentId, exfriendID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -756,7 +787,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
friendClient.SendInstantMessage(im);
|
friendClient.SendInstantMessage(im);
|
||||||
|
|
||||||
// Update the local cache
|
// Update the local cache
|
||||||
RefetchFriends(friendClient);
|
RecacheFriends(friendClient);
|
||||||
|
|
||||||
// we're done
|
// we're done
|
||||||
return true;
|
return true;
|
||||||
|
@ -789,7 +820,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
// the friend in this sim as root agent
|
// the friend in this sim as root agent
|
||||||
friendClient.SendTerminateFriend(exfriendID);
|
friendClient.SendTerminateFriend(exfriendID);
|
||||||
// update local cache
|
// update local cache
|
||||||
RefetchFriends(friendClient);
|
RecacheFriends(friendClient);
|
||||||
// we're done
|
// we're done
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -806,16 +837,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
if (onlineBitChanged)
|
if (onlineBitChanged)
|
||||||
{
|
{
|
||||||
if ((rights & (int)FriendRights.CanSeeOnline) == 1)
|
if ((rights & (int)FriendRights.CanSeeOnline) == 1)
|
||||||
friendClient.SendAgentOnline(new UUID[] { new UUID(userID) });
|
friendClient.SendAgentOnline(new UUID[] { userID });
|
||||||
else
|
else
|
||||||
friendClient.SendAgentOffline(new UUID[] { new UUID(userID) });
|
friendClient.SendAgentOffline(new UUID[] { userID });
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bool canEditObjectsChanged = ((rights ^ userFlags) & (int)FriendRights.CanModifyObjects) != 0;
|
bool canEditObjectsChanged = ((rights ^ userFlags) & (int)FriendRights.CanModifyObjects) != 0;
|
||||||
if (canEditObjectsChanged)
|
if (canEditObjectsChanged)
|
||||||
friendClient.SendChangeUserRights(userID, friendID, rights);
|
friendClient.SendChangeUserRights(userID, friendID, rights);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update local cache
|
// Update local cache
|
||||||
|
@ -868,7 +898,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Update loca cache only
|
/// Update local cache only
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="userID"></param>
|
/// <param name="userID"></param>
|
||||||
/// <param name="friendID"></param>
|
/// <param name="friendID"></param>
|
||||||
|
@ -889,7 +919,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
return FriendsService.GetFriends(client.AgentId);
|
return FriendsService.GetFriends(client.AgentId);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RefetchFriends(IClientAPI client)
|
private void RecacheFriends(IClientAPI client)
|
||||||
{
|
{
|
||||||
UUID agentID = client.AgentId;
|
UUID agentID = client.AgentId;
|
||||||
lock (m_Friends)
|
lock (m_Friends)
|
||||||
|
|
|
@ -30,7 +30,6 @@ using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
||||||
using log4net;
|
using log4net;
|
||||||
using Nini.Config;
|
using Nini.Config;
|
||||||
using Nwc.XmlRpc;
|
using Nwc.XmlRpc;
|
||||||
|
@ -84,9 +83,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
protected override bool FetchFriendslist(IClientAPI client)
|
protected override bool CacheFriends(IClientAPI client)
|
||||||
{
|
{
|
||||||
if (base.FetchFriendslist(client))
|
if (base.CacheFriends(client))
|
||||||
{
|
{
|
||||||
UUID agentID = client.AgentId;
|
UUID agentID = client.AgentId;
|
||||||
// we do this only for the root agent
|
// we do this only for the root agent
|
||||||
|
|
|
@ -0,0 +1,118 @@
|
||||||
|
/*
|
||||||
|
* 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 Nini.Config;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using OpenMetaverse;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Region.CoreModules.Avatar.Friends;
|
||||||
|
using OpenSim.Region.Framework.Scenes;
|
||||||
|
using OpenSim.Tests.Common;
|
||||||
|
using OpenSim.Tests.Common.Mock;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.CoreModules.Avatar.Friends.Tests
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class FriendsModuleTests
|
||||||
|
{
|
||||||
|
private FriendsModule m_fm;
|
||||||
|
private TestScene m_scene;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void Init()
|
||||||
|
{
|
||||||
|
IConfigSource config = new IniConfigSource();
|
||||||
|
config.AddConfig("Modules");
|
||||||
|
// Not strictly necessary since FriendsModule assumes it is the default (!)
|
||||||
|
config.Configs["Modules"].Set("FriendsModule", "FriendsModule");
|
||||||
|
config.AddConfig("Friends");
|
||||||
|
config.Configs["Friends"].Set("Connector", "OpenSim.Services.FriendsService.dll");
|
||||||
|
config.AddConfig("FriendsService");
|
||||||
|
config.Configs["FriendsService"].Set("StorageProvider", "OpenSim.Data.Null.dll");
|
||||||
|
|
||||||
|
m_scene = SceneHelpers.SetupScene();
|
||||||
|
m_fm = new FriendsModule();
|
||||||
|
SceneHelpers.SetupSceneModules(m_scene, config, m_fm);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestNoFriends()
|
||||||
|
{
|
||||||
|
TestHelpers.InMethod();
|
||||||
|
// log4net.Config.XmlConfigurator.Configure();
|
||||||
|
|
||||||
|
UUID userId = TestHelpers.ParseTail(0x1);
|
||||||
|
|
||||||
|
ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, userId);
|
||||||
|
|
||||||
|
Assert.That(((TestClient)sp.ControllingClient).ReceivedOfflineNotifications.Count, Is.EqualTo(0));
|
||||||
|
Assert.That(((TestClient)sp.ControllingClient).ReceivedOnlineNotifications.Count, Is.EqualTo(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestAddFriendshipWhileOnline()
|
||||||
|
{
|
||||||
|
TestHelpers.InMethod();
|
||||||
|
// log4net.Config.XmlConfigurator.Configure();
|
||||||
|
|
||||||
|
UUID userId = TestHelpers.ParseTail(0x1);
|
||||||
|
UUID user2Id = TestHelpers.ParseTail(0x2);
|
||||||
|
|
||||||
|
ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, userId);
|
||||||
|
ScenePresence sp2 = SceneHelpers.AddScenePresence(m_scene, user2Id);
|
||||||
|
|
||||||
|
// This fiendship is two-way but without a connector, only the first user will receive the online
|
||||||
|
// notification.
|
||||||
|
m_fm.AddFriendship(sp.ControllingClient, user2Id);
|
||||||
|
|
||||||
|
Assert.That(((TestClient)sp.ControllingClient).ReceivedOfflineNotifications.Count, Is.EqualTo(0));
|
||||||
|
Assert.That(((TestClient)sp.ControllingClient).ReceivedOnlineNotifications.Count, Is.EqualTo(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestRemoveFriendshipWhileOnline()
|
||||||
|
{
|
||||||
|
TestHelpers.InMethod();
|
||||||
|
// log4net.Config.XmlConfigurator.Configure();
|
||||||
|
|
||||||
|
UUID user1Id = TestHelpers.ParseTail(0x1);
|
||||||
|
UUID user2Id = TestHelpers.ParseTail(0x2);
|
||||||
|
|
||||||
|
ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, user1Id);
|
||||||
|
SceneHelpers.AddScenePresence(m_scene, user2Id);
|
||||||
|
|
||||||
|
m_fm.AddFriendship(sp.ControllingClient, user2Id);
|
||||||
|
m_fm.RemoveFriendship(sp.ControllingClient, user2Id);
|
||||||
|
|
||||||
|
TestClient user1Client = sp.ControllingClient as TestClient;
|
||||||
|
Assert.That(user1Client.ReceivedFriendshipTerminations.Count, Is.EqualTo(1));
|
||||||
|
Assert.That(user1Client.ReceivedFriendshipTerminations[0], Is.EqualTo(user2Id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -140,10 +140,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods
|
||||||
// This is a bit crude. It seems the client will be null before it actually stops the thread
|
// This is a bit crude. It seems the client will be null before it actually stops the thread
|
||||||
// The thread will kill itself eventually :/
|
// The thread will kill itself eventually :/
|
||||||
// Is there another way to make sure *all* clients get this 'inter region' message?
|
// Is there another way to make sure *all* clients get this 'inter region' message?
|
||||||
m_scene.ForEachScenePresence(
|
m_scene.ForEachRootScenePresence(
|
||||||
delegate(ScenePresence p)
|
delegate(ScenePresence p)
|
||||||
{
|
{
|
||||||
if (p.UUID != godID && !p.IsChildAgent)
|
if (p.UUID != godID)
|
||||||
{
|
{
|
||||||
// Possibly this should really be p.Close() though that method doesn't send a close
|
// Possibly this should really be p.Close() though that method doesn't send a close
|
||||||
// to the client
|
// to the client
|
||||||
|
|
|
@ -36,6 +36,7 @@ using Nwc.XmlRpc;
|
||||||
using Mono.Addins;
|
using Mono.Addins;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Framework.Servers;
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
using OpenSim.Region.Framework.Interfaces;
|
||||||
using OpenSim.Region.Framework.Scenes;
|
using OpenSim.Region.Framework.Scenes;
|
||||||
using GridRegion = OpenSim.Services.Interfaces.GridRegion;
|
using GridRegion = OpenSim.Services.Interfaces.GridRegion;
|
||||||
|
|
|
@ -34,6 +34,7 @@ using Nini.Config;
|
||||||
using Nwc.XmlRpc;
|
using Nwc.XmlRpc;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Framework.Servers;
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
using OpenSim.Region.Framework.Interfaces;
|
||||||
using OpenSim.Region.Framework.Scenes;
|
using OpenSim.Region.Framework.Scenes;
|
||||||
using GridRegion = OpenSim.Services.Interfaces.GridRegion;
|
using GridRegion = OpenSim.Services.Interfaces.GridRegion;
|
||||||
|
|
|
@ -275,19 +275,25 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
|
||||||
{
|
{
|
||||||
if (m_TransferModule != null)
|
if (m_TransferModule != null)
|
||||||
m_TransferModule.SendInstantMessage(im, delegate(bool success) {
|
m_TransferModule.SendInstantMessage(im, delegate(bool success) {
|
||||||
// Send BulkUpdateInventory
|
|
||||||
IInventoryService invService = scene.InventoryService;
|
|
||||||
UUID inventoryEntityID = new UUID(im.imSessionID); // The inventory item /folder, back from it's trip
|
|
||||||
|
|
||||||
InventoryFolderBase folder = new InventoryFolderBase(inventoryEntityID, client.AgentId);
|
// justincc - FIXME: Comment out for now. This code was added in commit db91044 Mon Aug 22 2011
|
||||||
folder = invService.GetFolder(folder);
|
// and is apparently supposed to fix bulk inventory updates after accepting items. But
|
||||||
|
// instead it appears to cause two copies of an accepted folder for the receiving user in
|
||||||
|
// at least some cases. Folder/item update is already done when the offer is made (see code above)
|
||||||
|
|
||||||
ScenePresence fromUser = scene.GetScenePresence(new UUID(im.fromAgentID));
|
// // Send BulkUpdateInventory
|
||||||
|
// IInventoryService invService = scene.InventoryService;
|
||||||
// If the user has left the scene by the time the message comes back then we can't send
|
// UUID inventoryEntityID = new UUID(im.imSessionID); // The inventory item /folder, back from it's trip
|
||||||
// them the update.
|
//
|
||||||
if (fromUser != null)
|
// InventoryFolderBase folder = new InventoryFolderBase(inventoryEntityID, client.AgentId);
|
||||||
fromUser.ControllingClient.SendBulkUpdateInventory(folder);
|
// folder = invService.GetFolder(folder);
|
||||||
|
//
|
||||||
|
// ScenePresence fromUser = scene.GetScenePresence(new UUID(im.fromAgentID));
|
||||||
|
//
|
||||||
|
// // If the user has left the scene by the time the message comes back then we can't send
|
||||||
|
// // them the update.
|
||||||
|
// if (fromUser != null)
|
||||||
|
// fromUser.ControllingClient.SendBulkUpdateInventory(folder);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,12 +29,14 @@ using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
using log4net;
|
using log4net;
|
||||||
using Nini.Config;
|
using Nini.Config;
|
||||||
using Mono.Addins;
|
using Mono.Addins;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
using OpenSim.Framework.Console;
|
using OpenSim.Framework.Console;
|
||||||
|
using OpenSim.Framework.Servers;
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
using OpenSim.Region.Framework.Interfaces;
|
||||||
using OpenSim.Region.Framework.Scenes;
|
using OpenSim.Region.Framework.Scenes;
|
||||||
using Caps=OpenSim.Framework.Capabilities.Caps;
|
using Caps=OpenSim.Framework.Capabilities.Caps;
|
||||||
|
@ -46,6 +48,8 @@ namespace OpenSim.Region.CoreModules.Framework
|
||||||
{
|
{
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
private string m_showCapsCommandFormat = " {0,-38} {1,-60}\n";
|
||||||
|
|
||||||
protected Scene m_scene;
|
protected Scene m_scene;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -67,7 +71,7 @@ namespace OpenSim.Region.CoreModules.Framework
|
||||||
m_scene.RegisterModuleInterface<ICapabilitiesModule>(this);
|
m_scene.RegisterModuleInterface<ICapabilitiesModule>(this);
|
||||||
MainConsole.Instance.Commands.AddCommand("Capabilities", false, "show caps",
|
MainConsole.Instance.Commands.AddCommand("Capabilities", false, "show caps",
|
||||||
"show caps",
|
"show caps",
|
||||||
"Shows all registered capabilities", CapabilitiesCommand);
|
"Shows all registered capabilities", HandleShowCapsCommand);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RegionLoaded(Scene scene)
|
public void RegionLoaded(Scene scene)
|
||||||
|
@ -226,21 +230,23 @@ namespace OpenSim.Region.CoreModules.Framework
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CapabilitiesCommand(string module, string[] cmdparams)
|
private void HandleShowCapsCommand(string module, string[] cmdparams)
|
||||||
{
|
{
|
||||||
System.Text.StringBuilder caps = new System.Text.StringBuilder();
|
StringBuilder caps = new StringBuilder();
|
||||||
caps.AppendFormat("Region {0}:\n", m_scene.RegionInfo.RegionName);
|
caps.AppendFormat("Region {0}:\n", m_scene.RegionInfo.RegionName);
|
||||||
|
|
||||||
foreach (KeyValuePair<UUID, Caps> kvp in m_capsObjects)
|
foreach (KeyValuePair<UUID, Caps> kvp in m_capsObjects)
|
||||||
{
|
{
|
||||||
caps.AppendFormat("** User {0}:\n", kvp.Key);
|
caps.AppendFormat("** User {0}:\n", kvp.Key);
|
||||||
for (IDictionaryEnumerator kvp2 = kvp.Value.CapsHandlers.CapsDetails.GetEnumerator(); kvp2.MoveNext(); )
|
|
||||||
|
for (IDictionaryEnumerator kvp2 = kvp.Value.CapsHandlers.GetCapsDetails(false).GetEnumerator(); kvp2.MoveNext(); )
|
||||||
{
|
{
|
||||||
Uri uri = new Uri(kvp2.Value.ToString());
|
Uri uri = new Uri(kvp2.Value.ToString());
|
||||||
caps.AppendFormat(" {0} = {1}\n", kvp2.Key, uri.PathAndQuery);
|
caps.AppendFormat(m_showCapsCommandFormat, kvp2.Key, uri.PathAndQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (KeyValuePair<string, string> kvp3 in kvp.Value.ExternalCapsHandlers)
|
foreach (KeyValuePair<string, string> kvp3 in kvp.Value.ExternalCapsHandlers)
|
||||||
caps.AppendFormat(" {0} = {1}\n", kvp3.Key, kvp3.Value);
|
caps.AppendFormat(m_showCapsCommandFormat, kvp3.Key, kvp3.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
MainConsole.Instance.Output(caps.ToString());
|
MainConsole.Instance.Output(caps.ToString());
|
||||||
|
|
|
@ -547,12 +547,20 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
userID = remoteClient.AgentId;
|
userID = remoteClient.AgentId;
|
||||||
|
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[INVENTORY ACCESS MODULE]: Target of {0} in CreateItemForObject() is {1} {2}",
|
||||||
|
// action, remoteClient.Name, userID);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// All returns / deletes go to the object owner
|
// All returns / deletes go to the object owner
|
||||||
//
|
//
|
||||||
userID = so.RootPart.OwnerID;
|
userID = so.RootPart.OwnerID;
|
||||||
|
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[INVENTORY ACCESS MODULE]: Target of {0} in CreateItemForObject() is object owner {1}",
|
||||||
|
// action, userID);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (userID == UUID.Zero) // Can't proceed
|
if (userID == UUID.Zero) // Can't proceed
|
||||||
|
@ -638,11 +646,11 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||||
}
|
}
|
||||||
|
|
||||||
// Override and put into where it came from, if it came
|
// Override and put into where it came from, if it came
|
||||||
// from anywhere in inventory
|
// from anywhere in inventory and the owner is taking it back.
|
||||||
//
|
//
|
||||||
if (action == DeRezAction.Take || action == DeRezAction.TakeCopy)
|
if (action == DeRezAction.Take || action == DeRezAction.TakeCopy)
|
||||||
{
|
{
|
||||||
if (so.RootPart.FromFolderID != UUID.Zero)
|
if (so.RootPart.FromFolderID != UUID.Zero && userID == remoteClient.AgentId)
|
||||||
{
|
{
|
||||||
InventoryFolderBase f = new InventoryFolderBase(so.RootPart.FromFolderID, userID);
|
InventoryFolderBase f = new InventoryFolderBase(so.RootPart.FromFolderID, userID);
|
||||||
folder = m_Scene.InventoryService.GetFolder(f);
|
folder = m_Scene.InventoryService.GetFolder(f);
|
||||||
|
|
|
@ -29,8 +29,31 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
|
||||||
{
|
{
|
||||||
interface IMonitor
|
interface IMonitor
|
||||||
{
|
{
|
||||||
double GetValue();
|
/// <summary>
|
||||||
|
/// Name of the monitor.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This is the name used in XML.
|
||||||
|
/// </remarks>
|
||||||
|
/// <returns></returns>
|
||||||
string GetName();
|
string GetName();
|
||||||
string GetFriendlyValue(); // Convert to readable numbers
|
|
||||||
|
/// <summary>
|
||||||
|
/// Value of this monitor
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
double GetValue();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Human-readable name of the monitor
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
string GetFriendlyName();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Human readable value.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
string GetFriendlyValue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
@ -32,6 +33,7 @@ using log4net;
|
||||||
using Nini.Config;
|
using Nini.Config;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Framework.Servers;
|
||||||
using OpenSim.Region.CoreModules.Framework.Monitoring.Alerts;
|
using OpenSim.Region.CoreModules.Framework.Monitoring.Alerts;
|
||||||
using OpenSim.Region.CoreModules.Framework.Monitoring.Monitors;
|
using OpenSim.Region.CoreModules.Framework.Monitoring.Monitors;
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
using OpenSim.Region.Framework.Interfaces;
|
||||||
|
@ -41,16 +43,50 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
|
||||||
{
|
{
|
||||||
public class MonitorModule : IRegionModule
|
public class MonitorModule : IRegionModule
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Is this module enabled?
|
||||||
|
/// </summary>
|
||||||
|
public bool Enabled { get; private set; }
|
||||||
|
|
||||||
private Scene m_scene;
|
private Scene m_scene;
|
||||||
private readonly List<IMonitor> m_monitors = new List<IMonitor>();
|
private readonly List<IMonitor> m_monitors = new List<IMonitor>();
|
||||||
private readonly List<IAlert> m_alerts = new List<IAlert>();
|
private readonly List<IAlert> m_alerts = new List<IAlert>();
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
#region Implementation of IRegionModule
|
||||||
|
|
||||||
|
public MonitorModule()
|
||||||
|
{
|
||||||
|
Enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Initialise(Scene scene, IConfigSource source)
|
||||||
|
{
|
||||||
|
IConfig cnfg = source.Configs["Monitoring"];
|
||||||
|
|
||||||
|
if (cnfg != null)
|
||||||
|
Enabled = cnfg.GetBoolean("Enabled", true);
|
||||||
|
|
||||||
|
if (!Enabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_scene = scene;
|
||||||
|
|
||||||
|
m_scene.AddCommand(this, "monitor report",
|
||||||
|
"monitor report",
|
||||||
|
"Returns a variety of statistics about the current region and/or simulator",
|
||||||
|
DebugMonitors);
|
||||||
|
|
||||||
|
MainServer.Instance.AddHTTPHandler("/monitorstats/" + m_scene.RegionInfo.RegionID, StatsPage);
|
||||||
|
MainServer.Instance.AddHTTPHandler(
|
||||||
|
"/monitorstats/" + Uri.EscapeDataString(m_scene.RegionInfo.RegionName), StatsPage);
|
||||||
|
}
|
||||||
|
|
||||||
public void DebugMonitors(string module, string[] args)
|
public void DebugMonitors(string module, string[] args)
|
||||||
{
|
{
|
||||||
foreach (IMonitor monitor in m_monitors)
|
foreach (IMonitor monitor in m_monitors)
|
||||||
{
|
{
|
||||||
m_log.Info("[MonitorModule] " + m_scene.RegionInfo.RegionName + " reports " + monitor.GetName() + " = " + monitor.GetFriendlyValue());
|
m_log.Info("[MonitorModule]: " + m_scene.RegionInfo.RegionName + " reports " + monitor.GetFriendlyName() + " = " + monitor.GetFriendlyValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,20 +98,6 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Implementation of IRegionModule
|
|
||||||
|
|
||||||
public void Initialise(Scene scene, IConfigSource source)
|
|
||||||
{
|
|
||||||
m_scene = scene;
|
|
||||||
|
|
||||||
m_scene.AddCommand(this, "monitor report",
|
|
||||||
"monitor report",
|
|
||||||
"Returns a variety of statistics about the current region and/or simulator",
|
|
||||||
DebugMonitors);
|
|
||||||
|
|
||||||
MainServer.Instance.AddHTTPHandler("/monitorstats/" + m_scene.RegionInfo.RegionID + "/", StatsPage);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Hashtable StatsPage(Hashtable request)
|
public Hashtable StatsPage(Hashtable request)
|
||||||
{
|
{
|
||||||
// If request was for a specific monitor
|
// If request was for a specific monitor
|
||||||
|
@ -114,11 +136,9 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
|
||||||
string xml = "<data>";
|
string xml = "<data>";
|
||||||
foreach (IMonitor monitor in m_monitors)
|
foreach (IMonitor monitor in m_monitors)
|
||||||
{
|
{
|
||||||
string elemName = monitor.ToString();
|
string elemName = monitor.GetName();
|
||||||
if (elemName.StartsWith(monitor.GetType().Namespace))
|
xml += "<" + elemName + ">" + monitor.GetValue().ToString() + "</" + elemName + ">";
|
||||||
elemName = elemName.Substring(monitor.GetType().Namespace.Length + 1);
|
// m_log.DebugFormat("[MONITOR MODULE]: {0} = {1}", elemName, monitor.GetValue());
|
||||||
|
|
||||||
xml += "<" + elemName + ">" + monitor.GetValue() + "</" + elemName + ">";
|
|
||||||
}
|
}
|
||||||
xml += "</data>";
|
xml += "</data>";
|
||||||
|
|
||||||
|
@ -133,6 +153,9 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
|
||||||
|
|
||||||
public void PostInitialise()
|
public void PostInitialise()
|
||||||
{
|
{
|
||||||
|
if (!Enabled)
|
||||||
|
return;
|
||||||
|
|
||||||
m_monitors.Add(new AgentCountMonitor(m_scene));
|
m_monitors.Add(new AgentCountMonitor(m_scene));
|
||||||
m_monitors.Add(new ChildAgentCountMonitor(m_scene));
|
m_monitors.Add(new ChildAgentCountMonitor(m_scene));
|
||||||
m_monitors.Add(new GCMemoryMonitor());
|
m_monitors.Add(new GCMemoryMonitor());
|
||||||
|
@ -146,6 +169,158 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
|
||||||
m_monitors.Add(new LandFrameMonitor(m_scene));
|
m_monitors.Add(new LandFrameMonitor(m_scene));
|
||||||
m_monitors.Add(new LastFrameTimeMonitor(m_scene));
|
m_monitors.Add(new LastFrameTimeMonitor(m_scene));
|
||||||
|
|
||||||
|
m_monitors.Add(
|
||||||
|
new GenericMonitor(
|
||||||
|
m_scene,
|
||||||
|
"TimeDilationMonitor",
|
||||||
|
"Time Dilation",
|
||||||
|
m => m.Scene.StatsReporter.LastReportedSimStats[0],
|
||||||
|
m => m.GetValue().ToString()));
|
||||||
|
|
||||||
|
m_monitors.Add(
|
||||||
|
new GenericMonitor(
|
||||||
|
m_scene,
|
||||||
|
"SimFPSMonitor",
|
||||||
|
"Sim FPS",
|
||||||
|
m => m.Scene.StatsReporter.LastReportedSimStats[1],
|
||||||
|
m => string.Format("{0}", m.GetValue())));
|
||||||
|
|
||||||
|
m_monitors.Add(
|
||||||
|
new GenericMonitor(
|
||||||
|
m_scene,
|
||||||
|
"PhysicsFPSMonitor",
|
||||||
|
"Physics FPS",
|
||||||
|
m => m.Scene.StatsReporter.LastReportedSimStats[2],
|
||||||
|
m => string.Format("{0}", m.GetValue())));
|
||||||
|
|
||||||
|
m_monitors.Add(
|
||||||
|
new GenericMonitor(
|
||||||
|
m_scene,
|
||||||
|
"AgentUpdatesPerSecondMonitor",
|
||||||
|
"Agent Updates",
|
||||||
|
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(
|
||||||
|
new GenericMonitor(
|
||||||
|
m_scene,
|
||||||
|
"ActiveObjectCountMonitor",
|
||||||
|
"Active Objects",
|
||||||
|
m => m.Scene.StatsReporter.LastReportedSimStats[7],
|
||||||
|
m => string.Format("{0}", m.GetValue())));
|
||||||
|
|
||||||
|
m_monitors.Add(
|
||||||
|
new GenericMonitor(
|
||||||
|
m_scene,
|
||||||
|
"ActiveScriptsMonitor",
|
||||||
|
"Active Scripts",
|
||||||
|
m => m.Scene.StatsReporter.LastReportedSimStats[19],
|
||||||
|
m => string.Format("{0}", m.GetValue())));
|
||||||
|
|
||||||
|
m_monitors.Add(
|
||||||
|
new GenericMonitor(
|
||||||
|
m_scene,
|
||||||
|
"ScriptEventsPerSecondMonitor",
|
||||||
|
"Script Events",
|
||||||
|
m => m.Scene.StatsReporter.LastReportedSimStats[20],
|
||||||
|
m => string.Format("{0} per second", m.GetValue())));
|
||||||
|
|
||||||
|
m_monitors.Add(
|
||||||
|
new GenericMonitor(
|
||||||
|
m_scene,
|
||||||
|
"InPacketsPerSecondMonitor",
|
||||||
|
"In Packets",
|
||||||
|
m => m.Scene.StatsReporter.LastReportedSimStats[13],
|
||||||
|
m => string.Format("{0} per second", m.GetValue())));
|
||||||
|
|
||||||
|
m_monitors.Add(
|
||||||
|
new GenericMonitor(
|
||||||
|
m_scene,
|
||||||
|
"OutPacketsPerSecondMonitor",
|
||||||
|
"Out Packets",
|
||||||
|
m => m.Scene.StatsReporter.LastReportedSimStats[14],
|
||||||
|
m => string.Format("{0} per second", m.GetValue())));
|
||||||
|
|
||||||
|
m_monitors.Add(
|
||||||
|
new GenericMonitor(
|
||||||
|
m_scene,
|
||||||
|
"UnackedBytesMonitor",
|
||||||
|
"Unacked Bytes",
|
||||||
|
m => m.Scene.StatsReporter.LastReportedSimStats[15],
|
||||||
|
m => string.Format("{0}", m.GetValue())));
|
||||||
|
|
||||||
|
m_monitors.Add(
|
||||||
|
new GenericMonitor(
|
||||||
|
m_scene,
|
||||||
|
"PendingDownloadsMonitor",
|
||||||
|
"Pending Downloads",
|
||||||
|
m => m.Scene.StatsReporter.LastReportedSimStats[17],
|
||||||
|
m => string.Format("{0}", m.GetValue())));
|
||||||
|
|
||||||
|
m_monitors.Add(
|
||||||
|
new GenericMonitor(
|
||||||
|
m_scene,
|
||||||
|
"PendingUploadsMonitor",
|
||||||
|
"Pending Uploads",
|
||||||
|
m => m.Scene.StatsReporter.LastReportedSimStats[18],
|
||||||
|
m => string.Format("{0}", m.GetValue())));
|
||||||
|
|
||||||
|
m_monitors.Add(
|
||||||
|
new GenericMonitor(
|
||||||
|
m_scene,
|
||||||
|
"TotalFrameTimeMonitor",
|
||||||
|
"Total Frame Time",
|
||||||
|
m => m.Scene.StatsReporter.LastReportedSimStats[8],
|
||||||
|
m => string.Format("{0} ms", m.GetValue())));
|
||||||
|
|
||||||
|
m_monitors.Add(
|
||||||
|
new GenericMonitor(
|
||||||
|
m_scene,
|
||||||
|
"NetFrameTimeMonitor",
|
||||||
|
"Net Frame Time",
|
||||||
|
m => m.Scene.StatsReporter.LastReportedSimStats[9],
|
||||||
|
m => string.Format("{0} ms", m.GetValue())));
|
||||||
|
|
||||||
|
m_monitors.Add(
|
||||||
|
new GenericMonitor(
|
||||||
|
m_scene,
|
||||||
|
"PhysicsFrameTimeMonitor",
|
||||||
|
"Physics Frame Time",
|
||||||
|
m => m.Scene.StatsReporter.LastReportedSimStats[10],
|
||||||
|
m => string.Format("{0} ms", m.GetValue())));
|
||||||
|
|
||||||
|
m_monitors.Add(
|
||||||
|
new GenericMonitor(
|
||||||
|
m_scene,
|
||||||
|
"SimulationFrameTimeMonitor",
|
||||||
|
"Simulation Frame Time",
|
||||||
|
m => m.Scene.StatsReporter.LastReportedSimStats[12],
|
||||||
|
m => string.Format("{0} ms", m.GetValue())));
|
||||||
|
|
||||||
|
m_monitors.Add(
|
||||||
|
new GenericMonitor(
|
||||||
|
m_scene,
|
||||||
|
"AgentFrameTimeMonitor",
|
||||||
|
"Agent Frame Time",
|
||||||
|
m => m.Scene.StatsReporter.LastReportedSimStats[16],
|
||||||
|
m => string.Format("{0} ms", m.GetValue())));
|
||||||
|
|
||||||
|
m_monitors.Add(
|
||||||
|
new GenericMonitor(
|
||||||
|
m_scene,
|
||||||
|
"ImagesFrameTimeMonitor",
|
||||||
|
"Images Frame Time",
|
||||||
|
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_monitors.Find(x => x is LastFrameTimeMonitor) as LastFrameTimeMonitor));
|
||||||
|
|
||||||
foreach (IAlert alert in m_alerts)
|
foreach (IAlert alert in m_alerts)
|
||||||
|
@ -161,7 +336,6 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
|
||||||
|
|
||||||
public void Close()
|
public void Close()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Name
|
public string Name
|
||||||
|
|
|
@ -40,12 +40,17 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring.Monitors
|
||||||
|
|
||||||
#region Implementation of IMonitor
|
#region Implementation of IMonitor
|
||||||
|
|
||||||
|
public string GetName()
|
||||||
|
{
|
||||||
|
return "AgentCountMonitor";
|
||||||
|
}
|
||||||
|
|
||||||
public double GetValue()
|
public double GetValue()
|
||||||
{
|
{
|
||||||
return m_scene.SceneGraph.GetRootAgentCount();
|
return m_scene.SceneGraph.GetRootAgentCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetName()
|
public string GetFriendlyName()
|
||||||
{
|
{
|
||||||
return "Root Agent Count";
|
return "Root Agent Count";
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,12 +40,17 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring.Monitors
|
||||||
|
|
||||||
#region Implementation of IMonitor
|
#region Implementation of IMonitor
|
||||||
|
|
||||||
|
public string GetName()
|
||||||
|
{
|
||||||
|
return "ChildAgentCountMonitor";
|
||||||
|
}
|
||||||
|
|
||||||
public double GetValue()
|
public double GetValue()
|
||||||
{
|
{
|
||||||
return m_scene.SceneGraph.GetChildAgentCount();
|
return m_scene.SceneGraph.GetChildAgentCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetName()
|
public string GetFriendlyName()
|
||||||
{
|
{
|
||||||
return "Child Agent Count";
|
return "Child Agent Count";
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,12 +40,17 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring.Monitors
|
||||||
|
|
||||||
#region Implementation of IMonitor
|
#region Implementation of IMonitor
|
||||||
|
|
||||||
|
public string GetName()
|
||||||
|
{
|
||||||
|
return "EventFrameMonitor";
|
||||||
|
}
|
||||||
|
|
||||||
public double GetValue()
|
public double GetValue()
|
||||||
{
|
{
|
||||||
return m_scene.MonitorEventTime;
|
return m_scene.MonitorEventTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetName()
|
public string GetFriendlyName()
|
||||||
{
|
{
|
||||||
return "Total Event Frame Time";
|
return "Total Event Frame Time";
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,12 +33,17 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring.Monitors
|
||||||
{
|
{
|
||||||
#region Implementation of IMonitor
|
#region Implementation of IMonitor
|
||||||
|
|
||||||
|
public string GetName()
|
||||||
|
{
|
||||||
|
return "GCMemoryMonitor";
|
||||||
|
}
|
||||||
|
|
||||||
public double GetValue()
|
public double GetValue()
|
||||||
{
|
{
|
||||||
return GC.GetTotalMemory(false);
|
return GC.GetTotalMemory(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetName()
|
public string GetFriendlyName()
|
||||||
{
|
{
|
||||||
return "GC Reported Memory";
|
return "GC Reported Memory";
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,43 +26,55 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
|
||||||
using OpenMetaverse;
|
|
||||||
using OpenSim.Framework;
|
|
||||||
using OpenSim.Region.Framework.Scenes;
|
using OpenSim.Region.Framework.Scenes;
|
||||||
|
|
||||||
namespace OpenSim.Region.Examples.SimpleModule
|
namespace OpenSim.Region.CoreModules.Framework.Monitoring.Monitors
|
||||||
{
|
{
|
||||||
public class CpuCounterObject : SceneObjectGroup
|
class GenericMonitor : IMonitor
|
||||||
{
|
{
|
||||||
protected override bool InSceneBackup
|
public Scene Scene { get; private set; }
|
||||||
|
public string Name { get; private set; }
|
||||||
|
public string FriendlyName { get; private set; }
|
||||||
|
|
||||||
|
private readonly Func<GenericMonitor, double> m_getValueAction;
|
||||||
|
private readonly Func<GenericMonitor, string> m_getFriendlyValueAction;
|
||||||
|
|
||||||
|
public GenericMonitor(
|
||||||
|
Scene scene,
|
||||||
|
string name,
|
||||||
|
string friendlyName,
|
||||||
|
Func<GenericMonitor, double> getValueAction,
|
||||||
|
Func<GenericMonitor, string> getFriendlyValueAction)
|
||||||
{
|
{
|
||||||
get
|
Scene = scene;
|
||||||
{
|
Name = name;
|
||||||
return false;
|
FriendlyName = name;
|
||||||
}
|
m_getFriendlyValueAction = getFriendlyValueAction;
|
||||||
|
m_getValueAction = getValueAction;
|
||||||
}
|
}
|
||||||
|
|
||||||
private PerformanceCounter m_counter;
|
public double GetValue()
|
||||||
|
|
||||||
public CpuCounterObject(UUID ownerID, Vector3 pos)
|
|
||||||
: base(ownerID, pos, PrimitiveBaseShape.Default)
|
|
||||||
{
|
{
|
||||||
String objectName = "Processor";
|
return m_getValueAction(this);
|
||||||
String counterName = "% Processor Time";
|
|
||||||
String instanceName = "_Total";
|
|
||||||
|
|
||||||
m_counter = new PerformanceCounter(objectName, counterName, instanceName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void UpdateMovement()
|
public string GetName()
|
||||||
{
|
{
|
||||||
float cpu = m_counter.NextValue()/40f;
|
return Name;
|
||||||
Vector3 size = new Vector3(cpu, cpu, cpu);
|
}
|
||||||
|
|
||||||
RootPart.Resize(size);
|
public string GetFriendlyName()
|
||||||
|
{
|
||||||
|
return FriendlyName;
|
||||||
|
}
|
||||||
|
|
||||||
base.UpdateMovement();
|
public string GetFriendlyValue()
|
||||||
|
{
|
||||||
|
return m_getFriendlyValueAction(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -40,12 +40,17 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring.Monitors
|
||||||
|
|
||||||
#region Implementation of IMonitor
|
#region Implementation of IMonitor
|
||||||
|
|
||||||
|
public string GetName()
|
||||||
|
{
|
||||||
|
return "LandFrameMonitor";
|
||||||
|
}
|
||||||
|
|
||||||
public double GetValue()
|
public double GetValue()
|
||||||
{
|
{
|
||||||
return m_scene.MonitorLandTime;
|
return m_scene.MonitorLandTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetName()
|
public string GetFriendlyName()
|
||||||
{
|
{
|
||||||
return "Land Frame Time";
|
return "Land Frame Time";
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,12 +41,17 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring.Monitors
|
||||||
|
|
||||||
#region Implementation of IMonitor
|
#region Implementation of IMonitor
|
||||||
|
|
||||||
|
public string GetName()
|
||||||
|
{
|
||||||
|
return "LastFrameTimeMonitor";
|
||||||
|
}
|
||||||
|
|
||||||
public double GetValue()
|
public double GetValue()
|
||||||
{
|
{
|
||||||
return Environment.TickCount - m_scene.MonitorLastFrameTick;
|
return Environment.TickCount - m_scene.MonitorLastFrameTick;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetName()
|
public string GetFriendlyName()
|
||||||
{
|
{
|
||||||
return "Last Completed Frame At";
|
return "Last Completed Frame At";
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,12 +40,17 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring.Monitors
|
||||||
|
|
||||||
#region Implementation of IMonitor
|
#region Implementation of IMonitor
|
||||||
|
|
||||||
|
public string GetName()
|
||||||
|
{
|
||||||
|
return "ObjectCountMonitor";
|
||||||
|
}
|
||||||
|
|
||||||
public double GetValue()
|
public double GetValue()
|
||||||
{
|
{
|
||||||
return m_scene.SceneGraph.GetTotalObjectsCount();
|
return m_scene.SceneGraph.GetTotalObjectsCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetName()
|
public string GetFriendlyName()
|
||||||
{
|
{
|
||||||
return "Total Objects Count";
|
return "Total Objects Count";
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,12 +33,17 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring.Monitors
|
||||||
{
|
{
|
||||||
#region Implementation of IMonitor
|
#region Implementation of IMonitor
|
||||||
|
|
||||||
|
public string GetName()
|
||||||
|
{
|
||||||
|
return "PWSMemoryMonitor";
|
||||||
|
}
|
||||||
|
|
||||||
public double GetValue()
|
public double GetValue()
|
||||||
{
|
{
|
||||||
return System.Diagnostics.Process.GetCurrentProcess().PrivateMemorySize64;
|
return System.Diagnostics.Process.GetCurrentProcess().PrivateMemorySize64;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetName()
|
public string GetFriendlyName()
|
||||||
{
|
{
|
||||||
return "Private Working Set Memory";
|
return "Private Working Set Memory";
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,12 +40,17 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring.Monitors
|
||||||
|
|
||||||
#region Implementation of IMonitor
|
#region Implementation of IMonitor
|
||||||
|
|
||||||
|
public string GetName()
|
||||||
|
{
|
||||||
|
return "PhysicsFrameMonitor";
|
||||||
|
}
|
||||||
|
|
||||||
public double GetValue()
|
public double GetValue()
|
||||||
{
|
{
|
||||||
return m_scene.MonitorPhysicsSyncTime + m_scene.MonitorPhysicsUpdateTime;
|
return m_scene.MonitorPhysicsSyncTime + m_scene.MonitorPhysicsUpdateTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetName()
|
public string GetFriendlyName()
|
||||||
{
|
{
|
||||||
return "Total Physics Frame Time";
|
return "Total Physics Frame Time";
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,12 +40,17 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring.Monitors
|
||||||
|
|
||||||
#region Implementation of IMonitor
|
#region Implementation of IMonitor
|
||||||
|
|
||||||
|
public string GetName()
|
||||||
|
{
|
||||||
|
return "PhysicsUpdateFrameMonitor";
|
||||||
|
}
|
||||||
|
|
||||||
public double GetValue()
|
public double GetValue()
|
||||||
{
|
{
|
||||||
return m_scene.MonitorPhysicsUpdateTime;
|
return m_scene.MonitorPhysicsUpdateTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetName()
|
public string GetFriendlyName()
|
||||||
{
|
{
|
||||||
return "Physics Update Frame Time";
|
return "Physics Update Frame Time";
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,12 +32,17 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring.Monitors
|
||||||
{
|
{
|
||||||
#region Implementation of IMonitor
|
#region Implementation of IMonitor
|
||||||
|
|
||||||
|
public string GetName()
|
||||||
|
{
|
||||||
|
return "ThreadCountMonitor";
|
||||||
|
}
|
||||||
|
|
||||||
public double GetValue()
|
public double GetValue()
|
||||||
{
|
{
|
||||||
return System.Diagnostics.Process.GetCurrentProcess().Threads.Count;
|
return System.Diagnostics.Process.GetCurrentProcess().Threads.Count;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetName()
|
public string GetFriendlyName()
|
||||||
{
|
{
|
||||||
return "Total Threads";
|
return "Total Threads";
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,12 +40,17 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring.Monitors
|
||||||
|
|
||||||
#region Implementation of IMonitor
|
#region Implementation of IMonitor
|
||||||
|
|
||||||
|
public string GetName()
|
||||||
|
{
|
||||||
|
return "TotalFrameMonitor";
|
||||||
|
}
|
||||||
|
|
||||||
public double GetValue()
|
public double GetValue()
|
||||||
{
|
{
|
||||||
return m_scene.MonitorFrameTime;
|
return m_scene.MonitorFrameTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetName()
|
public string GetFriendlyName()
|
||||||
{
|
{
|
||||||
return "Total Frame Time";
|
return "Total Frame Time";
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,7 @@ using Nwc.XmlRpc;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
using OpenSim.Framework.Communications;
|
using OpenSim.Framework.Communications;
|
||||||
|
using OpenSim.Framework.Servers;
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
using OpenSim.Region.Framework.Interfaces;
|
||||||
using OpenSim.Region.Framework.Scenes;
|
using OpenSim.Region.Framework.Scenes;
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,7 @@ using OpenMetaverse;
|
||||||
using OpenMetaverse.StructuredData;
|
using OpenMetaverse.StructuredData;
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
using OpenSim.Framework.Capabilities;
|
using OpenSim.Framework.Capabilities;
|
||||||
|
using OpenSim.Framework.Servers;
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
using OpenSim.Region.Framework.Interfaces;
|
||||||
using OpenSim.Region.Framework.Scenes;
|
using OpenSim.Region.Framework.Scenes;
|
||||||
using Caps=OpenSim.Framework.Capabilities.Caps;
|
using Caps=OpenSim.Framework.Capabilities.Caps;
|
||||||
|
|
|
@ -396,9 +396,11 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
|
||||||
{
|
{
|
||||||
result = OpenJPEG.EncodeFromImage(joint, true);
|
result = OpenJPEG.EncodeFromImage(joint, true);
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
m_log.Error("[DYNAMICTEXTUREMODULE]: OpenJpeg Encode Failed. Empty byte data returned!");
|
m_log.ErrorFormat(
|
||||||
|
"[DYNAMICTEXTUREMODULE]: OpenJpeg Encode Failed. Exception {0}{1}",
|
||||||
|
e.Message, e.StackTrace);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -34,6 +34,7 @@ using log4net;
|
||||||
using Nini.Config;
|
using Nini.Config;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Framework.Servers;
|
||||||
using OpenSim.Framework.Servers.HttpServer;
|
using OpenSim.Framework.Servers.HttpServer;
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
using OpenSim.Region.Framework.Interfaces;
|
||||||
using OpenSim.Region.Framework.Scenes;
|
using OpenSim.Region.Framework.Scenes;
|
||||||
|
@ -135,6 +136,12 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
|
||||||
|
|
||||||
public void RegionLoaded(Scene scene)
|
public void RegionLoaded(Scene scene)
|
||||||
{
|
{
|
||||||
|
IScriptModule[] scriptModules = scene.RequestModuleInterfaces<IScriptModule>();
|
||||||
|
foreach (IScriptModule scriptModule in scriptModules)
|
||||||
|
{
|
||||||
|
scriptModule.OnScriptRemoved += ScriptRemoved;
|
||||||
|
scriptModule.OnObjectRemoved += ObjectRemoved;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveRegion(Scene scene)
|
public void RemoveRegion(Scene scene)
|
||||||
|
@ -165,7 +172,6 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
|
||||||
urlData.urlcode = urlcode;
|
urlData.urlcode = urlcode;
|
||||||
urlData.requests = new Dictionary<UUID, RequestData>();
|
urlData.requests = new Dictionary<UUID, RequestData>();
|
||||||
|
|
||||||
|
|
||||||
m_UrlMap[url] = urlData;
|
m_UrlMap[url] = urlData;
|
||||||
|
|
||||||
string uri = "/lslhttp/" + urlcode.ToString() + "/";
|
string uri = "/lslhttp/" + urlcode.ToString() + "/";
|
||||||
|
@ -280,6 +286,8 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
|
||||||
|
|
||||||
public void ScriptRemoved(UUID itemID)
|
public void ScriptRemoved(UUID itemID)
|
||||||
{
|
{
|
||||||
|
// m_log.DebugFormat("[URL MODULE]: Removing script {0}", itemID);
|
||||||
|
|
||||||
lock (m_UrlMap)
|
lock (m_UrlMap)
|
||||||
{
|
{
|
||||||
List<string> removeURLs = new List<string>();
|
List<string> removeURLs = new List<string>();
|
||||||
|
|
|
@ -338,10 +338,11 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
|
||||||
{
|
{
|
||||||
imageJ2000 = OpenJPEG.EncodeFromImage(bitmap, true);
|
imageJ2000 = OpenJPEG.EncodeFromImage(bitmap, true);
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
m_log.Error(
|
m_log.ErrorFormat(
|
||||||
"[VECTORRENDERMODULE]: OpenJpeg Encode Failed. Empty byte data returned!");
|
"[VECTORRENDERMODULE]: OpenJpeg Encode Failed. Exception {0}{1}",
|
||||||
|
e.Message, e.StackTrace);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_textureManager.ReturnData(id, imageJ2000);
|
m_textureManager.ReturnData(id, imageJ2000);
|
||||||
|
|
|
@ -31,6 +31,7 @@ using System.Collections.Generic;
|
||||||
using log4net;
|
using log4net;
|
||||||
using Nini.Config;
|
using Nini.Config;
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Framework.Servers;
|
||||||
using OpenSim.Region.Framework.Scenes;
|
using OpenSim.Region.Framework.Scenes;
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
using OpenSim.Region.Framework.Interfaces;
|
||||||
using OpenSim.Server.Base;
|
using OpenSim.Server.Base;
|
||||||
|
|
|
@ -31,6 +31,7 @@ using System.Collections.Generic;
|
||||||
using log4net;
|
using log4net;
|
||||||
using Nini.Config;
|
using Nini.Config;
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Framework.Servers;
|
||||||
using OpenSim.Region.Framework.Scenes;
|
using OpenSim.Region.Framework.Scenes;
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
using OpenSim.Region.Framework.Interfaces;
|
||||||
using OpenSim.Server.Base;
|
using OpenSim.Server.Base;
|
||||||
|
|
|
@ -31,6 +31,7 @@ using System.Collections.Generic;
|
||||||
using log4net;
|
using log4net;
|
||||||
using Nini.Config;
|
using Nini.Config;
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Framework.Servers;
|
||||||
using OpenSim.Region.Framework.Scenes;
|
using OpenSim.Region.Framework.Scenes;
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
using OpenSim.Region.Framework.Interfaces;
|
||||||
using OpenSim.Server.Base;
|
using OpenSim.Server.Base;
|
||||||
|
|
|
@ -31,6 +31,7 @@ using System.Collections.Generic;
|
||||||
using log4net;
|
using log4net;
|
||||||
using Nini.Config;
|
using Nini.Config;
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Framework.Servers;
|
||||||
using OpenSim.Region.Framework.Scenes;
|
using OpenSim.Region.Framework.Scenes;
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
using OpenSim.Region.Framework.Interfaces;
|
||||||
using OpenSim.Server.Base;
|
using OpenSim.Server.Base;
|
||||||
|
|
|
@ -31,6 +31,7 @@ using System.Collections.Generic;
|
||||||
using log4net;
|
using log4net;
|
||||||
using Nini.Config;
|
using Nini.Config;
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Framework.Servers;
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
using OpenSim.Region.Framework.Interfaces;
|
||||||
using OpenSim.Region.Framework.Scenes;
|
using OpenSim.Region.Framework.Scenes;
|
||||||
using OpenSim.Server.Base;
|
using OpenSim.Server.Base;
|
||||||
|
@ -59,9 +60,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Inventory
|
||||||
{
|
{
|
||||||
m_log.Info("[INVENTORY IN CONNECTOR]: Inventory Service In Connector enabled");
|
m_log.Info("[INVENTORY IN CONNECTOR]: Inventory Service In Connector enabled");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void PostInitialise()
|
public void PostInitialise()
|
||||||
|
|
|
@ -31,6 +31,7 @@ using System.Collections.Generic;
|
||||||
using log4net;
|
using log4net;
|
||||||
using Nini.Config;
|
using Nini.Config;
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Framework.Servers;
|
||||||
using OpenSim.Region.Framework.Scenes;
|
using OpenSim.Region.Framework.Scenes;
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
using OpenSim.Region.Framework.Interfaces;
|
||||||
using OpenSim.Server.Base;
|
using OpenSim.Server.Base;
|
||||||
|
|
|
@ -31,6 +31,7 @@ using System.Collections.Generic;
|
||||||
using log4net;
|
using log4net;
|
||||||
using Nini.Config;
|
using Nini.Config;
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Framework.Servers;
|
||||||
using OpenSim.Region.Framework.Scenes;
|
using OpenSim.Region.Framework.Scenes;
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
using OpenSim.Region.Framework.Interfaces;
|
||||||
using OpenSim.Server.Base;
|
using OpenSim.Server.Base;
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue