Compare commits
608 Commits
master
...
0.7.3-exte
Author | SHA1 | Date |
---|---|---|
Justin Clark-Casey (justincc) | 57530c8897 | |
Justin Clark-Casey (justincc) | d3776e8fba | |
Justin Clark-Casey (justincc) | a124984177 | |
Justin Clark-Casey (justincc) | 49307ab4d1 | |
Justin Clark-Casey (justincc) | 2271986396 | |
Justin Clark-Casey (justincc) | e54c11e0da | |
Justin Clark-Casey (justincc) | 688c91308c | |
Justin Clark-Casey (justincc) | cce6e6c841 | |
Justin Clark-Casey (justincc) | 8638766d79 | |
Justin Clark-Casey (justincc) | 7ae128abbe | |
Justin Clark-Casey (justincc) | 6391a2fad4 | |
Justin Clark-Casey (justincc) | 65d838da00 | |
Justin Clark-Casey (justincc) | c8ff599544 | |
Justin Clark-Casey (justincc) | 10a12b10d5 | |
Justin Clark-Casey (justincc) | baddfa08f3 | |
Justin Clark-Casey (justincc) | f6aa262585 | |
Justin Clark-Casey (justincc) | 2cc7a89012 | |
Justin Clark-Casey (justincc) | 108e77fe1a | |
Justin Clark-Casey (justincc) | 97b1b309ce | |
Justin Clark-Casey (justincc) | 53839ac779 | |
Justin Clark-Casey (justincc) | 4efcf38e17 | |
Justin Clark-Casey (justincc) | 639d147231 | |
Justin Clark-Casey (justincc) | a53f90cf7a | |
Justin Clark-Casey (justincc) | e0a3a8d47b | |
Justin Clark-Casey (justincc) | 7ce30cc49e | |
Justin Clark-Casey (justincc) | 6c36471f0c | |
Justin Clark-Casey (justincc) | a100723aaf | |
Justin Clark-Casey (justincc) | 69dc9b89a2 | |
Justin Clark-Casey (justincc) | c0d68d0aa4 | |
Justin Clark-Casey (justincc) | ce89bc38e1 | |
Justin Clark-Casey (justincc) | a21ee11fe8 | |
Justin Clark-Casey (justincc) | 06df03d98a | |
Justin Clark-Casey (justincc) | 2f4181623d | |
Justin Clark-Casey (justincc) | bbfb501b02 | |
Justin Clark-Casey (justincc) | a70baa95d1 | |
Justin Clark-Casey (justincc) | ed99017271 | |
Justin Clark-Casey (justincc) | 061c748b75 | |
Justin Clark-Casey (justincc) | c4645a899f | |
Justin Clark-Casey (justincc) | c223ac6929 | |
Melanie | 7e287227a4 | |
Justin Clark-Casey (justincc) | d4470c6147 | |
SignpostMarv | c14f983cca | |
Justin Clark-Casey (justincc) | 8a78d0f974 | |
Justin Clark-Casey (justincc) | f35e94f168 | |
Justin Clark-Casey (justincc) | 0e9e60d55a | |
Justin Clark-Casey (justincc) | f6a7325961 | |
Justin Clark-Casey (justincc) | ed63cafa65 | |
Justin Clark-Casey (justincc) | 092e94035b | |
Justin Clark-Casey (justincc) | fa3ebd85c9 | |
Justin Clark-Casey (justincc) | 08a9b01123 | |
Justin Clark-Casey (justincc) | 5772d23ff6 | |
Justin Clark-Casey (justincc) | 1d0ff7da2a | |
Justin Clark-Casey (justincc) | ec063b9088 | |
Justin Clark-Casey (justincc) | 12fbfb6125 | |
SignpostMarv | 272cd9886d | |
Justin Clark-Casey (justincc) | 627cfe6678 | |
Justin Clark-Casey (justincc) | aac4d9d682 | |
Justin Clark-Casey (justincc) | 25d39a19e1 | |
Justin Clark-Casey (justincc) | 55d383e4be | |
Justin Clark-Casey (justincc) | b180fdd0fd | |
Justin Clark-Casey (justincc) | cc6b2fdb9f | |
Justin Clark-Casey (justincc) | 9d6ea27df0 | |
Melanie | 2d66fcd4cd | |
Melanie | 91ae1908fe | |
Melanie | ed962bb3d3 | |
Justin Clark-Casey (justincc) | 9ea09d785c | |
Justin Clark-Casey (justincc) | e3db5fb603 | |
Justin Clark-Casey (justincc) | 58aa51218e | |
Justin Clark-Casey (justincc) | 0fff0e1fad | |
Justin Clark-Casey (justincc) | 4457ec667a | |
Justin Clark-Casey (justincc) | 7f2e6a55c4 | |
Justin Clark-Casey (justincc) | 92a01a7e70 | |
Justin Clark-Casey (justincc) | 4debc67b48 | |
Justin Clark-Casey (justincc) | c8f60acc30 | |
Justin Clark-Casey (justincc) | 272c3c1069 | |
Justin Clark-Casey (justincc) | 5aa9c21e7d | |
Justin Clark-Casey (justincc) | 454c3fc913 | |
Justin Clark-Casey (justincc) | 3cd7c59696 | |
Justin Clark-Casey (justincc) | 1f8ac33ecb | |
Justin Clark-Casey (justincc) | 47e2922a40 | |
Justin Clark-Casey (justincc) | 4deb25da87 | |
Justin Clark-Casey (justincc) | 587c8017ab | |
Justin Clark-Casey (justincc) | d5d801f218 | |
Justin Clark-Casey (justincc) | 2f865da5c7 | |
Justin Clark-Casey (justincc) | cf2f6843c6 | |
Justin Clark-Casey (justincc) | 97d084c9f5 | |
Justin Clark-Casey (justincc) | 14f72a9a43 | |
Justin Clark-Casey (justincc) | 89efccaa71 | |
Justin Clark-Casey (justincc) | 8f61da0759 | |
Justin Clark-Casey (justincc) | e88e87ff63 | |
Justin Clark-Casey (justincc) | 4f10d1aa0c | |
Justin Clark-Casey (justincc) | 1912215c40 | |
Justin Clark-Casey (justincc) | ffbca99b57 | |
Justin Clark-Casey (justincc) | f660a25fa7 | |
Justin Clark-Casey (justincc) | 523d03fb76 | |
Justin Clark-Casey (justincc) | 85985a8c3e | |
Justin Clark-Casey (justincc) | 013e002b00 | |
Justin Clark-Casey (justincc) | 5269d77cf9 | |
Justin Clark-Casey (justincc) | 8c8e6220fb | |
Justin Clark-Casey (justincc) | 150860c964 | |
Justin Clark-Casey (justincc) | 0cb1b0bb4a | |
Justin Clark-Casey (justincc) | 56d894ae24 | |
Justin Clark-Casey (justincc) | b34fd50155 | |
Justin Clark-Casey (justincc) | 74486e767d | |
Justin Clark-Casey (justincc) | 1b8814878d | |
Justin Clark-Casey (justincc) | 095375d63d | |
Justin Clark-Casey (justincc) | cb4e074a8c | |
Justin Clark-Casey (justincc) | 222f844d65 | |
Justin Clark-Casey (justincc) | bb2a9060f1 | |
Justin Clark-Casey (justincc) | e21dd88ed5 | |
Justin Clark-Casey (justincc) | 35457448ca | |
Justin Clark-Casey (justincc) | 596caf41db | |
Justin Clark-Casey (justincc) | c62b46a167 | |
Justin Clark-Casey (justincc) | 2b3098f011 | |
Justin Clark-Casey (justincc) | 74b4efd7f9 | |
Justin Clark-Casey (justincc) | 298c4c0eb5 | |
Justin Clark-Casey (justincc) | 068917bc29 | |
Justin Clark-Casey (justincc) | d8f1d2892c | |
Justin Clark-Casey (justincc) | ccf8e89193 | |
Justin Clark-Casey (justincc) | f17f58ac2a | |
Justin Clark-Casey (justincc) | 6bcb5baab6 | |
Justin Clark-Casey (justincc) | 0aaf935333 | |
Justin Clark-Casey (justincc) | b30806822e | |
Justin Clark-Casey (justincc) | a2c3dfc422 | |
Justin Clark-Casey (justincc) | 4050a6f8bb | |
Justin Clark-Casey (justincc) | 0d0d04c484 | |
SignpostMarv | 952b3448a6 | |
Justin Clark-Casey (justincc) | d53ef3b302 | |
Justin Clark-Casey (justincc) | 48e88397a0 | |
Justin Clark-Casey (justincc) | 976190fe96 | |
Justin Clark-Casey (justincc) | 1e025d6074 | |
Justin Clark-Casey (justincc) | fffd2fe10d | |
Justin Clark-Casey (justincc) | cf8adbe007 | |
Justin Clark-Casey (justincc) | 890f617e58 | |
Justin Clark-Casey (justincc) | 6ff0e58db7 | |
Justin Clark-Casey (justincc) | 795443cff1 | |
Justin Clark-Casey (justincc) | 8c7f511e55 | |
Justin Clark-Casey (justincc) | 0acac2f890 | |
Justin Clark-Casey (justincc) | 72554fc5b8 | |
Justin Clark-Casey (justincc) | aa1442b07e | |
Justin Clark-Casey (justincc) | e8a0ec1287 | |
Justin Clark-Casey (justincc) | 3436be2046 | |
Justin Clark-Casey (justincc) | 9a0bcb7750 | |
Justin Clark-Casey (justincc) | 218fe36f84 | |
Justin Clark-Casey (justincc) | 07298c8b4f | |
Justin Clark-Casey (justincc) | d9f40d1ebc | |
Justin Clark-Casey (justincc) | eddff428ed | |
Justin Clark-Casey (justincc) | 61aaa10460 | |
Justin Clark-Casey (justincc) | e1d6929e61 | |
Justin Clark-Casey (justincc) | 6b87873aa7 | |
Justin Clark-Casey (justincc) | f690acbfb6 | |
Justin Clark-Casey (justincc) | f49c850269 | |
Justin Clark-Casey (justincc) | 70f85af75b | |
Justin Clark-Casey (justincc) | 663b0cc681 | |
Justin Clark-Casey (justincc) | 733a8c9f89 | |
Justin Clark-Casey (justincc) | 25109c8e4d | |
Justin Clark-Casey (justincc) | 51724128bf | |
Justin Clark-Casey (justincc) | 461831a65e | |
Justin Clark-Casey (justincc) | c6fa09c3af | |
Justin Clark-Casey (justincc) | 9ccf56eaae | |
Justin Clark-Casey (justincc) | ea9b0794e0 | |
Justin Clark-Casey (justincc) | 96191241be | |
Justin Clark-Casey (justincc) | 779f0ede49 | |
Justin Clark-Casey (justincc) | e511106d8d | |
Justin Clark-Casey (justincc) | 37f22e2946 | |
Justin Clark-Casey (justincc) | b802906827 | |
Justin Clark-Casey (justincc) | c6fb5f0fe4 | |
Justin Clark-Casey (justincc) | 8909e70fc3 | |
Justin Clark-Casey (justincc) | 78fcee1f4b | |
Justin Clark-Casey (justincc) | 3106a0f25e | |
Justin Clark-Casey (justincc) | 19c2f08a8b | |
Justin Clark-Casey (justincc) | 005ca12a99 | |
Justin Clark-Casey (justincc) | 02fe1a676e | |
Justin Clark-Casey (justincc) | 03fc8cf155 | |
Justin Clark-Casey (justincc) | 8dedd91961 | |
Justin Clark-Casey (justincc) | 0ac040d9ca | |
Justin Clark-Casey (justincc) | c5e5308120 | |
Justin Clark-Casey (justincc) | 1cfaacb88b | |
Justin Clark-Casey (justincc) | 689cafec63 | |
Justin Clark-Casey (justincc) | d4cd9e050b | |
Justin Clark-Casey (justincc) | 472785a5e8 | |
Justin Clark-Casey (justincc) | da28fcd357 | |
Justin Clark-Casey (justincc) | 1999338773 | |
Justin Clark-Casey (justincc) | 95670d2086 | |
Justin Clark-Casey (justincc) | af2c48449c | |
Justin Clark-Casey (justincc) | ffc6110edf | |
Justin Clark-Casey (justincc) | 1edd1f93c1 | |
Justin Clark-Casey (justincc) | b6e42da21a | |
Justin Clark-Casey (justincc) | 2e0402433d | |
Justin Clark-Casey (justincc) | d19600e257 | |
Justin Clark-Casey (justincc) | a6d97e6353 | |
Justin Clark-Casey (justincc) | 8eb39eb3ac | |
Justin Clark-Casey (justincc) | 553ac6335d | |
Justin Clark-Casey (justincc) | 32a2515817 | |
Justin Clark-Casey (justincc) | a0482bccc7 | |
Justin Clark-Casey (justincc) | 3291e256ba | |
Justin Clark-Casey (justincc) | fb7573f713 | |
Justin Clark-Casey (justincc) | 4684207d6e | |
Justin Clark-Casey (justincc) | 499b778391 | |
Justin Clark-Casey (justincc) | 9779ceded5 | |
Justin Clark-Casey (justincc) | 512d0ac411 | |
Justin Clark-Casey (justincc) | 981c7d63a0 | |
Justin Clark-Casey (justincc) | 7bd1601a3f | |
Justin Clark-Casey (justincc) | 3aef006e78 | |
Justin Clark-Casey (justincc) | 9a6aa528db | |
Justin Clark-Casey (justincc) | 02a163848c | |
Justin Clark-Casey (justincc) | b9f122be07 | |
Justin Clark-Casey (justincc) | e64ca361df | |
Justin Clark-Casey (justincc) | 8a11c4e7d4 | |
Justin Clark-Casey (justincc) | 584a076bec | |
Justin Clark-Casey (justincc) | 88596d6097 | |
Justin Clark-Casey (justincc) | 84d97b3bc0 | |
Justin Clark-Casey (justincc) | 2b4e97eeaf | |
Justin Clark-Casey (justincc) | a544280ef2 | |
Justin Clark-Casey (justincc) | 3a0f9836f3 | |
Justin Clark-Casey (justincc) | 4bfac5688d | |
Justin Clark-Casey (justincc) | 0fb93042c6 | |
Melanie | a3586a7c4b | |
Justin Clark-Casey (justincc) | d4ff56710b | |
Justin Clark-Casey (justincc) | 6219c137e1 | |
Justin Clark-Casey (justincc) | da3877a77d | |
Justin Clark-Casey (justincc) | 10ed7e3bbc | |
Justin Clark-Casey (justincc) | f248f8bf31 | |
Justin Clark-Casey (justincc) | 6f2031001b | |
Justin Clark-Casey (justincc) | 1c5ad8e9ab | |
Justin Clark-Casey (justincc) | d8d8b8fc9b | |
Justin Clark-Casey (justincc) | 719efdaf1f | |
Justin Clark-Casey (justincc) | 6a8e3907ca | |
Justin Clark-Casey (justincc) | 5a1b8fc6f7 | |
Justin Clark-Casey (justincc) | 00ac962db7 | |
Justin Clark-Casey (justincc) | cb518ad68c | |
Justin Clark-Casey (justincc) | 4859bc8c49 | |
Justin Clark-Casey (justincc) | 196e014782 | |
Justin Clark-Casey (justincc) | c6ffaaa959 | |
Justin Clark-Casey (justincc) | c3104f4bd2 | |
Justin Clark-Casey (justincc) | d8c40ca462 | |
Justin Clark-Casey (justincc) | 48f47bb4c7 | |
Justin Clark-Casey (justincc) | 8db6edbe87 | |
Justin Clark-Casey (justincc) | a57b78b44b | |
Justin Clark-Casey (justincc) | 280d005d55 | |
Justin Clark-Casey (justincc) | 61e7d4a0e2 | |
Justin Clark-Casey (justincc) | 3e75083d2d | |
Justin Clark-Casey (justincc) | 3d400dd677 | |
Justin Clark-Casey (justincc) | 1fbb0f97bf | |
Justin Clark-Casey (justincc) | 4968191c1e | |
Justin Clark-Casey (justincc) | 8889309324 | |
Justin Clark-Casey (justincc) | 27a7ba3e6a | |
Justin Clark-Casey (justincc) | 2d16d14ef1 | |
Justin Clark-Casey (justincc) | f2f8dcd65c | |
Justin Clark-Casey (justincc) | 332f8b6623 | |
Justin Clark-Casey (justincc) | 4eda679e12 | |
Justin Clark-Casey (justincc) | 498154af80 | |
Justin Clark-Casey (justincc) | ba0ebe6d75 | |
Justin Clark-Casey (justincc) | 28f93512bc | |
Justin Clark-Casey (justincc) | 78c2ef2346 | |
Justin Clark-Casey (justincc) | d30d68657e | |
Justin Clark-Casey (justincc) | 3a27f656b3 | |
Justin Clark-Casey (justincc) | cc27a6cb84 | |
Justin Clark-Casey (justincc) | ed21576ce0 | |
Talun | 9d9e042b4c | |
Justin Clark-Casey (justincc) | 4fb8d5cfba | |
Justin Clark-Casey (justincc) | 896c4b6248 | |
Justin Clark-Casey (justincc) | f6730da13a | |
Justin Clark-Casey (justincc) | 41d98916df | |
Justin Clark-Casey (justincc) | 771539a4e0 | |
Justin Clark-Casey (justincc) | 27c62bba99 | |
Justin Clark-Casey (justincc) | 93e053a122 | |
Justin Clark-Casey (justincc) | eb022f4cc1 | |
Justin Clark-Casey (justincc) | 83542034dd | |
Justin Clark-Casey (justincc) | 627382f702 | |
Justin Clark-Casey (justincc) | 2eb563b3bb | |
Justin Clark-Casey (justincc) | 54a23f14d5 | |
Justin Clark-Casey (justincc) | e8059b74f8 | |
Justin Clark-Casey (justincc) | 075909520a | |
Justin Clark-Casey (justincc) | 808bf12cd5 | |
Justin Clark-Casey (justincc) | 0f39f41317 | |
Justin Clark-Casey (justincc) | f23b7ae3e9 | |
Justin Clark-Casey (justincc) | 5e4b09fc22 | |
Justin Clark-Casey (justincc) | 25ab7841b7 | |
Justin Clark-Casey (justincc) | 0c0e575379 | |
Justin Clark-Casey (justincc) | 68946bffae | |
Justin Clark-Casey (justincc) | 2fc461d9ab | |
Justin Clark-Casey (justincc) | 59a48d9ebb | |
Justin Clark-Casey (justincc) | 533d1ea20c | |
Justin Clark-Casey (justincc) | dca1ca1d07 | |
Justin Clark-Casey (justincc) | 20a3907e86 | |
Justin Clark-Casey (justincc) | 7358e5748d | |
Blake.Bourque | a1b64db942 | |
Justin Clark-Casey (justincc) | 4d44f2d248 | |
Justin Clark-Casey (justincc) | 67abbcf269 | |
Justin Clark-Casey (justincc) | 6b819a9032 | |
Talun | 2021a8aedb | |
Justin Clark-Casey (justincc) | 58dc175ae3 | |
Justin Clark-Casey (justincc) | 4ad6763956 | |
Justin Clark-Casey (justincc) | 702826b850 | |
Justin Clark-Casey (justincc) | 8d30a1f74b | |
Justin Clark-Casey (justincc) | 1a988ba835 | |
Justin Clark-Casey (justincc) | c422f852a6 | |
Justin Clark-Casey (justincc) | bcacdb3352 | |
Justin Clark-Casey (justincc) | cd61567de8 | |
Justin Clark-Casey (justincc) | 5c48c3c57a | |
Justin Clark-Casey (justincc) | 7692ccc0cc | |
Justin Clark-Casey (justincc) | 17cc7e85e2 | |
Justin Clark-Casey (justincc) | 96b3e1d0fa | |
Justin Clark-Casey (justincc) | dc3cfcbe69 | |
Justin Clark-Casey (justincc) | 1ca1f80eac | |
Justin Clark-Casey (justincc) | afe2b437bc | |
Justin Clark-Casey (justincc) | dff71c1aa9 | |
Justin Clark-Casey (justincc) | 7f9a025e30 | |
Justin Clark-Casey (justincc) | a0ac284a11 | |
Justin Clark-Casey (justincc) | 5341036261 | |
Justin Clark-Casey (justincc) | 46a6cab307 | |
Justin Clark-Casey (justincc) | edb17d1aac | |
Justin Clark-Casey (justincc) | dd05e96066 | |
Justin Clark-Casey (justincc) | ed0878ca23 | |
Justin Clark-Casey (justincc) | 54c222be26 | |
Justin Clark-Casey (justincc) | 80d139297a | |
Justin Clark-Casey (justincc) | 8e6459f616 | |
Justin Clark-Casey (justincc) | ba909cb692 | |
Justin Clark-Casey (justincc) | 96b964f7fa | |
Justin Clark-Casey (justincc) | 7bbab2f1d5 | |
Justin Clark-Casey (justincc) | e5f3af4abe | |
Justin Clark-Casey (justincc) | 452538c6b0 | |
Justin Clark-Casey (justincc) | 5c828724f3 | |
Justin Clark-Casey (justincc) | 6538dd24bb | |
Justin Clark-Casey (justincc) | 996abe1ea5 | |
Justin Clark-Casey (justincc) | f421e0c3d1 | |
Justin Clark-Casey (justincc) | e4eaca5f9b | |
Justin Clark-Casey (justincc) | ef5925fa18 | |
Justin Clark-Casey (justincc) | bae48a9394 | |
Justin Clark-Casey (justincc) | c813ed44d8 | |
Justin Clark-Casey (justincc) | 885bec68bd | |
Justin Clark-Casey (justincc) | b553a05db3 | |
Justin Clark-Casey (justincc) | 5473c4f8cc | |
Justin Clark-Casey (justincc) | 0d73f81fb5 | |
Justin Clark-Casey (justincc) | 66c204b983 | |
Justin Clark-Casey (justincc) | afb0600621 | |
Justin Clark-Casey (justincc) | a13f2c6985 | |
Justin Clark-Casey (justincc) | 17c7ef06ba | |
Justin Clark-Casey (justincc) | 4933ce49b6 | |
Justin Clark-Casey (justincc) | 5cec1fa50a | |
Justin Clark-Casey (justincc) | debd83b06a | |
Justin Clark-Casey (justincc) | f01618ad1a | |
Justin Clark-Casey (justincc) | cfc1dba99b | |
Justin Clark-Casey (justincc) | 529a3f2400 | |
Justin Clark-Casey (justincc) | 7c1abc5225 | |
Justin Clark-Casey (justincc) | ca22b5e2f0 | |
Justin Clark-Casey (justincc) | 9ec74f2098 | |
Justin Clark-Casey (justincc) | cb4ae39cb9 | |
Justin Clark-Casey (justincc) | 802488814f | |
Justin Clark-Casey (justincc) | 53aa48b42c | |
Justin Clark-Casey (justincc) | b33801f854 | |
Talun | fc88ce0615 | |
Justin Clark-Casey (justincc) | 28daec7f4e | |
Justin Clark-Casey (justincc) | f25efa291d | |
Justin Clark-Casey (justincc) | 5ed0559cf2 | |
Justin Clark-Casey (justincc) | 8c1e549c12 | |
Justin Clark-Casey (justincc) | 796334c5ff | |
Justin Clark-Casey (justincc) | 2e1c2e1261 | |
Talun | a896aac4bd | |
Justin Clark-Casey (justincc) | 80030d3f15 | |
Oren Hurvitz | 4eba4a37ed | |
Justin Clark-Casey (justincc) | dd0858e204 | |
Justin Clark-Casey (justincc) | 25fa6ee699 | |
Justin Clark-Casey (justincc) | 84dfffe0aa | |
Justin Clark-Casey (justincc) | aba803c447 | |
Justin Clark-Casey (justincc) | 79aae63aff | |
Justin Clark-Casey (justincc) | 59e93b8ee3 | |
Justin Clark-Casey (justincc) | e0e63f312f | |
Snoopy Pfeffer | d453372f4e | |
Justin Clark-Casey (justincc) | 0f5a77c5bd | |
Justin Clark-Casey (justincc) | 0c96d7ea5c | |
Justin Clark-Casey (justincc) | 4b947cd6d3 | |
Justin Clark-Casey (justincc) | ca586ca809 | |
Justin Clark-Casey (justincc) | 880358f46b | |
Justin Clark-Casey (justincc) | 3393babb7d | |
Justin Clark-Casey (justincc) | c3ae90c067 | |
Justin Clark-Casey (justincc) | 25983f20a0 | |
Justin Clark-Casey (justincc) | 1441758bc6 | |
Justin Clark-Casey (justincc) | c7bbeb4490 | |
Diva Canto | 6145f90423 | |
Diva Canto | 2e397d1514 | |
Diva Canto | a5d0a29dd9 | |
Melanie | de843fd0a8 | |
Melanie | ced4eeddcf | |
Melanie | 093910e90e | |
Melanie | 37685ec1b4 | |
Melanie | ccd7d35b3f | |
Melanie | de7e0d7e52 | |
Diva Canto | 89ee03a24d | |
Melanie | 79d1d3ca55 | |
Justin Clark-Casey (justincc) | 675c208c7e | |
Justin Clark-Casey (justincc) | b3307850ab | |
Oren Hurvitz | eaa840dbd9 | |
Justin Clark-Casey (justincc) | f64089fa6c | |
Justin Clark-Casey (justincc) | 5157d2023d | |
Justin Clark-Casey (justincc) | 2cd927bb14 | |
Justin Clark-Casey (justincc) | 2889961622 | |
Justin Clark-Casey (justincc) | 232f59749e | |
Justin Clark-Casey (justincc) | d368a10cc7 | |
Justin Clark-Casey (justincc) | 139b848774 | |
Justin Clark-Casey (justincc) | 74a5226af5 | |
Justin Clark-Casey (justincc) | c7ddc7a633 | |
Justin Clark-Casey (justincc) | 265707d21c | |
Justin Clark-Casey (justincc) | eb39d1c4d4 | |
Justin Clark-Casey (justincc) | 1197d48fc7 | |
Justin Clark-Casey (justincc) | 23e1a55ed5 | |
Justin Clark-Casey (justincc) | ba2a539603 | |
Justin Clark-Casey (justincc) | 8a8093d8dd | |
Justin Clark-Casey (justincc) | 3fb0103452 | |
Justin Clark-Casey (justincc) | aeefdaedc7 | |
Justin Clark-Casey (justincc) | 756d1f917f | |
Justin Clark-Casey (justincc) | 6fa3dffad2 | |
Justin Clark-Casey (justincc) | 123e781cb3 | |
Justin Clark-Casey (justincc) | ed9bf5b0c6 | |
Justin Clark-Casey (justincc) | dd4e39ca1d | |
Justin Clark-Casey (justincc) | 5a551b074b | |
Justin Clark-Casey (justincc) | c1a9355865 | |
Diva Canto | 3ea6c25fb6 | |
Justin Clark-Casey (justincc) | 2d3135448c | |
Justin Clark-Casey (justincc) | 36a99af37c | |
Justin Clark-Casey (justincc) | 2aefd15913 | |
Justin Clark-Casey (justincc) | 6bc55b1086 | |
Justin Clark-Casey (justincc) | 7058ce2c70 | |
Justin Clark-Casey (justincc) | 8e111e9018 | |
Justin Clark-Casey (justincc) | d8bd7ca436 | |
Justin Clark-Casey (justincc) | 392f73a000 | |
Justin Clark-Casey (justincc) | 67efbaf33b | |
Justin Clark-Casey (justincc) | 0d06740148 | |
Diva Canto | eda6947a22 | |
Justin Clark-Casey (justincc) | f331173145 | |
Justin Clark-Casey (justincc) | a666cd9e1f | |
Justin Clark-Casey (justincc) | 2657aa6987 | |
Justin Clark-Casey (justincc) | 6610cd2332 | |
Justin Clark-Casey (justincc) | 0c8b44d514 | |
Justin Clark-Casey (justincc) | ec46ff4445 | |
Melanie | db891880e6 | |
Melanie | 9c433e8c50 | |
Justin Clark-Casey (justincc) | 5141863ae3 | |
Justin Clark-Casey (justincc) | d23550dea5 | |
Justin Clark-Casey (justincc) | c3b12510ae | |
Justin Clark-Casey (justincc) | b2685e3671 | |
Justin Clark-Casey (justincc) | 601d2ddbf3 | |
Justin Clark-Casey (justincc) | a5e8fe70af | |
Justin Clark-Casey (justincc) | 9b3a96aa81 | |
Justin Clark-Casey (justincc) | d674e815bd | |
Justin Clark-Casey (justincc) | c2e696d686 | |
Justin Clark-Casey (justincc) | 411dbb8df4 | |
Justin Clark-Casey (justincc) | b22dfbbf15 | |
Justin Clark-Casey (justincc) | 4c39a3fdbf | |
Justin Clark-Casey (justincc) | f3eb366f24 | |
Justin Clark-Casey (justincc) | a20d1b8f6b | |
Justin Clark-Casey (justincc) | 0a51289332 | |
Justin Clark-Casey (justincc) | 97ebfb00b4 | |
Justin Clark-Casey (justincc) | c7d664f9d0 | |
Justin Clark-Casey (justincc) | c2fbaaa95d | |
Justin Clark-Casey (justincc) | 84d4b390f1 | |
Justin Clark-Casey (justincc) | 54e59099b7 | |
Justin Clark-Casey (justincc) | d9585ba37e | |
Justin Clark-Casey (justincc) | 45c617b5c3 | |
Justin Clark-Casey (justincc) | 4b0c78c64f | |
Justin Clark-Casey (justincc) | dd36e23a62 | |
Justin Clark-Casey (justincc) | e2dade05d9 | |
Justin Clark-Casey (justincc) | fbd61106cb | |
Justin Clark-Casey (justincc) | 67e66a2d34 | |
Justin Clark-Casey (justincc) | 59911963ca | |
Justin Clark-Casey (justincc) | dc2a4a6ccd | |
Justin Clark-Casey (justincc) | 81fb0b4f07 | |
Melanie | a06c8fb7b2 | |
Melanie | 05e70f76a9 | |
Melanie | b9f4836d3e | |
Melanie | ef77dc932b | |
Justin Clark-Casey (justincc) | bd5b1d4d48 | |
Melanie | 5c2ffa260c | |
Justin Clark-Casey (justincc) | 23d04fa25c | |
Justin Clark-Casey (justincc) | 67dbce4512 | |
Justin Clark-Casey (justincc) | 46170fd0d8 | |
Justin Clark-Casey (justincc) | f85a453dc8 | |
nebadon | bcfe48e05b | |
Justin Clark-Casey (justincc) | 722ca250ea | |
Justin Clark-Casey (justincc) | f4df128e52 | |
Justin Clark-Casey (justincc) | 8cc5322b39 | |
Justin Clark-Casey (justincc) | 1480845597 | |
Justin Clark-Casey (justincc) | c877e73463 | |
Justin Clark-Casey (justincc) | 3ce5e8eb6c | |
Justin Clark-Casey (justincc) | e6b12e1f9d | |
Justin Clark-Casey (justincc) | bfbbd4ccba | |
Justin Clark-Casey (justincc) | fec7016665 | |
Justin Clark-Casey (justincc) | 47fe6170b2 | |
Justin Clark-Casey (justincc) | 24b5fb8523 | |
Justin Clark-Casey (justincc) | e8cd9688ce | |
Justin Clark-Casey (justincc) | fa952f6d35 | |
Justin Clark-Casey (justincc) | df55fd69af | |
Justin Clark-Casey (justincc) | 019fc4c1f2 | |
Justin Clark-Casey (justincc) | 22ea441feb | |
Justin Clark-Casey (justincc) | 9f5b33e52e | |
Justin Clark-Casey (justincc) | 92837c4f89 | |
Justin Clark-Casey (justincc) | 68ce06f40f | |
Justin Clark-Casey (justincc) | 279b31c75b | |
Justin Clark-Casey (justincc) | 3117b3cd88 | |
Justin Clark-Casey (justincc) | 9b547f76e7 | |
Justin Clark-Casey (justincc) | 3d6675784a | |
Justin Clark-Casey (justincc) | 26f50eadd1 | |
Justin Clark-Casey (justincc) | 6e8496ffc5 | |
Justin Clark-Casey (justincc) | 88d6c4ec0e | |
Justin Clark-Casey (justincc) | 135eeb45d6 | |
Justin Clark-Casey (justincc) | 54ee59c0bb | |
Justin Clark-Casey (justincc) | 4a5c61a33d | |
Diva Canto | 179c0f5f56 | |
Justin Clark-Casey (justincc) | 4dbf937707 | |
Justin Clark-Casey (justincc) | 9edb57e5e9 | |
Justin Clark-Casey (justincc) | 4d15ad63bf | |
Justin Clark-Casey (justincc) | 4021709371 | |
Justin Clark-Casey (justincc) | 3c13f5c3aa | |
Justin Clark-Casey (justincc) | 381517b451 | |
Justin Clark-Casey (justincc) | 6ecf36d49c | |
Justin Clark-Casey (justincc) | 64eb4b8408 | |
Diva Canto | 318da3fdcd | |
Melanie | 50c99fcda6 | |
Melanie | 321de1f263 | |
Diva Canto | fa30ace67d | |
Justin Clark-Casey (justincc) | 92baa79253 | |
Justin Clark-Casey (justincc) | e861b45313 | |
Justin Clark-Casey (justincc) | cf91ac68b6 | |
Justin Clark-Casey (justincc) | d4aba13526 | |
Justin Clark-Casey (justincc) | d36c7c3782 | |
Justin Clark-Casey (justincc) | 4385fcdeae | |
Justin Clark-Casey (justincc) | 04eb170624 | |
Justin Clark-Casey (justincc) | 4803686078 | |
Justin Clark-Casey (justincc) | 20b0fda3bb | |
Justin Clark-Casey (justincc) | 4e5f823595 | |
Justin Clark-Casey (justincc) | a74408d1d2 | |
Justin Clark-Casey (justincc) | 8206537efd | |
Justin Clark-Casey (justincc) | a9a77bb3ab | |
Justin Clark-Casey (justincc) | 6390de689d | |
Justin Clark-Casey (justincc) | 41ce19836b | |
Melanie | 883a4f6fff | |
Justin Clark-Casey (justincc) | 5f1da80fc1 | |
Justin Clark-Casey (justincc) | 64217d67f6 | |
Justin Clark-Casey (justincc) | b01c79354c | |
Justin Clark-Casey (justincc) | 9ecbcb787c | |
Justin Clark-Casey (justincc) | e17e376b04 | |
Justin Clark-Casey (justincc) | 1b4ea4f178 | |
Melanie | 1de29fb362 | |
Justin Clark-Casey (justincc) | 7e4bd492fd | |
Justin Clark-Casey (justincc) | 588d56503d | |
Justin Clark-Casey (justincc) | e9602656f8 | |
Justin Clark-Casey (justincc) | 0116d418f0 | |
Justin Clark-Casey (justincc) | 9992974c66 | |
Justin Clark-Casey (justincc) | ba27d8a389 | |
Justin Clark-Casey (justincc) | f96e985763 | |
Diva Canto | 5b9eaae50d | |
Diva Canto | 74a13f7e3b | |
Diva Canto | 3e88fc8aad | |
Diva Canto | 881740d702 | |
Diva Canto | 9a643a1bb9 | |
Diva Canto | a5488650ff | |
Diva Canto | a275127a65 | |
Diva Canto | 02db31db6a | |
Diva Canto | 8bd813e6fc | |
Diva Canto | 09ff121654 | |
Diva Canto | 0434758a0d | |
Diva Canto | 8bb0a71083 | |
Diva Canto | d7651a389e | |
Justin Clark-Casey (justincc) | 824318a0c1 | |
Justin Clark-Casey (justincc) | 5e9ed22e84 | |
Chris Hart | a6c611e7c9 | |
Diva Canto | 72b325f8b5 | |
Justin Clark-Casey (justincc) | 54d0514b13 | |
Justin Clark-Casey (justincc) | 58b1c3cec0 | |
Justin Clark-Casey (justincc) | 71641523a3 | |
Justin Clark-Casey (justincc) | 94c5e25c3b | |
Justin Clark-Casey (justincc) | 20bad0aa6c | |
Justin Clark-Casey (justincc) | e7f23a6218 | |
Justin Clark-Casey (justincc) | 25c29db8b6 | |
Justin Clark-Casey (justincc) | 1750fba9ce | |
PixelTomsen | b18e410586 | |
Justin Clark-Casey (justincc) | 38d5e1fab3 | |
Justin Clark-Casey (justincc) | 4180c32eb1 | |
Justin Clark-Casey (justincc) | 5115229fdf | |
Justin Clark-Casey (justincc) | e8f2d814e7 | |
Diva Canto | 1fda8c5a86 | |
Justin Clark-Casey (justincc) | 6b77b55d40 | |
Justin Clark-Casey (justincc) | 82cdb08c1f | |
Justin Clark-Casey (justincc) | dafcb3bcd7 | |
Diva Canto | 3259b1d1e0 | |
Diva Canto | 512910a51f | |
Diva Canto | fdda57cf10 | |
Diva Canto | ec8e34950d | |
Diva Canto | 93964ef3a4 | |
Diva Canto | 5c8af6a136 | |
PixelTomsen | 4d0c8aca05 | |
PixelTomsen | 8fc16ece96 | |
BlueWall | fcbb375e8f | |
BlueWall | 49c65279fa | |
BlueWall | 86e8a56fe1 | |
BlueWall | b199330682 | |
BlueWall | 7a7ebaebd1 | |
BlueWall | 164ae0b24b | |
Diva Canto | 7156545fca | |
Justin Clark-Casey (justincc) | 73a5abf4d9 | |
Justin Clark-Casey (justincc) | 630c8dc828 | |
Justin Clark-Casey (justincc) | 6de89246c2 | |
Justin Clark-Casey (justincc) | 96973a5778 | |
Justin Clark-Casey (justincc) | 96843f2b17 | |
Justin Clark-Casey (justincc) | 8a36f54cf4 | |
Justin Clark-Casey (justincc) | 1a14e660d2 | |
Justin Clark-Casey (justincc) | 2502aae5db |
|
@ -41,6 +41,8 @@ bin/Physics*
|
||||||
bin/Terrain*
|
bin/Terrain*
|
||||||
bin/Regions/*
|
bin/Regions/*
|
||||||
bin/UserAssets
|
bin/UserAssets
|
||||||
|
bin/assetcache
|
||||||
|
bin/maptiles
|
||||||
bin/estate_settings.xml
|
bin/estate_settings.xml
|
||||||
bin/config-include/CenomeCache.ini
|
bin/config-include/CenomeCache.ini
|
||||||
bin/config-include/FlotsamCache.ini
|
bin/config-include/FlotsamCache.ini
|
||||||
|
|
|
@ -8,6 +8,24 @@
|
||||||
<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"/>
|
<copy file="bin/config-include/FlotsamCache.ini.example" tofile="bin/config-include/FlotsamCache.ini"/>
|
||||||
|
<!-- delete files generated by runprebuild.sh which had to be run in order to generate the build file for this target-->
|
||||||
|
<delete>
|
||||||
|
<fileset basedir="OpenSim">
|
||||||
|
<include name="**/*.build"/>
|
||||||
|
<include name="**/*.csproj*"/>
|
||||||
|
<include name="**/*.dll.build"/>
|
||||||
|
<include name="**/*.pidb"/>
|
||||||
|
<exclude name="Tools/OpenSim.32BitLaunch/**"/>
|
||||||
|
<exclude name="Tools/Robust.32BitLaunch/**"/>
|
||||||
|
<exclude name="Tools/LaunchSLClient/**"/>
|
||||||
|
</fileset>
|
||||||
|
</delete>
|
||||||
|
<delete>
|
||||||
|
<fileset>
|
||||||
|
<include name="OpenSim.build"/>
|
||||||
|
<include name="OpenSim.sln"/>
|
||||||
|
</fileset>
|
||||||
|
</delete>
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
<property name="distbindir" value="distbin" />
|
<property name="distbindir" value="distbin" />
|
||||||
|
@ -117,14 +135,25 @@
|
||||||
<delete dir="%temp%"/>
|
<delete dir="%temp%"/>
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
<target name="torture" depends="build, find-nunit">
|
<target name="test-stress" depends="build, find-nunit">
|
||||||
<setenv name="MONO_THREADS_PER_CPU" value="100" />
|
<setenv name="MONO_THREADS_PER_CPU" value="100" />
|
||||||
|
|
||||||
<exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.tests.torture">
|
<exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.tests.stress">
|
||||||
<arg value="./bin/OpenSim.Tests.Torture.dll" />
|
<arg value="./bin/OpenSim.Tests.Stress.dll" />
|
||||||
</exec>
|
</exec>
|
||||||
|
|
||||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.tests.torture)==0}" />
|
<fail message="Failures reported in stress tests." unless="${int::parse(testresult.opensim.tests.stress)==0}" />
|
||||||
|
<delete dir="%temp%"/>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="test-perf" depends="build, find-nunit">
|
||||||
|
<setenv name="MONO_THREADS_PER_CPU" value="100" />
|
||||||
|
|
||||||
|
<exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.tests.performance">
|
||||||
|
<arg value="./bin/OpenSim.Tests.Performance.dll" />
|
||||||
|
</exec>
|
||||||
|
|
||||||
|
<fail message="Failures reported in performance tests." unless="${int::parse(testresult.opensim.tests.performance)==0}" />
|
||||||
<delete dir="%temp%"/>
|
<delete dir="%temp%"/>
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
The following people have contributed to OpenSim (Thank you
|
<<<>>>>The following people have contributed to OpenSim (Thank you
|
||||||
for your effort!)
|
for your effort!)
|
||||||
|
|
||||||
= Current OpenSim Developers (in very rough order of appearance) =
|
= Current OpenSim Developers (in very rough order of appearance) =
|
||||||
|
@ -139,6 +139,9 @@ what it is today.
|
||||||
* SignpostMarv
|
* SignpostMarv
|
||||||
* SpotOn3D
|
* SpotOn3D
|
||||||
* Strawberry Fride
|
* Strawberry Fride
|
||||||
|
* Talun
|
||||||
|
* TechplexEngineer (Blake Bourque)
|
||||||
|
* TBG Renfold
|
||||||
* tglion
|
* tglion
|
||||||
* tlaukkan/Tommil (Tommi S. E. Laukkanen, Bubble Cloud)
|
* tlaukkan/Tommil (Tommi S. E. Laukkanen, Bubble Cloud)
|
||||||
* tyre
|
* tyre
|
||||||
|
|
|
@ -539,7 +539,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
|
||||||
/// path has not already been registered, the method is added to the active
|
/// path has not already been registered, the method is added to the active
|
||||||
/// handler table.
|
/// handler table.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
||||||
public void AddStreamHandler(string httpMethod, string path, RestMethod method)
|
public void AddStreamHandler(string httpMethod, string path, RestMethod method)
|
||||||
{
|
{
|
||||||
if (!IsEnabled)
|
if (!IsEnabled)
|
||||||
|
|
|
@ -101,18 +101,8 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
llsdItem.item_id = invItem.ID;
|
llsdItem.item_id = invItem.ID;
|
||||||
llsdItem.name = invItem.Name;
|
llsdItem.name = invItem.Name;
|
||||||
llsdItem.parent_id = invItem.Folder;
|
llsdItem.parent_id = invItem.Folder;
|
||||||
|
llsdItem.type = invItem.AssetType;
|
||||||
try
|
llsdItem.inv_type = invItem.InvType;
|
||||||
{
|
|
||||||
llsdItem.type = Utils.AssetTypeToString((AssetType)invItem.AssetType);
|
|
||||||
llsdItem.inv_type = Utils.InventoryTypeToString((InventoryType)invItem.InvType);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
m_log.ErrorFormat(
|
|
||||||
"[WEB FETCH INV DESC HANDLER]: Problem setting asset {0} inventory {1} types while converting inventory item {2}: {3}",
|
|
||||||
invItem.AssetType, invItem.InvType, invItem.Name, e.Message);
|
|
||||||
}
|
|
||||||
|
|
||||||
llsdItem.permissions = new LLSDPermissions();
|
llsdItem.permissions = new LLSDPermissions();
|
||||||
llsdItem.permissions.creator_id = invItem.CreatorIdAsUuid;
|
llsdItem.permissions.creator_id = invItem.CreatorIdAsUuid;
|
||||||
|
@ -126,21 +116,7 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
llsdItem.permissions.owner_mask = (int)invItem.CurrentPermissions;
|
llsdItem.permissions.owner_mask = (int)invItem.CurrentPermissions;
|
||||||
llsdItem.sale_info = new LLSDSaleInfo();
|
llsdItem.sale_info = new LLSDSaleInfo();
|
||||||
llsdItem.sale_info.sale_price = invItem.SalePrice;
|
llsdItem.sale_info.sale_price = invItem.SalePrice;
|
||||||
switch (invItem.SaleType)
|
llsdItem.sale_info.sale_type = invItem.SaleType;
|
||||||
{
|
|
||||||
default:
|
|
||||||
llsdItem.sale_info.sale_type = "not";
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
llsdItem.sale_info.sale_type = "original";
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
llsdItem.sale_info.sale_type = "copy";
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
llsdItem.sale_info.sale_type = "contents";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return llsdItem;
|
return llsdItem;
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,7 +63,8 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
|
|
||||||
FetchInventory2Handler fiHandler = new FetchInventory2Handler(m_InventoryService);
|
FetchInventory2Handler fiHandler = new FetchInventory2Handler(m_InventoryService);
|
||||||
IRequestHandler reqHandler
|
IRequestHandler reqHandler
|
||||||
= new RestStreamHandler("POST", "/CAPS/FetchInventory/", fiHandler.FetchInventoryRequest);
|
= new RestStreamHandler(
|
||||||
|
"POST", "/CAPS/FetchInventory/", fiHandler.FetchInventoryRequest, "FetchInventory", null);
|
||||||
server.AddStreamHandler(reqHandler);
|
server.AddStreamHandler(reqHandler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,13 +66,14 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
throw new Exception(String.Format("Failed to load AssetService from {0}; config is {1}", assetService, m_ConfigName));
|
throw new Exception(String.Format("Failed to load AssetService from {0}; config is {1}", assetService, m_ConfigName));
|
||||||
|
|
||||||
GetMeshHandler gmeshHandler = new GetMeshHandler(m_AssetService);
|
GetMeshHandler gmeshHandler = new GetMeshHandler(m_AssetService);
|
||||||
IRequestHandler reqHandler = new RestHTTPHandler("GET", "/CAPS/" + UUID.Random(),
|
IRequestHandler reqHandler
|
||||||
delegate(Hashtable m_dhttpMethod)
|
= new RestHTTPHandler(
|
||||||
{
|
"GET",
|
||||||
return gmeshHandler.ProcessGetMesh(m_dhttpMethod, UUID.Zero, null);
|
"/CAPS/" + UUID.Random(),
|
||||||
});
|
httpMethod => gmeshHandler.ProcessGetMesh(httpMethod, UUID.Zero, null),
|
||||||
|
"GetMesh",
|
||||||
|
null);
|
||||||
server.AddStreamHandler(reqHandler);
|
server.AddStreamHandler(reqHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -58,8 +58,8 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
// TODO: Change this to a config option
|
// TODO: Change this to a config option
|
||||||
const string REDIRECT_URL = null;
|
const string REDIRECT_URL = null;
|
||||||
|
|
||||||
public GetTextureHandler(string path, IAssetService assService) :
|
public GetTextureHandler(string path, IAssetService assService, string name, string description)
|
||||||
base("GET", path)
|
: base("GET", path, name, description)
|
||||||
{
|
{
|
||||||
m_assetService = assService;
|
m_assetService = assService;
|
||||||
}
|
}
|
||||||
|
@ -77,7 +77,6 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
{
|
{
|
||||||
m_log.Error("[GETTEXTURE]: Cannot fetch texture " + textureStr + " without an asset service");
|
m_log.Error("[GETTEXTURE]: Cannot fetch texture " + textureStr + " without an asset service");
|
||||||
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
|
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UUID textureID;
|
UUID textureID;
|
||||||
|
@ -115,7 +114,6 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
// "[GETTEXTURE]: For texture {0} sending back response {1}, data length {2}",
|
// "[GETTEXTURE]: For texture {0} sending back response {1}, data length {2}",
|
||||||
// textureID, httpResponse.StatusCode, httpResponse.ContentLength);
|
// textureID, httpResponse.StatusCode, httpResponse.ContentLength);
|
||||||
|
|
||||||
httpResponse.Send();
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -221,12 +219,30 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
int start, end;
|
int start, end;
|
||||||
if (TryParseRange(range, out start, out end))
|
if (TryParseRange(range, out start, out end))
|
||||||
{
|
{
|
||||||
|
|
||||||
// Before clamping start make sure we can satisfy it in order to avoid
|
// Before clamping start make sure we can satisfy it in order to avoid
|
||||||
// sending back the last byte instead of an error status
|
// sending back the last byte instead of an error status
|
||||||
if (start >= texture.Data.Length)
|
if (start >= texture.Data.Length)
|
||||||
{
|
{
|
||||||
response.StatusCode = (int)System.Net.HttpStatusCode.RequestedRangeNotSatisfiable;
|
m_log.DebugFormat(
|
||||||
|
"[GETTEXTURE]: Client requested range for texture {0} starting at {1} but texture has end of {2}",
|
||||||
|
texture.ID, start, texture.Data.Length);
|
||||||
|
|
||||||
|
// Stricly speaking, as per http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html, we should be sending back
|
||||||
|
// Requested Range Not Satisfiable (416) here. However, it appears that at least recent implementations
|
||||||
|
// of the Linden Lab viewer (3.2.1 and 3.3.4 and probably earlier), a viewer that has previously
|
||||||
|
// received a very small texture may attempt to fetch bytes from the server past the
|
||||||
|
// range of data that it received originally. Whether this happens appears to depend on whether
|
||||||
|
// the viewer's estimation of how large a request it needs to make for certain discard levels
|
||||||
|
// (http://wiki.secondlife.com/wiki/Image_System#Discard_Level_and_Mip_Mapping), chiefly discard
|
||||||
|
// level 2. If this estimate is greater than the total texture size, returning a RequestedRangeNotSatisfiable
|
||||||
|
// here will cause the viewer to treat the texture as bad and never display the full resolution
|
||||||
|
// However, if we return PartialContent (or OK) instead, the viewer will display that resolution.
|
||||||
|
|
||||||
|
// response.StatusCode = (int)System.Net.HttpStatusCode.RequestedRangeNotSatisfiable;
|
||||||
|
// response.AddHeader("Content-Range", String.Format("bytes */{0}", texture.Data.Length));
|
||||||
|
// response.StatusCode = (int)System.Net.HttpStatusCode.OK;
|
||||||
|
response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent;
|
||||||
|
response.ContentType = texture.Metadata.ContentType;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -240,6 +256,12 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
// We were accidentally sending back 404 before in this situation
|
// 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
|
// 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.
|
// entire range is requested, and viewer 3.2.2 (and very probably earlier) seems fine with this.
|
||||||
|
//
|
||||||
|
// We also do not want to send back OK even if the whole range was satisfiable since this causes
|
||||||
|
// HTTP textures on at least Imprudence 1.4.0-beta2 to never display the final texture quality.
|
||||||
|
// if (end > maxEnd)
|
||||||
|
// response.StatusCode = (int)System.Net.HttpStatusCode.OK;
|
||||||
|
// else
|
||||||
response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent;
|
response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent;
|
||||||
|
|
||||||
response.ContentLength = len;
|
response.ContentLength = len;
|
||||||
|
|
|
@ -62,8 +62,8 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
if (m_AssetService == null)
|
if (m_AssetService == null)
|
||||||
throw new Exception(String.Format("Failed to load AssetService from {0}; config is {1}", assetService, m_ConfigName));
|
throw new Exception(String.Format("Failed to load AssetService from {0}; config is {1}", assetService, m_ConfigName));
|
||||||
|
|
||||||
server.AddStreamHandler(new GetTextureHandler("/CAPS/GetTexture/" /*+ UUID.Random() */, m_AssetService));
|
server.AddStreamHandler(
|
||||||
}
|
new GetTextureHandler("/CAPS/GetTexture/" /*+ UUID.Random() */, m_AssetService, "GetTexture", null));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -50,9 +50,9 @@ namespace OpenSim.Capabilities.Handlers.GetTexture.Tests
|
||||||
TestHelpers.InMethod();
|
TestHelpers.InMethod();
|
||||||
|
|
||||||
// Overkill - we only really need the asset service, not a whole scene.
|
// Overkill - we only really need the asset service, not a whole scene.
|
||||||
Scene scene = SceneHelpers.SetupScene();
|
Scene scene = new SceneHelpers().SetupScene();
|
||||||
|
|
||||||
GetTextureHandler handler = new GetTextureHandler(null, scene.AssetService);
|
GetTextureHandler handler = new GetTextureHandler(null, scene.AssetService, "TestGetTexture", null);
|
||||||
TestOSHttpRequest req = new TestOSHttpRequest();
|
TestOSHttpRequest req = new TestOSHttpRequest();
|
||||||
TestOSHttpResponse resp = new TestOSHttpResponse();
|
TestOSHttpResponse resp = new TestOSHttpResponse();
|
||||||
req.Url = new Uri("http://localhost/?texture_id=00000000-0000-1111-9999-000000000012");
|
req.Url = new Uri("http://localhost/?texture_id=00000000-0000-1111-9999-000000000012");
|
||||||
|
|
|
@ -85,8 +85,8 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
uploader.OnUpLoad += BakedTextureUploaded;
|
uploader.OnUpLoad += BakedTextureUploaded;
|
||||||
|
|
||||||
m_HostCapsObj.HttpListener.AddStreamHandler(
|
m_HostCapsObj.HttpListener.AddStreamHandler(
|
||||||
new BinaryStreamHandler("POST", capsBase + uploaderPath,
|
new BinaryStreamHandler(
|
||||||
uploader.uploaderCaps));
|
"POST", capsBase + uploaderPath, uploader.uploaderCaps, "UploadBakedTexture", null));
|
||||||
|
|
||||||
string protocol = "http://";
|
string protocol = "http://";
|
||||||
|
|
||||||
|
|
|
@ -156,11 +156,12 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
inv.Folders = new List<InventoryFolderBase>();
|
inv.Folders = new List<InventoryFolderBase>();
|
||||||
inv.Items = new List<InventoryItemBase>();
|
inv.Items = new List<InventoryItemBase>();
|
||||||
int version = 0;
|
int version = 0;
|
||||||
|
int descendents = 0;
|
||||||
|
|
||||||
inv
|
inv
|
||||||
= Fetch(
|
= Fetch(
|
||||||
invFetch.owner_id, invFetch.folder_id, invFetch.owner_id,
|
invFetch.owner_id, invFetch.folder_id, invFetch.owner_id,
|
||||||
invFetch.fetch_folders, invFetch.fetch_items, invFetch.sort_order, out version);
|
invFetch.fetch_folders, invFetch.fetch_items, invFetch.sort_order, out version, out descendents);
|
||||||
|
|
||||||
if (inv.Folders != null)
|
if (inv.Folders != null)
|
||||||
{
|
{
|
||||||
|
@ -168,6 +169,8 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
{
|
{
|
||||||
contents.categories.Array.Add(ConvertInventoryFolder(invFolder));
|
contents.categories.Array.Add(ConvertInventoryFolder(invFolder));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
descendents += inv.Folders.Count;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inv.Items != null)
|
if (inv.Items != null)
|
||||||
|
@ -178,7 +181,7 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
contents.descendents = contents.items.Array.Count + contents.categories.Array.Count;
|
contents.descendents = descendents;
|
||||||
contents.version = version;
|
contents.version = version;
|
||||||
|
|
||||||
// m_log.DebugFormat(
|
// m_log.DebugFormat(
|
||||||
|
@ -206,7 +209,7 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
/// <returns>An empty InventoryCollection if the inventory look up failed</returns>
|
/// <returns>An empty InventoryCollection if the inventory look up failed</returns>
|
||||||
private InventoryCollection Fetch(
|
private InventoryCollection Fetch(
|
||||||
UUID agentID, UUID folderID, UUID ownerID,
|
UUID agentID, UUID folderID, UUID ownerID,
|
||||||
bool fetchFolders, bool fetchItems, int sortOrder, out int version)
|
bool fetchFolders, bool fetchItems, int sortOrder, out int version, out int descendents)
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat(
|
// m_log.DebugFormat(
|
||||||
// "[WEB FETCH INV DESC HANDLER]: Fetching folders ({0}), items ({1}) from {2} for agent {3}",
|
// "[WEB FETCH INV DESC HANDLER]: Fetching folders ({0}), items ({1}) from {2} for agent {3}",
|
||||||
|
@ -215,6 +218,8 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
// FIXME MAYBE: We're not handling sortOrder!
|
// FIXME MAYBE: We're not handling sortOrder!
|
||||||
|
|
||||||
version = 0;
|
version = 0;
|
||||||
|
descendents = 0;
|
||||||
|
|
||||||
InventoryFolderImpl fold;
|
InventoryFolderImpl fold;
|
||||||
if (m_LibraryService != null && m_LibraryService.LibraryRootFolder != null && agentID == m_LibraryService.LibraryRootFolder.Owner)
|
if (m_LibraryService != null && m_LibraryService.LibraryRootFolder != null && agentID == m_LibraryService.LibraryRootFolder.Owner)
|
||||||
{
|
{
|
||||||
|
@ -223,6 +228,7 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
InventoryCollection ret = new InventoryCollection();
|
InventoryCollection ret = new InventoryCollection();
|
||||||
ret.Folders = new List<InventoryFolderBase>();
|
ret.Folders = new List<InventoryFolderBase>();
|
||||||
ret.Items = fold.RequestListOfItems();
|
ret.Items = fold.RequestListOfItems();
|
||||||
|
descendents = ret.Folders.Count + ret.Items.Count;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -246,24 +252,72 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
|
|
||||||
version = containingFolder.Version;
|
version = containingFolder.Version;
|
||||||
|
|
||||||
// if (fetchItems)
|
if (fetchItems)
|
||||||
// {
|
{
|
||||||
// List<InventoryItemBase> linkedItemsToAdd = new List<InventoryItemBase>();
|
List<InventoryItemBase> itemsToReturn = contents.Items;
|
||||||
//
|
List<InventoryItemBase> originalItems = new List<InventoryItemBase>(itemsToReturn);
|
||||||
|
|
||||||
|
// descendents must only include the links, not the linked items we add
|
||||||
|
descendents = originalItems.Count;
|
||||||
|
|
||||||
|
// Add target items for links in this folder before the links themselves.
|
||||||
|
foreach (InventoryItemBase item in originalItems)
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
itemsToReturn.Insert(0, linkedItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now scan for folder links and insert the items they target and those links at the head of the return data
|
||||||
|
foreach (InventoryItemBase item in originalItems)
|
||||||
|
{
|
||||||
|
if (item.AssetType == (int)AssetType.LinkFolder)
|
||||||
|
{
|
||||||
|
InventoryCollection linkedFolderContents = m_InventoryService.GetFolderContent(ownerID, item.AssetID);
|
||||||
|
List<InventoryItemBase> links = linkedFolderContents.Items;
|
||||||
|
|
||||||
|
itemsToReturn.InsertRange(0, links);
|
||||||
|
|
||||||
|
foreach (InventoryItemBase link in linkedFolderContents.Items)
|
||||||
|
{
|
||||||
|
// 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 (link != null)
|
||||||
|
{
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[WEB FETCH INV DESC HANDLER]: Adding item {0} {1} from folder {2} linked from {3}",
|
||||||
|
// link.Name, (AssetType)link.AssetType, item.AssetID, containingFolder.Name);
|
||||||
|
|
||||||
|
InventoryItemBase linkedItem
|
||||||
|
= m_InventoryService.GetItem(new InventoryItemBase(link.AssetID));
|
||||||
|
|
||||||
|
if (linkedItem != null)
|
||||||
|
itemsToReturn.Insert(0, linkedItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// foreach (InventoryItemBase item in contents.Items)
|
// foreach (InventoryItemBase item in contents.Items)
|
||||||
// {
|
// {
|
||||||
// if (item.AssetType == (int)AssetType.Link)
|
// m_log.DebugFormat(
|
||||||
// {
|
// "[WEB FETCH INV DESC HANDLER]: Returning item {0}, type {1}, parent {2} in {3} {4}",
|
||||||
// InventoryItemBase linkedItem = m_InventoryService.GetItem(new InventoryItemBase(item.AssetID));
|
// item.Name, (AssetType)item.AssetType, item.Folder, containingFolder.Name, containingFolder.ID);
|
||||||
//
|
|
||||||
// // 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)
|
// foreach (InventoryItemBase linkedItem in linkedItemsToAdd)
|
||||||
// {
|
// {
|
||||||
|
@ -340,12 +394,8 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
llsdFolder.folder_id = invFolder.ID;
|
llsdFolder.folder_id = invFolder.ID;
|
||||||
llsdFolder.parent_id = invFolder.ParentID;
|
llsdFolder.parent_id = invFolder.ParentID;
|
||||||
llsdFolder.name = invFolder.Name;
|
llsdFolder.name = invFolder.Name;
|
||||||
|
llsdFolder.type = invFolder.Type;
|
||||||
if (invFolder.Type == (short)AssetType.Unknown || !Enum.IsDefined(typeof(AssetType), (sbyte)invFolder.Type))
|
llsdFolder.preferred_type = -1;
|
||||||
llsdFolder.type = "-1";
|
|
||||||
else
|
|
||||||
llsdFolder.type = Utils.AssetTypeToString((AssetType)invFolder.Type);
|
|
||||||
llsdFolder.preferred_type = "-1";
|
|
||||||
|
|
||||||
return llsdFolder;
|
return llsdFolder;
|
||||||
}
|
}
|
||||||
|
@ -365,18 +415,8 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
llsdItem.item_id = invItem.ID;
|
llsdItem.item_id = invItem.ID;
|
||||||
llsdItem.name = invItem.Name;
|
llsdItem.name = invItem.Name;
|
||||||
llsdItem.parent_id = invItem.Folder;
|
llsdItem.parent_id = invItem.Folder;
|
||||||
|
llsdItem.type = invItem.AssetType;
|
||||||
try
|
llsdItem.inv_type = invItem.InvType;
|
||||||
{
|
|
||||||
llsdItem.type = Utils.AssetTypeToString((AssetType)invItem.AssetType);
|
|
||||||
llsdItem.inv_type = Utils.InventoryTypeToString((InventoryType)invItem.InvType);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
m_log.ErrorFormat(
|
|
||||||
"[WEB FETCH INV DESC HANDLER]: Problem setting asset {0} inventory {1} types while converting inventory item {2}: {3}",
|
|
||||||
invItem.AssetType, invItem.InvType, invItem.Name, e.Message);
|
|
||||||
}
|
|
||||||
|
|
||||||
llsdItem.permissions = new LLSDPermissions();
|
llsdItem.permissions = new LLSDPermissions();
|
||||||
llsdItem.permissions.creator_id = invItem.CreatorIdAsUuid;
|
llsdItem.permissions.creator_id = invItem.CreatorIdAsUuid;
|
||||||
|
@ -390,21 +430,7 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
llsdItem.permissions.owner_mask = (int)invItem.CurrentPermissions;
|
llsdItem.permissions.owner_mask = (int)invItem.CurrentPermissions;
|
||||||
llsdItem.sale_info = new LLSDSaleInfo();
|
llsdItem.sale_info = new LLSDSaleInfo();
|
||||||
llsdItem.sale_info.sale_price = invItem.SalePrice;
|
llsdItem.sale_info.sale_price = invItem.SalePrice;
|
||||||
switch (invItem.SaleType)
|
llsdItem.sale_info.sale_type = invItem.SaleType;
|
||||||
{
|
|
||||||
default:
|
|
||||||
llsdItem.sale_info.sale_type = "not";
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
llsdItem.sale_info.sale_type = "original";
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
llsdItem.sale_info.sale_type = "copy";
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
llsdItem.sale_info.sale_type = "contents";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return llsdItem;
|
return llsdItem;
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,7 +68,13 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
ServerUtils.LoadPlugin<ILibraryService>(libService, args);
|
ServerUtils.LoadPlugin<ILibraryService>(libService, args);
|
||||||
|
|
||||||
WebFetchInvDescHandler webFetchHandler = new WebFetchInvDescHandler(m_InventoryService, m_LibraryService);
|
WebFetchInvDescHandler webFetchHandler = new WebFetchInvDescHandler(m_InventoryService, m_LibraryService);
|
||||||
IRequestHandler reqHandler = new RestStreamHandler("POST", "/CAPS/WebFetchInvDesc/" /*+ UUID.Random()*/, webFetchHandler.FetchInventoryDescendentsRequest);
|
IRequestHandler reqHandler
|
||||||
|
= new RestStreamHandler(
|
||||||
|
"POST",
|
||||||
|
"/CAPS/WebFetchInvDesc/" /*+ UUID.Random()*/,
|
||||||
|
webFetchHandler.FetchInventoryDescendentsRequest,
|
||||||
|
"WebFetchInvDesc",
|
||||||
|
null);
|
||||||
server.AddStreamHandler(reqHandler);
|
server.AddStreamHandler(reqHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ namespace OpenSim.Framework.Capabilities
|
||||||
public UUID folder_id;
|
public UUID folder_id;
|
||||||
public UUID parent_id;
|
public UUID parent_id;
|
||||||
public string name;
|
public string name;
|
||||||
public string type;
|
public int type;
|
||||||
public string preferred_type;
|
public int preferred_type;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,8 +37,8 @@ namespace OpenSim.Framework.Capabilities
|
||||||
public UUID asset_id;
|
public UUID asset_id;
|
||||||
public UUID item_id;
|
public UUID item_id;
|
||||||
public LLSDPermissions permissions;
|
public LLSDPermissions permissions;
|
||||||
public string type;
|
public int type;
|
||||||
public string inv_type;
|
public int inv_type;
|
||||||
public int flags;
|
public int flags;
|
||||||
|
|
||||||
public LLSDSaleInfo sale_info;
|
public LLSDSaleInfo sale_info;
|
||||||
|
@ -65,7 +65,7 @@ namespace OpenSim.Framework.Capabilities
|
||||||
public class LLSDSaleInfo
|
public class LLSDSaleInfo
|
||||||
{
|
{
|
||||||
public int sale_price;
|
public int sale_price;
|
||||||
public string sale_type;
|
public int sale_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
[OSDMap]
|
[OSDMap]
|
||||||
|
|
|
@ -39,7 +39,11 @@ namespace OpenSim.Framework.Capabilities
|
||||||
private LLSDMethod<TRequest, TResponse> m_method;
|
private LLSDMethod<TRequest, TResponse> m_method;
|
||||||
|
|
||||||
public LLSDStreamhandler(string httpMethod, string path, LLSDMethod<TRequest, TResponse> method)
|
public LLSDStreamhandler(string httpMethod, string path, LLSDMethod<TRequest, TResponse> method)
|
||||||
: base(httpMethod, path)
|
: this(httpMethod, path, method, null, null) {}
|
||||||
|
|
||||||
|
public LLSDStreamhandler(
|
||||||
|
string httpMethod, string path, LLSDMethod<TRequest, TResponse> method, string name, string description)
|
||||||
|
: base(httpMethod, path, name, description)
|
||||||
{
|
{
|
||||||
m_method = method;
|
m_method = method;
|
||||||
}
|
}
|
||||||
|
@ -62,9 +66,7 @@ namespace OpenSim.Framework.Capabilities
|
||||||
|
|
||||||
TResponse response = m_method(llsdRequest);
|
TResponse response = m_method(llsdRequest);
|
||||||
|
|
||||||
Encoding encoding = new UTF8Encoding(false);
|
return Util.UTF8NoBomEncoding.GetBytes(LLSDHelpers.SerialiseLLSDReply(response));
|
||||||
|
|
||||||
return encoding.GetBytes(LLSDHelpers.SerialiseLLSDReply(response));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@ namespace OpenSim.ConsoleClient
|
||||||
|
|
||||||
request.ContentType = "application/x-www-form-urlencoded";
|
request.ContentType = "application/x-www-form-urlencoded";
|
||||||
|
|
||||||
byte[] buffer = new System.Text.ASCIIEncoding().GetBytes(data);
|
byte[] buffer = Encoding.ASCII.GetBytes(data);
|
||||||
int length = (int) buffer.Length;
|
int length = (int) buffer.Length;
|
||||||
request.ContentLength = length;
|
request.ContentLength = length;
|
||||||
|
|
||||||
|
|
|
@ -106,7 +106,22 @@ namespace OpenSim.Data
|
||||||
/// <returns>true if the delete was successful, false if it was not</returns>
|
/// <returns>true if the delete was successful, false if it was not</returns>
|
||||||
bool DeleteItems(string[] fields, string[] vals);
|
bool DeleteItems(string[] fields, string[] vals);
|
||||||
|
|
||||||
bool MoveItem(string id, string newParent);
|
/// <summary>
|
||||||
|
/// Move an item to another folder.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>/returns>
|
||||||
|
/// <param name='id'>UUID of the item</param>
|
||||||
|
/// <param name='newParent'>UUID of the new parent folder.</param>
|
||||||
|
bool MoveItem(string id, string newParentFolderID);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Move a folder to another folder.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>/returns>
|
||||||
|
/// <param name='id'>UUID of the item</param>
|
||||||
|
/// <param name='newParent'>UUID of the new parent folder.</param>
|
||||||
|
bool MoveFolder(string id, string newParentFolderID);
|
||||||
|
|
||||||
XInventoryItem[] GetActiveGestures(UUID principalID);
|
XInventoryItem[] GetActiveGestures(UUID principalID);
|
||||||
int GetAssetPermissions(UUID principalID, UUID assetID);
|
int GetAssetPermissions(UUID principalID, UUID assetID);
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,5 +89,11 @@ namespace OpenSim.Data.MSSQL
|
||||||
return DoQuery(cmd);
|
return DoQuery(cmd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public FriendsData[] GetFriends(Guid principalID)
|
||||||
|
{
|
||||||
|
return GetFriends(principalID.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -813,7 +813,7 @@ namespace OpenSim.Data.MSSQL
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using (SqlCommand command = new SqlCommand("DELETE FROM inventoryfolders WHERE folderID=@folderID", connection))
|
using (SqlCommand command = new SqlCommand("DELETE FROM inventoryfolders WHERE folderID=@folderID and type=-1", connection))
|
||||||
{
|
{
|
||||||
command.Parameters.Add(database.CreateParameter("folderID", folderID));
|
command.Parameters.Add(database.CreateParameter("folderID", folderID));
|
||||||
|
|
||||||
|
|
|
@ -675,7 +675,7 @@ VALUES
|
||||||
cmd.ExecuteNonQuery();
|
cmd.ExecuteNonQuery();
|
||||||
}
|
}
|
||||||
|
|
||||||
sql = "INSERT INTO [landaccesslist] ([LandUUID],[AccessUUID],[Flags]) VALUES (@LandUUID,@AccessUUID,@Flags)";
|
sql = "INSERT INTO [landaccesslist] ([LandUUID],[AccessUUID],[Flags],[Expires]) VALUES (@LandUUID,@AccessUUID,@Flags,@Expires)";
|
||||||
|
|
||||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||||
|
@ -1215,6 +1215,8 @@ VALUES
|
||||||
//Store new values
|
//Store new values
|
||||||
StoreNewRegionSettings(regionSettings);
|
StoreNewRegionSettings(regionSettings);
|
||||||
|
|
||||||
|
LoadSpawnPoints(regionSettings);
|
||||||
|
|
||||||
return regionSettings;
|
return regionSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1252,7 +1254,7 @@ VALUES
|
||||||
,[elevation_1_ne] = @elevation_1_ne ,[elevation_2_ne] = @elevation_2_ne ,[elevation_1_se] = @elevation_1_se ,[elevation_2_se] = @elevation_2_se
|
,[elevation_1_ne] = @elevation_1_ne ,[elevation_2_ne] = @elevation_2_ne ,[elevation_1_se] = @elevation_1_se ,[elevation_2_se] = @elevation_2_se
|
||||||
,[elevation_1_sw] = @elevation_1_sw ,[elevation_2_sw] = @elevation_2_sw ,[water_height] = @water_height ,[terrain_raise_limit] = @terrain_raise_limit
|
,[elevation_1_sw] = @elevation_1_sw ,[elevation_2_sw] = @elevation_2_sw ,[water_height] = @water_height ,[terrain_raise_limit] = @terrain_raise_limit
|
||||||
,[terrain_lower_limit] = @terrain_lower_limit ,[use_estate_sun] = @use_estate_sun ,[fixed_sun] = @fixed_sun ,[sun_position] = @sun_position
|
,[terrain_lower_limit] = @terrain_lower_limit ,[use_estate_sun] = @use_estate_sun ,[fixed_sun] = @fixed_sun ,[sun_position] = @sun_position
|
||||||
,[covenant] = @covenant ,[covenant_datetime] = @covenant_datetime, [sunvectorx] = @sunvectorx, [sunvectory] = @sunvectory, [sunvectorz] = @sunvectorz, [Sandbox] = @Sandbox, [loaded_creation_datetime] = @loaded_creation_datetime, [loaded_creation_id] = @loaded_creation_id
|
,[covenant] = @covenant ,[covenant_datetime] = @covenant_datetime, [sunvectorx] = @sunvectorx, [sunvectory] = @sunvectory, [sunvectorz] = @sunvectorz, [Sandbox] = @Sandbox, [loaded_creation_datetime] = @loaded_creation_datetime, [loaded_creation_id] = @loaded_creation_id, [map_tile_id] = @TerrainImageID, [telehubobject] = @telehubobject, [parcel_tile_id] = @ParcelImageID
|
||||||
WHERE [regionUUID] = @regionUUID";
|
WHERE [regionUUID] = @regionUUID";
|
||||||
|
|
||||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||||
|
@ -1263,6 +1265,7 @@ VALUES
|
||||||
cmd.ExecuteNonQuery();
|
cmd.ExecuteNonQuery();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
SaveSpawnPoints(regionSettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Shutdown()
|
public void Shutdown()
|
||||||
|
@ -1383,6 +1386,11 @@ VALUES
|
||||||
newSettings.LoadedCreationID = "";
|
newSettings.LoadedCreationID = "";
|
||||||
else
|
else
|
||||||
newSettings.LoadedCreationID = (String)row["loaded_creation_id"];
|
newSettings.LoadedCreationID = (String)row["loaded_creation_id"];
|
||||||
|
|
||||||
|
newSettings.TerrainImageID = new UUID((string)row["map_tile_ID"]);
|
||||||
|
newSettings.ParcelImageID = new UUID((Guid)row["parcel_tile_ID"]);
|
||||||
|
newSettings.TelehubObject = new UUID((Guid)row["TelehubObject"]);
|
||||||
|
|
||||||
return newSettings;
|
return newSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1454,6 +1462,13 @@ VALUES
|
||||||
}
|
}
|
||||||
|
|
||||||
newData.ParcelAccessList = new List<LandAccessEntry>();
|
newData.ParcelAccessList = new List<LandAccessEntry>();
|
||||||
|
newData.MediaDescription = (string)row["MediaDescription"];
|
||||||
|
newData.MediaType = (string)row["MediaType"];
|
||||||
|
newData.MediaWidth = Convert.ToInt32((((string)row["MediaSize"]).Split(','))[0]);
|
||||||
|
newData.MediaHeight = Convert.ToInt32((((string)row["MediaSize"]).Split(','))[1]);
|
||||||
|
newData.MediaLoop = Convert.ToBoolean(row["MediaLoop"]);
|
||||||
|
newData.ObscureMusic = Convert.ToBoolean(row["ObscureMusic"]);
|
||||||
|
newData.ObscureMedia = Convert.ToBoolean(row["ObscureMedia"]);
|
||||||
|
|
||||||
return newData;
|
return newData;
|
||||||
}
|
}
|
||||||
|
@ -1468,7 +1483,7 @@ VALUES
|
||||||
LandAccessEntry entry = new LandAccessEntry();
|
LandAccessEntry entry = new LandAccessEntry();
|
||||||
entry.AgentID = new UUID((Guid)row["AccessUUID"]);
|
entry.AgentID = new UUID((Guid)row["AccessUUID"]);
|
||||||
entry.Flags = (AccessList)Convert.ToInt32(row["Flags"]);
|
entry.Flags = (AccessList)Convert.ToInt32(row["Flags"]);
|
||||||
entry.Expires = 0;
|
entry.Expires = Convert.ToInt32(row["Expires"]);
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1497,7 +1512,8 @@ VALUES
|
||||||
prim.TouchName = (string)primRow["TouchName"];
|
prim.TouchName = (string)primRow["TouchName"];
|
||||||
// permissions
|
// permissions
|
||||||
prim.Flags = (PrimFlags)Convert.ToUInt32(primRow["ObjectFlags"]);
|
prim.Flags = (PrimFlags)Convert.ToUInt32(primRow["ObjectFlags"]);
|
||||||
prim.CreatorID = new UUID((Guid)primRow["CreatorID"]);
|
//prim.CreatorID = new UUID((Guid)primRow["CreatorID"]);
|
||||||
|
prim.CreatorIdentification = (string)primRow["CreatorID"];
|
||||||
prim.OwnerID = new UUID((Guid)primRow["OwnerID"]);
|
prim.OwnerID = new UUID((Guid)primRow["OwnerID"]);
|
||||||
prim.GroupID = new UUID((Guid)primRow["GroupID"]);
|
prim.GroupID = new UUID((Guid)primRow["GroupID"]);
|
||||||
prim.LastOwnerID = new UUID((Guid)primRow["LastOwnerID"]);
|
prim.LastOwnerID = new UUID((Guid)primRow["LastOwnerID"]);
|
||||||
|
@ -1691,7 +1707,8 @@ VALUES
|
||||||
taskItem.Name = (string)inventoryRow["name"];
|
taskItem.Name = (string)inventoryRow["name"];
|
||||||
taskItem.Description = (string)inventoryRow["description"];
|
taskItem.Description = (string)inventoryRow["description"];
|
||||||
taskItem.CreationDate = Convert.ToUInt32(inventoryRow["creationDate"]);
|
taskItem.CreationDate = Convert.ToUInt32(inventoryRow["creationDate"]);
|
||||||
taskItem.CreatorID = new UUID((Guid)inventoryRow["creatorID"]);
|
//taskItem.CreatorID = new UUID((Guid)inventoryRow["creatorID"]);
|
||||||
|
taskItem.CreatorIdentification = (string)inventoryRow["creatorID"];
|
||||||
taskItem.OwnerID = new UUID((Guid)inventoryRow["ownerID"]);
|
taskItem.OwnerID = new UUID((Guid)inventoryRow["ownerID"]);
|
||||||
taskItem.LastOwnerID = new UUID((Guid)inventoryRow["lastOwnerID"]);
|
taskItem.LastOwnerID = new UUID((Guid)inventoryRow["lastOwnerID"]);
|
||||||
taskItem.GroupID = new UUID((Guid)inventoryRow["groupID"]);
|
taskItem.GroupID = new UUID((Guid)inventoryRow["groupID"]);
|
||||||
|
@ -1792,6 +1809,9 @@ VALUES
|
||||||
parameters.Add(_Database.CreateParameter("covenant_datetime", settings.CovenantChangedDateTime));
|
parameters.Add(_Database.CreateParameter("covenant_datetime", settings.CovenantChangedDateTime));
|
||||||
parameters.Add(_Database.CreateParameter("Loaded_Creation_DateTime", settings.LoadedCreationDateTime));
|
parameters.Add(_Database.CreateParameter("Loaded_Creation_DateTime", settings.LoadedCreationDateTime));
|
||||||
parameters.Add(_Database.CreateParameter("Loaded_Creation_ID", settings.LoadedCreationID));
|
parameters.Add(_Database.CreateParameter("Loaded_Creation_ID", settings.LoadedCreationID));
|
||||||
|
parameters.Add(_Database.CreateParameter("TerrainImageID", settings.TerrainImageID));
|
||||||
|
parameters.Add(_Database.CreateParameter("ParcelImageID", settings.ParcelImageID));
|
||||||
|
parameters.Add(_Database.CreateParameter("TelehubObject", settings.TelehubObject));
|
||||||
|
|
||||||
return parameters.ToArray();
|
return parameters.ToArray();
|
||||||
}
|
}
|
||||||
|
@ -1859,6 +1879,7 @@ VALUES
|
||||||
parameters.Add(_Database.CreateParameter("LandUUID", parcelID));
|
parameters.Add(_Database.CreateParameter("LandUUID", parcelID));
|
||||||
parameters.Add(_Database.CreateParameter("AccessUUID", parcelAccessEntry.AgentID));
|
parameters.Add(_Database.CreateParameter("AccessUUID", parcelAccessEntry.AgentID));
|
||||||
parameters.Add(_Database.CreateParameter("Flags", parcelAccessEntry.Flags));
|
parameters.Add(_Database.CreateParameter("Flags", parcelAccessEntry.Flags));
|
||||||
|
parameters.Add(_Database.CreateParameter("Expires", parcelAccessEntry.Expires));
|
||||||
|
|
||||||
return parameters.ToArray();
|
return parameters.ToArray();
|
||||||
}
|
}
|
||||||
|
@ -2063,5 +2084,57 @@ VALUES
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
private void LoadSpawnPoints(RegionSettings rs)
|
||||||
|
{
|
||||||
|
rs.ClearSpawnPoints();
|
||||||
|
|
||||||
|
string sql = "SELECT Yaw, Pitch, Distance FROM spawn_points WHERE RegionUUID = @RegionUUID";
|
||||||
|
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||||
|
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||||
|
{
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", rs.RegionUUID.ToString()));
|
||||||
|
conn.Open();
|
||||||
|
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||||
|
{
|
||||||
|
if (reader.Read())
|
||||||
|
{
|
||||||
|
SpawnPoint sp = new SpawnPoint();
|
||||||
|
|
||||||
|
sp.Yaw = (float)reader["Yaw"];
|
||||||
|
sp.Pitch = (float)reader["Pitch"];
|
||||||
|
sp.Distance = (float)reader["Distance"];
|
||||||
|
|
||||||
|
rs.AddSpawnPoint(sp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SaveSpawnPoints(RegionSettings rs)
|
||||||
|
{
|
||||||
|
string sql = "DELETE FROM spawn_points WHERE RegionUUID = @RegionUUID";
|
||||||
|
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||||
|
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||||
|
{
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", rs.RegionUUID));
|
||||||
|
conn.Open();
|
||||||
|
cmd.ExecuteNonQuery();
|
||||||
|
}
|
||||||
|
foreach (SpawnPoint p in rs.SpawnPoints())
|
||||||
|
{
|
||||||
|
sql = "INSERT INTO spawn_points (RegionUUID, Yaw, Pitch, Distance) VALUES (@RegionUUID, @Yaw, @Pitch, @Distance)";
|
||||||
|
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||||
|
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||||
|
{
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", rs.RegionUUID));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("@Yaw", p.Yaw));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("@Pitch", p.Pitch));
|
||||||
|
cmd.Parameters.Add(_Database.CreateParameter("@Distance", p.Distance));
|
||||||
|
conn.Open();
|
||||||
|
cmd.ExecuteNonQuery();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,12 +43,12 @@ namespace OpenSim.Data.MSSQL
|
||||||
// private static readonly ILog m_log = LogManager.GetLogger(
|
// private static readonly ILog m_log = LogManager.GetLogger(
|
||||||
// MethodBase.GetCurrentMethod().DeclaringType);
|
// MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
private MSSQLGenericTableHandler<XInventoryFolder> m_Folders;
|
private MSSQLFolderHandler m_Folders;
|
||||||
private MSSQLItemHandler m_Items;
|
private MSSQLItemHandler m_Items;
|
||||||
|
|
||||||
public MSSQLXInventoryData(string conn, string realm)
|
public MSSQLXInventoryData(string conn, string realm)
|
||||||
{
|
{
|
||||||
m_Folders = new MSSQLGenericTableHandler<XInventoryFolder>(
|
m_Folders = new MSSQLFolderHandler(
|
||||||
conn, "inventoryfolders", "InventoryStore");
|
conn, "inventoryfolders", "InventoryStore");
|
||||||
m_Items = new MSSQLItemHandler(
|
m_Items = new MSSQLItemHandler(
|
||||||
conn, "inventoryitems", String.Empty);
|
conn, "inventoryitems", String.Empty);
|
||||||
|
@ -85,6 +85,7 @@ namespace OpenSim.Data.MSSQL
|
||||||
{
|
{
|
||||||
return m_Folders.Delete(field, val);
|
return m_Folders.Delete(field, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool DeleteFolders(string[] fields, string[] vals)
|
public bool DeleteFolders(string[] fields, string[] vals)
|
||||||
{
|
{
|
||||||
return m_Folders.Delete(fields, vals);
|
return m_Folders.Delete(fields, vals);
|
||||||
|
@ -94,15 +95,22 @@ namespace OpenSim.Data.MSSQL
|
||||||
{
|
{
|
||||||
return m_Items.Delete(field, val);
|
return m_Items.Delete(field, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool DeleteItems(string[] fields, string[] vals)
|
public bool DeleteItems(string[] fields, string[] vals)
|
||||||
{
|
{
|
||||||
return m_Items.Delete(fields, vals);
|
return m_Items.Delete(fields, vals);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool MoveItem(string id, string newParent)
|
public bool MoveItem(string id, string newParent)
|
||||||
{
|
{
|
||||||
return m_Items.MoveItem(id, newParent);
|
return m_Items.MoveItem(id, newParent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool MoveFolder(string id, string newParent)
|
||||||
|
{
|
||||||
|
return m_Folders.MoveFolder(id, newParent);
|
||||||
|
}
|
||||||
|
|
||||||
public XInventoryItem[] GetActiveGestures(UUID principalID)
|
public XInventoryItem[] GetActiveGestures(UUID principalID)
|
||||||
{
|
{
|
||||||
return m_Items.GetActiveGestures(principalID);
|
return m_Items.GetActiveGestures(principalID);
|
||||||
|
@ -124,6 +132,7 @@ namespace OpenSim.Data.MSSQL
|
||||||
public bool MoveItem(string id, string newParent)
|
public bool MoveItem(string id, string newParent)
|
||||||
{
|
{
|
||||||
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||||
|
{
|
||||||
using (SqlCommand cmd = new SqlCommand())
|
using (SqlCommand cmd = new SqlCommand())
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -135,10 +144,12 @@ namespace OpenSim.Data.MSSQL
|
||||||
return cmd.ExecuteNonQuery() == 0 ? false : true;
|
return cmd.ExecuteNonQuery() == 0 ? false : true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public XInventoryItem[] GetActiveGestures(UUID principalID)
|
public XInventoryItem[] GetActiveGestures(UUID principalID)
|
||||||
{
|
{
|
||||||
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||||
|
{
|
||||||
using (SqlCommand cmd = new SqlCommand())
|
using (SqlCommand cmd = new SqlCommand())
|
||||||
{
|
{
|
||||||
cmd.CommandText = String.Format("select * from inventoryitems where avatarId = @uuid and assetType = @type and flags = 1", m_Realm);
|
cmd.CommandText = String.Format("select * from inventoryitems where avatarId = @uuid and assetType = @type and flags = 1", m_Realm);
|
||||||
|
@ -150,10 +161,12 @@ namespace OpenSim.Data.MSSQL
|
||||||
return DoQuery(cmd);
|
return DoQuery(cmd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public int GetAssetPermissions(UUID principalID, UUID assetID)
|
public int GetAssetPermissions(UUID principalID, UUID assetID)
|
||||||
{
|
{
|
||||||
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||||
|
{
|
||||||
using (SqlCommand cmd = new SqlCommand())
|
using (SqlCommand cmd = new SqlCommand())
|
||||||
{
|
{
|
||||||
cmd.CommandText = String.Format("select bit_or(inventoryCurrentPermissions) as inventoryCurrentPermissions from inventoryitems where avatarID = @PrincipalID and assetID = @AssetID group by assetID", m_Realm);
|
cmd.CommandText = String.Format("select bit_or(inventoryCurrentPermissions) as inventoryCurrentPermissions from inventoryitems where avatarID = @PrincipalID and assetID = @AssetID group by assetID", m_Realm);
|
||||||
|
@ -176,12 +189,16 @@ namespace OpenSim.Data.MSSQL
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override bool Store(XInventoryItem item)
|
public override bool Store(XInventoryItem item)
|
||||||
{
|
{
|
||||||
if (!base.Store(item))
|
if (!base.Store(item))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
string sql = "update inventoryfolders set version=version+1 where folderID = @folderID";
|
string sql = "update inventoryfolders set version=version+1 where folderID = @folderID";
|
||||||
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||||
|
{
|
||||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||||
{
|
{
|
||||||
conn.Open();
|
conn.Open();
|
||||||
|
@ -196,7 +213,34 @@ namespace OpenSim.Data.MSSQL
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class MSSQLFolderHandler : MSSQLGenericTableHandler<XInventoryFolder>
|
||||||
|
{
|
||||||
|
public MSSQLFolderHandler(string c, string t, string m) :
|
||||||
|
base(c, t, m)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool MoveFolder(string id, string newParentFolderID)
|
||||||
|
{
|
||||||
|
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||||
|
{
|
||||||
|
using (SqlCommand cmd = new SqlCommand())
|
||||||
|
{
|
||||||
|
|
||||||
|
cmd.CommandText = String.Format("update {0} set parentFolderID = @ParentFolderID where folderID = @folderID", m_Realm);
|
||||||
|
cmd.Parameters.Add(m_database.CreateParameter("@ParentFolderID", newParentFolderID));
|
||||||
|
cmd.Parameters.Add(m_database.CreateParameter("@folderID", id));
|
||||||
|
cmd.Connection = conn;
|
||||||
|
conn.Open();
|
||||||
|
return cmd.ExecuteNonQuery() == 0 ? false : true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1044,10 +1044,93 @@ ALTER TABLE primitems ALTER COLUMN CreatorID uniqueidentifier NOT NULL
|
||||||
|
|
||||||
COMMIT
|
COMMIT
|
||||||
|
|
||||||
:VERSION 29 #---------------------
|
:VERSION 29 #----------------- Region Covenant changed time
|
||||||
|
|
||||||
BEGIN TRANSACTION
|
BEGIN TRANSACTION
|
||||||
|
|
||||||
ALTER TABLE regionsettings ADD covenant_datetime int NOT NULL default 0
|
ALTER TABLE regionsettings ADD covenant_datetime int NOT NULL default 0
|
||||||
|
|
||||||
COMMIT
|
COMMIT
|
||||||
|
|
||||||
|
:VERSION 30 #------------------Migrate creatorID storage to varchars instead of UUIDs for HG support
|
||||||
|
|
||||||
|
BEGIN TRANSACTION
|
||||||
|
|
||||||
|
EXECUTE sp_rename N'dbo.prims.creatorid', N'creatoridold', 'COLUMN'
|
||||||
|
EXECUTE sp_rename N'dbo.primitems.creatorid', N'creatoridold', 'COLUMN'
|
||||||
|
|
||||||
|
COMMIT
|
||||||
|
|
||||||
|
:VERSION 31 #---------------------
|
||||||
|
|
||||||
|
BEGIN TRANSACTION
|
||||||
|
|
||||||
|
ALTER TABLE prims ADD CreatorID varchar(255)
|
||||||
|
ALTER TABLE primitems ADD CreatorID varchar(255)
|
||||||
|
|
||||||
|
COMMIT
|
||||||
|
|
||||||
|
:VERSION 32 #---------------------
|
||||||
|
|
||||||
|
BEGIN TRANSACTION
|
||||||
|
|
||||||
|
UPDATE prims SET prims.CreatorID = CONVERT(varchar(255), creatoridold)
|
||||||
|
UPDATE primitems SET primitems.CreatorID = CONVERT(varchar(255), creatoridold)
|
||||||
|
|
||||||
|
COMMIT
|
||||||
|
|
||||||
|
:VERSION 33 #---------------------
|
||||||
|
|
||||||
|
BEGIN TRANSACTION
|
||||||
|
|
||||||
|
ALTER TABLE prims
|
||||||
|
ADD CONSTRAINT DF_prims_CreatorIDNew
|
||||||
|
DEFAULT '00000000-0000-0000-0000-000000000000'
|
||||||
|
FOR CreatorID
|
||||||
|
|
||||||
|
ALTER TABLE prims ALTER COLUMN CreatorID varchar(255) NOT NULL
|
||||||
|
|
||||||
|
ALTER TABLE primitems
|
||||||
|
ADD CONSTRAINT DF_primitems_CreatorIDNew
|
||||||
|
DEFAULT '00000000-0000-0000-0000-000000000000'
|
||||||
|
FOR CreatorID
|
||||||
|
|
||||||
|
ALTER TABLE primitems ALTER COLUMN CreatorID varchar(255) NOT NULL
|
||||||
|
|
||||||
|
COMMIT
|
||||||
|
|
||||||
|
:VERSION 34 #--------------- Telehub support
|
||||||
|
|
||||||
|
BEGIN TRANSACTION
|
||||||
|
|
||||||
|
CREATE TABLE [dbo].[Spawn_Points](
|
||||||
|
[RegionUUID] [uniqueidentifier] NOT NULL,
|
||||||
|
[Yaw] [float] NOT NULL,
|
||||||
|
[Pitch] [float] NOT NULL,
|
||||||
|
[Distance] [float] NOT NULL,
|
||||||
|
PRIMARY KEY CLUSTERED
|
||||||
|
(
|
||||||
|
[RegionUUID] ASC
|
||||||
|
)WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
|
||||||
|
) ON [PRIMARY]
|
||||||
|
|
||||||
|
ALTER TABLE regionsettings ADD TelehubObject uniqueidentifier NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000';
|
||||||
|
|
||||||
|
COMMIT
|
||||||
|
|
||||||
|
:VERSION 35 #---------------- Parcels for sale
|
||||||
|
|
||||||
|
BEGIN TRANSACTION
|
||||||
|
|
||||||
|
ALTER TABLE regionsettings ADD parcel_tile_ID uniqueidentifier NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000';
|
||||||
|
|
||||||
|
COMMIT
|
||||||
|
|
||||||
|
:VERSION 36 #---------------- Timed bans/access
|
||||||
|
|
||||||
|
BEGIN TRANSACTION
|
||||||
|
|
||||||
|
ALTER TABLE landaccesslist ADD Expires integer NOT NULL DEFAULT 0;
|
||||||
|
|
||||||
|
COMMIT
|
||||||
|
|
||||||
|
|
|
@ -217,6 +217,8 @@ namespace OpenSim.Data.MySQL
|
||||||
|
|
||||||
public virtual bool Store(T row)
|
public virtual bool Store(T row)
|
||||||
{
|
{
|
||||||
|
// m_log.DebugFormat("[MYSQL GENERIC TABLE HANDLER]: Store(T row) invoked");
|
||||||
|
|
||||||
using (MySqlCommand cmd = new MySqlCommand())
|
using (MySqlCommand cmd = new MySqlCommand())
|
||||||
{
|
{
|
||||||
string query = "";
|
string query = "";
|
||||||
|
@ -271,6 +273,10 @@ namespace OpenSim.Data.MySQL
|
||||||
|
|
||||||
public virtual bool Delete(string[] fields, string[] keys)
|
public virtual bool Delete(string[] fields, string[] keys)
|
||||||
{
|
{
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[MYSQL GENERIC TABLE HANDLER]: Delete(string[] fields, string[] keys) invoked with {0}:{1}",
|
||||||
|
// string.Join(",", fields), string.Join(",", keys));
|
||||||
|
|
||||||
if (fields.Length != keys.Length)
|
if (fields.Length != keys.Length)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
|
@ -26,9 +26,10 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Data;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Data;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
using log4net;
|
using log4net;
|
||||||
using MySql.Data.MySqlClient;
|
using MySql.Data.MySqlClient;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
|
@ -41,12 +42,12 @@ namespace OpenSim.Data.MySQL
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class MySQLXInventoryData : IXInventoryData
|
public class MySQLXInventoryData : IXInventoryData
|
||||||
{
|
{
|
||||||
private MySQLGenericTableHandler<XInventoryFolder> m_Folders;
|
private MySqlFolderHandler m_Folders;
|
||||||
private MySqlItemHandler m_Items;
|
private MySqlItemHandler m_Items;
|
||||||
|
|
||||||
public MySQLXInventoryData(string conn, string realm)
|
public MySQLXInventoryData(string conn, string realm)
|
||||||
{
|
{
|
||||||
m_Folders = new MySQLGenericTableHandler<XInventoryFolder>(
|
m_Folders = new MySqlFolderHandler(
|
||||||
conn, "inventoryfolders", "InventoryStore");
|
conn, "inventoryfolders", "InventoryStore");
|
||||||
m_Items = new MySqlItemHandler(
|
m_Items = new MySqlItemHandler(
|
||||||
conn, "inventoryitems", String.Empty);
|
conn, "inventoryitems", String.Empty);
|
||||||
|
@ -105,6 +106,11 @@ namespace OpenSim.Data.MySQL
|
||||||
return m_Items.MoveItem(id, newParent);
|
return m_Items.MoveItem(id, newParent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool MoveFolder(string id, string newParent)
|
||||||
|
{
|
||||||
|
return m_Folders.MoveFolder(id, newParent);
|
||||||
|
}
|
||||||
|
|
||||||
public XInventoryItem[] GetActiveGestures(UUID principalID)
|
public XInventoryItem[] GetActiveGestures(UUID principalID)
|
||||||
{
|
{
|
||||||
return m_Items.GetActiveGestures(principalID);
|
return m_Items.GetActiveGestures(principalID);
|
||||||
|
@ -118,22 +124,69 @@ namespace OpenSim.Data.MySQL
|
||||||
|
|
||||||
public class MySqlItemHandler : MySQLGenericTableHandler<XInventoryItem>
|
public class MySqlItemHandler : MySQLGenericTableHandler<XInventoryItem>
|
||||||
{
|
{
|
||||||
|
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
public MySqlItemHandler(string c, string t, string m) :
|
public MySqlItemHandler(string c, string t, string m) :
|
||||||
base(c, t, m)
|
base(c, t, m)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override bool Delete(string field, string val)
|
||||||
|
{
|
||||||
|
XInventoryItem[] retrievedItems = Get(new string[] { field }, new string[] { val });
|
||||||
|
if (retrievedItems.Length == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!base.Delete(field, val))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Don't increment folder version here since Delete(string, string) calls Delete(string[], string[])
|
||||||
|
// IncrementFolderVersion(retrievedItems[0].parentFolderID);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Delete(string[] fields, string[] vals)
|
||||||
|
{
|
||||||
|
XInventoryItem[] retrievedItems = Get(fields, vals);
|
||||||
|
if (retrievedItems.Length == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!base.Delete(fields, vals))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
HashSet<UUID> deletedItemFolderUUIDs = new HashSet<UUID>();
|
||||||
|
|
||||||
|
Array.ForEach<XInventoryItem>(retrievedItems, i => deletedItemFolderUUIDs.Add(i.parentFolderID));
|
||||||
|
|
||||||
|
foreach (UUID deletedItemFolderUUID in deletedItemFolderUUIDs)
|
||||||
|
IncrementFolderVersion(deletedItemFolderUUID);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public bool MoveItem(string id, string newParent)
|
public bool MoveItem(string id, string newParent)
|
||||||
{
|
{
|
||||||
|
XInventoryItem[] retrievedItems = Get(new string[] { "inventoryID" }, new string[] { id });
|
||||||
|
if (retrievedItems.Length == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
UUID oldParent = retrievedItems[0].parentFolderID;
|
||||||
|
|
||||||
using (MySqlCommand cmd = new MySqlCommand())
|
using (MySqlCommand cmd = new MySqlCommand())
|
||||||
{
|
{
|
||||||
|
|
||||||
cmd.CommandText = String.Format("update {0} set parentFolderID = ?ParentFolderID where inventoryID = ?InventoryID", m_Realm);
|
cmd.CommandText = String.Format("update {0} set parentFolderID = ?ParentFolderID where inventoryID = ?InventoryID", m_Realm);
|
||||||
cmd.Parameters.AddWithValue("?ParentFolderID", newParent);
|
cmd.Parameters.AddWithValue("?ParentFolderID", newParent);
|
||||||
cmd.Parameters.AddWithValue("?InventoryID", id);
|
cmd.Parameters.AddWithValue("?InventoryID", id);
|
||||||
|
|
||||||
return ExecuteNonQuery(cmd) == 0 ? false : true;
|
if (ExecuteNonQuery(cmd) == 0)
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IncrementFolderVersion(oldParent);
|
||||||
|
IncrementFolderVersion(newParent);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public XInventoryItem[] GetActiveGestures(UUID principalID)
|
public XInventoryItem[] GetActiveGestures(UUID principalID)
|
||||||
|
@ -184,6 +237,21 @@ namespace OpenSim.Data.MySQL
|
||||||
if (!base.Store(item))
|
if (!base.Store(item))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
IncrementFolderVersion(item.parentFolderID);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool IncrementFolderVersion(UUID folderID)
|
||||||
|
{
|
||||||
|
return IncrementFolderVersion(folderID.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool IncrementFolderVersion(string folderID)
|
||||||
|
{
|
||||||
|
// m_log.DebugFormat("[MYSQL ITEM HANDLER]: Incrementing version on folder {0}", folderID);
|
||||||
|
// Util.PrintCallStack();
|
||||||
|
|
||||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||||
{
|
{
|
||||||
dbcon.Open();
|
dbcon.Open();
|
||||||
|
@ -193,7 +261,7 @@ namespace OpenSim.Data.MySQL
|
||||||
cmd.Connection = dbcon;
|
cmd.Connection = dbcon;
|
||||||
|
|
||||||
cmd.CommandText = String.Format("update inventoryfolders set version=version+1 where folderID = ?folderID");
|
cmd.CommandText = String.Format("update inventoryfolders set version=version+1 where folderID = ?folderID");
|
||||||
cmd.Parameters.AddWithValue("?folderID", item.parentFolderID.ToString());
|
cmd.Parameters.AddWithValue("?folderID", folderID);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -205,8 +273,95 @@ namespace OpenSim.Data.MySQL
|
||||||
}
|
}
|
||||||
cmd.Dispose();
|
cmd.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
dbcon.Close();
|
dbcon.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MySqlFolderHandler : MySQLGenericTableHandler<XInventoryFolder>
|
||||||
|
{
|
||||||
|
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
public MySqlFolderHandler(string c, string t, string m) :
|
||||||
|
base(c, t, m)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool MoveFolder(string id, string newParentFolderID)
|
||||||
|
{
|
||||||
|
XInventoryFolder[] folders = Get(new string[] { "folderID" }, new string[] { id });
|
||||||
|
|
||||||
|
if (folders.Length == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
UUID oldParentFolderUUID = folders[0].parentFolderID;
|
||||||
|
|
||||||
|
using (MySqlCommand cmd = new MySqlCommand())
|
||||||
|
{
|
||||||
|
cmd.CommandText
|
||||||
|
= String.Format(
|
||||||
|
"update {0} set parentFolderID = ?ParentFolderID where folderID = ?folderID", m_Realm);
|
||||||
|
cmd.Parameters.AddWithValue("?ParentFolderID", newParentFolderID);
|
||||||
|
cmd.Parameters.AddWithValue("?folderID", id);
|
||||||
|
|
||||||
|
if (ExecuteNonQuery(cmd) == 0)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
IncrementFolderVersion(oldParentFolderUUID);
|
||||||
|
IncrementFolderVersion(newParentFolderID);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Store(XInventoryFolder folder)
|
||||||
|
{
|
||||||
|
if (!base.Store(folder))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
IncrementFolderVersion(folder.parentFolderID);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool IncrementFolderVersion(UUID folderID)
|
||||||
|
{
|
||||||
|
return IncrementFolderVersion(folderID.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool IncrementFolderVersion(string folderID)
|
||||||
|
{
|
||||||
|
// m_log.DebugFormat("[MYSQL FOLDER HANDLER]: Incrementing version on folder {0}", folderID);
|
||||||
|
// Util.PrintCallStack();
|
||||||
|
|
||||||
|
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||||
|
{
|
||||||
|
dbcon.Open();
|
||||||
|
|
||||||
|
using (MySqlCommand cmd = new MySqlCommand())
|
||||||
|
{
|
||||||
|
cmd.Connection = dbcon;
|
||||||
|
|
||||||
|
cmd.CommandText = String.Format("update inventoryfolders set version=version+1 where folderID = ?folderID");
|
||||||
|
cmd.Parameters.AddWithValue("?folderID", folderID);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
cmd.ExecuteNonQuery();
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
cmd.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
dbcon.Close();
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,9 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Threading;
|
||||||
|
using log4net;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
using OpenSim.Data;
|
using OpenSim.Data;
|
||||||
|
@ -36,12 +39,26 @@ namespace OpenSim.Data.Null
|
||||||
{
|
{
|
||||||
public class NullFriendsData : IFriendsData
|
public class NullFriendsData : IFriendsData
|
||||||
{
|
{
|
||||||
|
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
private static List<FriendsData> m_Data = new List<FriendsData>();
|
private static List<FriendsData> m_Data = new List<FriendsData>();
|
||||||
|
|
||||||
public NullFriendsData(string connectionString, string realm)
|
public NullFriendsData(string connectionString, string realm)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clear all friends data
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This is required by unit tests to clear the static data between test runs.
|
||||||
|
/// </remarks>
|
||||||
|
public static void Clear()
|
||||||
|
{
|
||||||
|
lock (m_Data)
|
||||||
|
m_Data.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
public FriendsData[] GetFriends(UUID principalID)
|
public FriendsData[] GetFriends(UUID principalID)
|
||||||
{
|
{
|
||||||
return GetFriends(principalID.ToString());
|
return GetFriends(principalID.ToString());
|
||||||
|
@ -55,6 +72,8 @@ namespace OpenSim.Data.Null
|
||||||
/// <param name="values"></param>
|
/// <param name="values"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public FriendsData[] GetFriends(string userID)
|
public FriendsData[] GetFriends(string userID)
|
||||||
|
{
|
||||||
|
lock (m_Data)
|
||||||
{
|
{
|
||||||
List<FriendsData> lst = m_Data.FindAll(fdata =>
|
List<FriendsData> lst = m_Data.FindAll(fdata =>
|
||||||
{
|
{
|
||||||
|
@ -66,11 +85,19 @@ namespace OpenSim.Data.Null
|
||||||
lst.ForEach(f =>
|
lst.ForEach(f =>
|
||||||
{
|
{
|
||||||
FriendsData f2 = m_Data.Find(candidateF2 => f.Friend == candidateF2.PrincipalID);
|
FriendsData f2 = m_Data.Find(candidateF2 => f.Friend == candidateF2.PrincipalID);
|
||||||
if (f2 != null) { f.Data["TheirFlags"] = f2.Data["Flags"]; }
|
if (f2 != null)
|
||||||
|
f.Data["TheirFlags"] = f2.Data["Flags"];
|
||||||
|
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[NULL FRIENDS DATA]: Got {0} {1} {2} for {3}",
|
||||||
|
// f.Friend, f.Data["Flags"], f2 != null ? f.Data["TheirFlags"] : "not found!", f.PrincipalID);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// m_log.DebugFormat("[NULL FRIENDS DATA]: Got {0} friends for {1}", lst.Count, userID);
|
||||||
|
|
||||||
return lst.ToArray();
|
return lst.ToArray();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return new FriendsData[0];
|
return new FriendsData[0];
|
||||||
}
|
}
|
||||||
|
@ -80,6 +107,10 @@ namespace OpenSim.Data.Null
|
||||||
if (data == null)
|
if (data == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[NULL FRIENDS DATA]: Storing {0} {1} {2}", data.PrincipalID, data.Friend, data.Data["Flags"]);
|
||||||
|
|
||||||
|
lock (m_Data)
|
||||||
m_Data.Add(data);
|
m_Data.Add(data);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -91,6 +122,8 @@ namespace OpenSim.Data.Null
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Delete(string userID, string friendID)
|
public bool Delete(string userID, string friendID)
|
||||||
|
{
|
||||||
|
lock (m_Data)
|
||||||
{
|
{
|
||||||
List<FriendsData> lst = m_Data.FindAll(delegate(FriendsData fdata) { return fdata.PrincipalID == userID.ToString(); });
|
List<FriendsData> lst = m_Data.FindAll(delegate(FriendsData fdata) { return fdata.PrincipalID == userID.ToString(); });
|
||||||
if (lst != null)
|
if (lst != null)
|
||||||
|
@ -98,10 +131,15 @@ namespace OpenSim.Data.Null
|
||||||
FriendsData friend = lst.Find(delegate(FriendsData fdata) { return fdata.Friend == friendID; });
|
FriendsData friend = lst.Find(delegate(FriendsData fdata) { return fdata.Friend == friendID; });
|
||||||
if (friendID != null)
|
if (friendID != null)
|
||||||
{
|
{
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[NULL FRIENDS DATA]: Deleting friend {0} {1} for {2}",
|
||||||
|
// friend.Friend, friend.Data["Flags"], friend.PrincipalID);
|
||||||
|
|
||||||
m_Data.Remove(friend);
|
m_Data.Remove(friend);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,7 +110,6 @@ namespace OpenSim.Data.Null
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public PresenceData[] Get(string field, string data)
|
public PresenceData[] Get(string field, string data)
|
||||||
{
|
{
|
||||||
if (Instance != this)
|
if (Instance != this)
|
||||||
|
|
|
@ -47,7 +47,7 @@ namespace OpenSim.Data.SQLite
|
||||||
{
|
{
|
||||||
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
private SQLiteGenericTableHandler<XInventoryFolder> m_Folders;
|
private SqliteFolderHandler m_Folders;
|
||||||
private SqliteItemHandler m_Items;
|
private SqliteItemHandler m_Items;
|
||||||
|
|
||||||
public SQLiteXInventoryData(string conn, string realm)
|
public SQLiteXInventoryData(string conn, string realm)
|
||||||
|
@ -55,7 +55,7 @@ namespace OpenSim.Data.SQLite
|
||||||
if (Util.IsWindows())
|
if (Util.IsWindows())
|
||||||
Util.LoadArchSpecificWindowsDll("sqlite3.dll");
|
Util.LoadArchSpecificWindowsDll("sqlite3.dll");
|
||||||
|
|
||||||
m_Folders = new SQLiteGenericTableHandler<XInventoryFolder>(
|
m_Folders = new SqliteFolderHandler(
|
||||||
conn, "inventoryfolders", "XInventoryStore");
|
conn, "inventoryfolders", "XInventoryStore");
|
||||||
m_Items = new SqliteItemHandler(
|
m_Items = new SqliteItemHandler(
|
||||||
conn, "inventoryitems", String.Empty);
|
conn, "inventoryitems", String.Empty);
|
||||||
|
@ -114,6 +114,11 @@ namespace OpenSim.Data.SQLite
|
||||||
return m_Items.MoveItem(id, newParent);
|
return m_Items.MoveItem(id, newParent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool MoveFolder(string id, string newParent)
|
||||||
|
{
|
||||||
|
return m_Folders.MoveFolder(id, newParent);
|
||||||
|
}
|
||||||
|
|
||||||
public XInventoryItem[] GetActiveGestures(UUID principalID)
|
public XInventoryItem[] GetActiveGestures(UUID principalID)
|
||||||
{
|
{
|
||||||
return m_Items.GetActiveGestures(principalID);
|
return m_Items.GetActiveGestures(principalID);
|
||||||
|
@ -177,4 +182,23 @@ namespace OpenSim.Data.SQLite
|
||||||
return perms;
|
return perms;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class SqliteFolderHandler : SQLiteGenericTableHandler<XInventoryFolder>
|
||||||
|
{
|
||||||
|
public SqliteFolderHandler(string c, string t, string m) :
|
||||||
|
base(c, t, m)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool MoveFolder(string id, string newParentFolderID)
|
||||||
|
{
|
||||||
|
SqliteCommand cmd = new SqliteCommand();
|
||||||
|
|
||||||
|
cmd.CommandText = String.Format("update {0} set parentFolderID = :ParentFolderID where folderID = :FolderID", m_Realm);
|
||||||
|
cmd.Parameters.Add(new SqliteParameter(":ParentFolderID", newParentFolderID));
|
||||||
|
cmd.Parameters.Add(new SqliteParameter(":FolderID", id));
|
||||||
|
|
||||||
|
return ExecuteNonQuery(cmd, m_Connection) == 0 ? false : true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1070,8 +1070,6 @@ namespace OpenSim.Data.Tests
|
||||||
regionInfo.RegionLocX = 0;
|
regionInfo.RegionLocX = 0;
|
||||||
regionInfo.RegionLocY = 0;
|
regionInfo.RegionLocY = 0;
|
||||||
|
|
||||||
Scene scene = new Scene(regionInfo);
|
|
||||||
|
|
||||||
SceneObjectPart sop = new SceneObjectPart();
|
SceneObjectPart sop = new SceneObjectPart();
|
||||||
sop.Name = name;
|
sop.Name = name;
|
||||||
sop.Description = name;
|
sop.Description = name;
|
||||||
|
@ -1082,7 +1080,7 @@ namespace OpenSim.Data.Tests
|
||||||
sop.Shape = PrimitiveBaseShape.Default;
|
sop.Shape = PrimitiveBaseShape.Default;
|
||||||
|
|
||||||
SceneObjectGroup sog = new SceneObjectGroup(sop);
|
SceneObjectGroup sog = new SceneObjectGroup(sop);
|
||||||
sog.SetScene(scene);
|
// sog.SetScene(scene);
|
||||||
|
|
||||||
return sog;
|
return sog;
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,6 +98,11 @@ namespace OpenSim.Framework
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string lastname;
|
public string lastname;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Agent's full name.
|
||||||
|
/// </summary>
|
||||||
|
public string Name { get { return string.Format("{0} {1}", firstname, lastname); } }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Random Unique GUID for this session. Client gets this at login and it's
|
/// Random Unique GUID for this session. Client gets this at login and it's
|
||||||
/// only supposed to be disclosed over secure channels
|
/// only supposed to be disclosed over secure channels
|
||||||
|
|
|
@ -199,7 +199,14 @@ namespace OpenSim.Framework
|
||||||
//
|
//
|
||||||
public class Cache
|
public class Cache
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Must only be accessed under lock.
|
||||||
|
/// </summary>
|
||||||
private List<CacheItemBase> m_Index = new List<CacheItemBase>();
|
private List<CacheItemBase> m_Index = new List<CacheItemBase>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Must only be accessed under m_Index lock.
|
||||||
|
/// </summary>
|
||||||
private Dictionary<string, CacheItemBase> m_Lookup =
|
private Dictionary<string, CacheItemBase> m_Lookup =
|
||||||
new Dictionary<string, CacheItemBase>();
|
new Dictionary<string, CacheItemBase>();
|
||||||
|
|
||||||
|
@ -320,7 +327,6 @@ namespace OpenSim.Framework
|
||||||
{
|
{
|
||||||
if (m_Lookup.ContainsKey(index))
|
if (m_Lookup.ContainsKey(index))
|
||||||
item = m_Lookup[index];
|
item = m_Lookup[index];
|
||||||
}
|
|
||||||
|
|
||||||
if (item == null)
|
if (item == null)
|
||||||
{
|
{
|
||||||
|
@ -332,6 +338,7 @@ namespace OpenSim.Framework
|
||||||
item.lastUsed = DateTime.Now;
|
item.lastUsed = DateTime.Now;
|
||||||
|
|
||||||
Expire(true);
|
Expire(true);
|
||||||
|
}
|
||||||
|
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
@ -385,7 +392,10 @@ namespace OpenSim.Framework
|
||||||
//
|
//
|
||||||
public Object Find(Predicate<CacheItemBase> d)
|
public Object Find(Predicate<CacheItemBase> d)
|
||||||
{
|
{
|
||||||
CacheItemBase item = m_Index.Find(d);
|
CacheItemBase item;
|
||||||
|
|
||||||
|
lock (m_Index)
|
||||||
|
item = m_Index.Find(d);
|
||||||
|
|
||||||
if (item == null)
|
if (item == null)
|
||||||
return null;
|
return null;
|
||||||
|
@ -419,12 +429,12 @@ namespace OpenSim.Framework
|
||||||
public virtual void Store(string index, Object data, Type container,
|
public virtual void Store(string index, Object data, Type container,
|
||||||
Object[] parameters)
|
Object[] parameters)
|
||||||
{
|
{
|
||||||
Expire(false);
|
|
||||||
|
|
||||||
CacheItemBase item;
|
CacheItemBase item;
|
||||||
|
|
||||||
lock (m_Index)
|
lock (m_Index)
|
||||||
{
|
{
|
||||||
|
Expire(false);
|
||||||
|
|
||||||
if (m_Index.Contains(new CacheItemBase(index)))
|
if (m_Index.Contains(new CacheItemBase(index)))
|
||||||
{
|
{
|
||||||
if ((m_Flags & CacheFlags.AllowUpdate) != 0)
|
if ((m_Flags & CacheFlags.AllowUpdate) != 0)
|
||||||
|
@ -450,9 +460,17 @@ namespace OpenSim.Framework
|
||||||
m_Index.Add(item);
|
m_Index.Add(item);
|
||||||
m_Lookup[index] = item;
|
m_Lookup[index] = item;
|
||||||
}
|
}
|
||||||
|
|
||||||
item.Store(data);
|
item.Store(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Expire items as appropriate.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Callers must lock m_Index.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name='getting'></param>
|
||||||
protected virtual void Expire(bool getting)
|
protected virtual void Expire(bool getting)
|
||||||
{
|
{
|
||||||
if (getting && (m_Strategy == CacheStrategy.Aggressive))
|
if (getting && (m_Strategy == CacheStrategy.Aggressive))
|
||||||
|
@ -479,8 +497,6 @@ namespace OpenSim.Framework
|
||||||
if (Count < Size)
|
if (Count < Size)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
lock (m_Index)
|
|
||||||
{
|
|
||||||
m_Index.Sort(new SortLRU());
|
m_Index.Sort(new SortLRU());
|
||||||
m_Index.Reverse();
|
m_Index.Reverse();
|
||||||
|
|
||||||
|
@ -513,14 +529,17 @@ namespace OpenSim.Framework
|
||||||
foreach (CacheItemBase item in m_Index)
|
foreach (CacheItemBase item in m_Index)
|
||||||
m_Lookup[item.uuid] = item;
|
m_Lookup[item.uuid] = item;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Invalidate(string uuid)
|
public void Invalidate(string uuid)
|
||||||
|
{
|
||||||
|
lock (m_Index)
|
||||||
{
|
{
|
||||||
if (!m_Lookup.ContainsKey(uuid))
|
if (!m_Lookup.ContainsKey(uuid))
|
||||||
return;
|
return;
|
||||||
|
@ -529,11 +548,15 @@ namespace OpenSim.Framework
|
||||||
m_Lookup.Remove(uuid);
|
m_Lookup.Remove(uuid);
|
||||||
m_Index.Remove(item);
|
m_Index.Remove(item);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void Clear()
|
public void Clear()
|
||||||
|
{
|
||||||
|
lock (m_Index)
|
||||||
{
|
{
|
||||||
m_Index.Clear();
|
m_Index.Clear();
|
||||||
m_Lookup.Clear();
|
m_Lookup.Clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
* 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 OpenMetaverse;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
|
||||||
|
namespace OpenSim.Framework.Client
|
||||||
|
{
|
||||||
|
public interface IClientInventory
|
||||||
|
{
|
||||||
|
void SendRemoveInventoryFolders(UUID[] folders);
|
||||||
|
void SendRemoveInventoryItems(UUID[] folders);
|
||||||
|
void SendBulkUpdateInventory(InventoryFolderBase[] folders, InventoryItemBase[] items);
|
||||||
|
}
|
||||||
|
}
|
|
@ -29,6 +29,7 @@ using System;
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
@ -40,6 +41,8 @@ namespace OpenSim.Framework.Console
|
||||||
{
|
{
|
||||||
public class Commands : ICommands
|
public class Commands : ICommands
|
||||||
{
|
{
|
||||||
|
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Encapsulates a command that can be invoked from the console
|
/// Encapsulates a command that can be invoked from the console
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -76,12 +79,23 @@ namespace OpenSim.Framework.Console
|
||||||
public List<CommandDelegate> fn;
|
public List<CommandDelegate> fn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public const string GeneralHelpText
|
||||||
|
= "To enter an argument that contains spaces, surround the argument with double quotes.\nFor example, show object name \"My long object name\"\n";
|
||||||
|
|
||||||
|
public const string ItemHelpText
|
||||||
|
= "For more information, type 'help <item>' where <item> is one of the following:";
|
||||||
|
|
||||||
/// <value>
|
/// <value>
|
||||||
/// Commands organized by keyword in a tree
|
/// Commands organized by keyword in a tree
|
||||||
/// </value>
|
/// </value>
|
||||||
private Dictionary<string, object> tree =
|
private Dictionary<string, object> tree =
|
||||||
new Dictionary<string, object>();
|
new Dictionary<string, object>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Commands organized by module
|
||||||
|
/// </summary>
|
||||||
|
private Dictionary<string, List<CommandInfo>> m_modulesCommands = new Dictionary<string, List<CommandInfo>>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get help for the given help string
|
/// Get help for the given help string
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -98,8 +112,10 @@ namespace OpenSim.Framework.Console
|
||||||
// General help
|
// General help
|
||||||
if (helpParts.Count == 0)
|
if (helpParts.Count == 0)
|
||||||
{
|
{
|
||||||
help.AddRange(CollectHelp(tree));
|
help.Add(""); // Will become a newline.
|
||||||
help.Sort();
|
help.Add(GeneralHelpText);
|
||||||
|
help.Add(ItemHelpText);
|
||||||
|
help.AddRange(CollectModulesHelp(tree));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -119,6 +135,13 @@ namespace OpenSim.Framework.Console
|
||||||
string originalHelpRequest = string.Join(" ", helpParts.ToArray());
|
string originalHelpRequest = string.Join(" ", helpParts.ToArray());
|
||||||
List<string> help = new List<string>();
|
List<string> help = new List<string>();
|
||||||
|
|
||||||
|
// Check modules first to see if we just need to display a list of those commands
|
||||||
|
if (TryCollectModuleHelp(originalHelpRequest, help))
|
||||||
|
{
|
||||||
|
help.Insert(0, ItemHelpText);
|
||||||
|
return help;
|
||||||
|
}
|
||||||
|
|
||||||
Dictionary<string, object> dict = tree;
|
Dictionary<string, object> dict = tree;
|
||||||
while (helpParts.Count > 0)
|
while (helpParts.Count > 0)
|
||||||
{
|
{
|
||||||
|
@ -161,25 +184,63 @@ namespace OpenSim.Framework.Console
|
||||||
return help;
|
return help;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<string> CollectHelp(Dictionary<string, object> dict)
|
/// <summary>
|
||||||
|
/// Try to collect help for the given module if that module exists.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="moduleName"></param>
|
||||||
|
/// <param name="helpText">/param>
|
||||||
|
/// <returns>true if there was the module existed, false otherwise.</returns>
|
||||||
|
private bool TryCollectModuleHelp(string moduleName, List<string> helpText)
|
||||||
{
|
{
|
||||||
List<string> result = new List<string>();
|
lock (m_modulesCommands)
|
||||||
|
{
|
||||||
|
foreach (string key in m_modulesCommands.Keys)
|
||||||
|
{
|
||||||
|
// Allow topic help requests to succeed whether they are upper or lowercase.
|
||||||
|
if (moduleName.ToLower() == key.ToLower())
|
||||||
|
{
|
||||||
|
List<CommandInfo> commands = m_modulesCommands[key];
|
||||||
|
var ourHelpText = commands.ConvertAll(c => string.Format("{0} - {1}", c.help_text, c.long_help));
|
||||||
|
ourHelpText.Sort();
|
||||||
|
helpText.AddRange(ourHelpText);
|
||||||
|
|
||||||
foreach (KeyValuePair<string, object> kvp in dict)
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<string> CollectModulesHelp(Dictionary<string, object> dict)
|
||||||
{
|
{
|
||||||
if (kvp.Value is Dictionary<string, Object>)
|
lock (m_modulesCommands)
|
||||||
{
|
{
|
||||||
result.AddRange(CollectHelp((Dictionary<string, Object>)kvp.Value));
|
List<string> helpText = new List<string>(m_modulesCommands.Keys);
|
||||||
}
|
helpText.Sort();
|
||||||
else
|
return helpText;
|
||||||
{
|
|
||||||
if (((CommandInfo)kvp.Value).long_help != String.Empty)
|
|
||||||
result.Add(((CommandInfo)kvp.Value).help_text+" - "+
|
|
||||||
((CommandInfo)kvp.Value).long_help);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
|
||||||
}
|
// private List<string> CollectHelp(Dictionary<string, object> dict)
|
||||||
|
// {
|
||||||
|
// List<string> result = new List<string>();
|
||||||
|
//
|
||||||
|
// foreach (KeyValuePair<string, object> kvp in dict)
|
||||||
|
// {
|
||||||
|
// if (kvp.Value is Dictionary<string, Object>)
|
||||||
|
// {
|
||||||
|
// result.AddRange(CollectHelp((Dictionary<string, Object>)kvp.Value));
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// if (((CommandInfo)kvp.Value).long_help != String.Empty)
|
||||||
|
// result.Add(((CommandInfo)kvp.Value).help_text+" - "+
|
||||||
|
// ((CommandInfo)kvp.Value).long_help);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return result;
|
||||||
|
// }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Add a command to those which can be invoked from the console.
|
/// Add a command to those which can be invoked from the console.
|
||||||
|
@ -212,21 +273,19 @@ namespace OpenSim.Framework.Console
|
||||||
|
|
||||||
Dictionary<string, Object> current = tree;
|
Dictionary<string, Object> current = tree;
|
||||||
|
|
||||||
foreach (string s in parts)
|
foreach (string part in parts)
|
||||||
{
|
{
|
||||||
if (current.ContainsKey(s))
|
if (current.ContainsKey(part))
|
||||||
{
|
{
|
||||||
if (current[s] is Dictionary<string, Object>)
|
if (current[part] is Dictionary<string, Object>)
|
||||||
{
|
current = (Dictionary<string, Object>)current[part];
|
||||||
current = (Dictionary<string, Object>)current[s];
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
current[s] = new Dictionary<string, Object>();
|
current[part] = new Dictionary<string, Object>();
|
||||||
current = (Dictionary<string, Object>)current[s];
|
current = (Dictionary<string, Object>)current[part];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,6 +309,24 @@ namespace OpenSim.Framework.Console
|
||||||
info.fn = new List<CommandDelegate>();
|
info.fn = new List<CommandDelegate>();
|
||||||
info.fn.Add(fn);
|
info.fn.Add(fn);
|
||||||
current[String.Empty] = info;
|
current[String.Empty] = info;
|
||||||
|
|
||||||
|
// Now add command to modules dictionary
|
||||||
|
lock (m_modulesCommands)
|
||||||
|
{
|
||||||
|
List<CommandInfo> commands;
|
||||||
|
if (m_modulesCommands.ContainsKey(module))
|
||||||
|
{
|
||||||
|
commands = m_modulesCommands[module];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
commands = new List<CommandInfo>();
|
||||||
|
m_modulesCommands[module] = commands;
|
||||||
|
}
|
||||||
|
|
||||||
|
// m_log.DebugFormat("[COMMAND CONSOLE]: Adding to category {0} command {1}", module, command);
|
||||||
|
commands.Add(info);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public string[] FindNextOption(string[] cmd, bool term)
|
public string[] FindNextOption(string[] cmd, bool term)
|
||||||
|
@ -607,8 +684,9 @@ namespace OpenSim.Framework.Console
|
||||||
{
|
{
|
||||||
Commands = new Commands();
|
Commands = new Commands();
|
||||||
|
|
||||||
Commands.AddCommand("console", false, "help", "help [<command>]",
|
Commands.AddCommand(
|
||||||
"Get general command list or more detailed help on a specific command", Help);
|
"Help", false, "help", "help [<item>]",
|
||||||
|
"Display help on a particular command or on a list of commands in a category", Help);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Help(string module, string[] cmd)
|
private void Help(string module, string[] cmd)
|
||||||
|
|
|
@ -0,0 +1,112 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSimulator Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace OpenSim.Framework.Console
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Used to generated a formatted table for the console.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Currently subject to change. If you use this, be prepared to change your code when this class changes.
|
||||||
|
/// </remarks>
|
||||||
|
public class ConsoleDisplayList
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The default divider between key and value for a list item.
|
||||||
|
/// </summary>
|
||||||
|
public const string DefaultKeyValueDivider = " : ";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The divider used between key and value for a list item.
|
||||||
|
/// </summary>
|
||||||
|
public string KeyValueDivider { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Table rows
|
||||||
|
/// </summary>
|
||||||
|
public List<KeyValuePair<string, string>> Rows { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Number of spaces to indent the list.
|
||||||
|
/// </summary>
|
||||||
|
public int Indent { get; set; }
|
||||||
|
|
||||||
|
public ConsoleDisplayList()
|
||||||
|
{
|
||||||
|
Rows = new List<KeyValuePair<string, string>>();
|
||||||
|
KeyValueDivider = DefaultKeyValueDivider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
AddToStringBuilder(sb);
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddToStringBuilder(StringBuilder sb)
|
||||||
|
{
|
||||||
|
string formatString = GetFormatString();
|
||||||
|
// System.Console.WriteLine("FORMAT STRING [{0}]", formatString);
|
||||||
|
|
||||||
|
// rows
|
||||||
|
foreach (KeyValuePair<string, string> row in Rows)
|
||||||
|
sb.AppendFormat(formatString, row.Key, row.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the format string for the table.
|
||||||
|
/// </summary>
|
||||||
|
private string GetFormatString()
|
||||||
|
{
|
||||||
|
StringBuilder formatSb = new StringBuilder();
|
||||||
|
|
||||||
|
int longestKey = -1;
|
||||||
|
|
||||||
|
foreach (KeyValuePair<string, string> row in Rows)
|
||||||
|
if (row.Key.Length > longestKey)
|
||||||
|
longestKey = row.Key.Length;
|
||||||
|
|
||||||
|
formatSb.Append(' ', Indent);
|
||||||
|
|
||||||
|
// Can only do left formatting for now
|
||||||
|
formatSb.AppendFormat("{{0,-{0}}}{1}{{1}}\n", longestKey, KeyValueDivider);
|
||||||
|
|
||||||
|
return formatSb.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddRow(object key, object value)
|
||||||
|
{
|
||||||
|
Rows.Add(new KeyValuePair<string, string>(key.ToString(), value.ToString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,154 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSimulator Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace OpenSim.Framework.Console
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Used to generated a formatted table for the console.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Currently subject to change. If you use this, be prepared to change your code when this class changes.
|
||||||
|
/// </remarks>
|
||||||
|
public class ConsoleDisplayTable
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Default number of spaces between table columns.
|
||||||
|
/// </summary>
|
||||||
|
public const int DefaultTableSpacing = 2;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Table columns.
|
||||||
|
/// </summary>
|
||||||
|
public List<ConsoleDisplayTableColumn> Columns { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Table rows
|
||||||
|
/// </summary>
|
||||||
|
public List<ConsoleDisplayTableRow> Rows { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Number of spaces to indent the table.
|
||||||
|
/// </summary>
|
||||||
|
public int Indent { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Spacing between table columns
|
||||||
|
/// </summary>
|
||||||
|
public int TableSpacing { get; set; }
|
||||||
|
|
||||||
|
public ConsoleDisplayTable()
|
||||||
|
{
|
||||||
|
TableSpacing = DefaultTableSpacing;
|
||||||
|
Columns = new List<ConsoleDisplayTableColumn>();
|
||||||
|
Rows = new List<ConsoleDisplayTableRow>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
AddToStringBuilder(sb);
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddColumn(string name, int width)
|
||||||
|
{
|
||||||
|
Columns.Add(new ConsoleDisplayTableColumn(name, width));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddRow(params string[] cells)
|
||||||
|
{
|
||||||
|
Rows.Add(new ConsoleDisplayTableRow(cells));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddToStringBuilder(StringBuilder sb)
|
||||||
|
{
|
||||||
|
string formatString = GetFormatString();
|
||||||
|
// System.Console.WriteLine("FORMAT STRING [{0}]", formatString);
|
||||||
|
|
||||||
|
// columns
|
||||||
|
sb.AppendFormat(formatString, Columns.ConvertAll(c => c.Header).ToArray());
|
||||||
|
|
||||||
|
// rows
|
||||||
|
foreach (ConsoleDisplayTableRow row in Rows)
|
||||||
|
sb.AppendFormat(formatString, row.Cells.ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the format string for the table.
|
||||||
|
/// </summary>
|
||||||
|
private string GetFormatString()
|
||||||
|
{
|
||||||
|
StringBuilder formatSb = new StringBuilder();
|
||||||
|
|
||||||
|
formatSb.Append(' ', Indent);
|
||||||
|
|
||||||
|
for (int i = 0; i < Columns.Count; i++)
|
||||||
|
{
|
||||||
|
formatSb.Append(' ', TableSpacing);
|
||||||
|
|
||||||
|
// Can only do left formatting for now
|
||||||
|
formatSb.AppendFormat("{{{0},-{1}}}", i, Columns[i].Width);
|
||||||
|
}
|
||||||
|
|
||||||
|
formatSb.Append('\n');
|
||||||
|
|
||||||
|
return formatSb.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct ConsoleDisplayTableColumn
|
||||||
|
{
|
||||||
|
public string Header { get; set; }
|
||||||
|
public int Width { get; set; }
|
||||||
|
|
||||||
|
public ConsoleDisplayTableColumn(string header, int width) : this()
|
||||||
|
{
|
||||||
|
Header = header;
|
||||||
|
Width = width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct ConsoleDisplayTableRow
|
||||||
|
{
|
||||||
|
public List<string> Cells { get; private set; }
|
||||||
|
|
||||||
|
public ConsoleDisplayTableRow(List<string> cells) : this()
|
||||||
|
{
|
||||||
|
Cells = cells;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConsoleDisplayTableRow(params string[] cells) : this()
|
||||||
|
{
|
||||||
|
Cells = new List<string>(cells);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -29,6 +29,7 @@ using System;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Xml;
|
||||||
|
|
||||||
namespace OpenSim.Framework.Console
|
namespace OpenSim.Framework.Console
|
||||||
{
|
{
|
||||||
|
@ -37,28 +38,42 @@ namespace OpenSim.Framework.Console
|
||||||
/// Don't use this except for Unit Testing or you're in for a world of hurt when the
|
/// Don't use this except for Unit Testing or you're in for a world of hurt when the
|
||||||
/// sim gets to ReadLine
|
/// sim gets to ReadLine
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class MockConsole : CommandConsole
|
public class MockConsole : ICommandConsole
|
||||||
{
|
|
||||||
public MockConsole(string defaultPrompt) : base(defaultPrompt)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
public override void Output(string text)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
public override void Output(string text, string level)
|
|
||||||
{
|
{
|
||||||
|
private MockCommands m_commands = new MockCommands();
|
||||||
|
|
||||||
|
public ICommands Commands { get { return m_commands; } }
|
||||||
|
|
||||||
|
public void Prompt() {}
|
||||||
|
|
||||||
|
public void RunCommand(string cmd) {}
|
||||||
|
|
||||||
|
public string ReadLine(string p, bool isCommand, bool e) { return ""; }
|
||||||
|
|
||||||
|
public object ConsoleScene { get { return null; } }
|
||||||
|
|
||||||
|
public void Output(string text, string level) {}
|
||||||
|
public void Output(string text) {}
|
||||||
|
public void OutputFormat(string format, params object[] components) {}
|
||||||
|
|
||||||
|
public string CmdPrompt(string p) { return ""; }
|
||||||
|
public string CmdPrompt(string p, string def) { return ""; }
|
||||||
|
public string CmdPrompt(string p, List<char> excludedCharacters) { return ""; }
|
||||||
|
public string CmdPrompt(string p, string def, List<char> excludedCharacters) { return ""; }
|
||||||
|
|
||||||
|
public string CmdPrompt(string prompt, string defaultresponse, List<string> options) { return ""; }
|
||||||
|
|
||||||
|
public string PasswdPrompt(string p) { return ""; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ReadLine(string p, bool isCommand, bool e)
|
public class MockCommands : ICommands
|
||||||
{
|
|
||||||
//Thread.CurrentThread.Join(1000);
|
|
||||||
return string.Empty;
|
|
||||||
}
|
|
||||||
public override void UnlockOutput()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
public override void LockOutput()
|
|
||||||
{
|
{
|
||||||
}
|
public void FromXml(XmlElement root, CommandDelegate fn) {}
|
||||||
|
public List<string> GetHelp(string[] cmd) { return null; }
|
||||||
|
public void AddCommand(string module, bool shared, string command, string help, string longhelp, CommandDelegate fn) {}
|
||||||
|
public void AddCommand(string module, bool shared, string command, string help, string longhelp, string descriptivehelp, CommandDelegate fn) {}
|
||||||
|
public string[] FindNextOption(string[] cmd, bool term) { return null; }
|
||||||
|
public string[] Resolve(string[] cmd) { return null; }
|
||||||
|
public XmlElement GetXml(XmlDocument doc) { return null; }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
/*
|
||||||
|
* 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.Reflection;
|
||||||
|
using log4net;
|
||||||
|
|
||||||
|
public class GcNotify
|
||||||
|
{
|
||||||
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
public static bool Enabled
|
||||||
|
{
|
||||||
|
get { return s_initialized; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (!s_initialized && value)
|
||||||
|
new GcNotify();
|
||||||
|
|
||||||
|
s_initialized = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool s_initialized = false;
|
||||||
|
|
||||||
|
private GcNotify() {}
|
||||||
|
|
||||||
|
~GcNotify()
|
||||||
|
{
|
||||||
|
if (!Environment.HasShutdownStarted && !AppDomain.CurrentDomain.IsFinalizingForUnload())
|
||||||
|
{
|
||||||
|
m_log.DebugFormat("[GC NOTIFY]: Garbage collection triggered.");
|
||||||
|
|
||||||
|
if (Enabled)
|
||||||
|
new GcNotify();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -296,9 +296,9 @@ namespace OpenSim.Framework
|
||||||
public delegate void ConfirmXfer(IClientAPI remoteClient, ulong xferID, uint packetID);
|
public delegate void ConfirmXfer(IClientAPI remoteClient, ulong xferID, uint packetID);
|
||||||
|
|
||||||
public delegate void FriendActionDelegate(
|
public delegate void FriendActionDelegate(
|
||||||
IClientAPI remoteClient, UUID agentID, UUID transactionID, List<UUID> callingCardFolders);
|
IClientAPI remoteClient, UUID transactionID, List<UUID> callingCardFolders);
|
||||||
|
|
||||||
public delegate void FriendshipTermination(IClientAPI remoteClient, UUID agentID, UUID ExID);
|
public delegate void FriendshipTermination(IClientAPI remoteClient, UUID ExID);
|
||||||
|
|
||||||
public delegate void MoneyTransferRequest(
|
public delegate void MoneyTransferRequest(
|
||||||
UUID sourceID, UUID destID, int amount, int transactionType, string description);
|
UUID sourceID, UUID destID, int amount, int transactionType, string description);
|
||||||
|
@ -458,7 +458,7 @@ namespace OpenSim.Framework
|
||||||
public delegate void AvatarNotesUpdate(IClientAPI client, UUID targetID, string notes);
|
public delegate void AvatarNotesUpdate(IClientAPI client, UUID targetID, string notes);
|
||||||
public delegate void MuteListRequest(IClientAPI client, uint muteCRC);
|
public delegate void MuteListRequest(IClientAPI client, uint muteCRC);
|
||||||
public delegate void AvatarInterestUpdate(IClientAPI client, uint wantmask, string wanttext, uint skillsmask, string skillstext, string languages);
|
public delegate void AvatarInterestUpdate(IClientAPI client, uint wantmask, string wanttext, uint skillsmask, string skillstext, string languages);
|
||||||
public delegate void GrantUserFriendRights(IClientAPI client, UUID requester, UUID target, int rights);
|
public delegate void GrantUserFriendRights(IClientAPI client, UUID target, int rights);
|
||||||
public delegate void PlacesQuery(UUID QueryID, UUID TransactionID, string QueryText, uint QueryFlags, byte Category, string SimName, IClientAPI client);
|
public delegate void PlacesQuery(UUID QueryID, UUID TransactionID, string QueryText, uint QueryFlags, byte Category, string SimName, IClientAPI client);
|
||||||
|
|
||||||
public delegate void AgentFOV(IClientAPI client, float verticalAngle);
|
public delegate void AgentFOV(IClientAPI client, float verticalAngle);
|
||||||
|
@ -710,7 +710,7 @@ namespace OpenSim.Framework
|
||||||
/// The scene agent for this client. This will only be set if the client has an agent in a scene (i.e. if it
|
/// 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).
|
/// is connected).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
ISceneAgent SceneAgent { get; }
|
ISceneAgent SceneAgent { get; set; }
|
||||||
|
|
||||||
UUID SessionId { get; }
|
UUID SessionId { get; }
|
||||||
|
|
||||||
|
@ -740,14 +740,21 @@ namespace OpenSim.Framework
|
||||||
/// </summary>
|
/// </summary>
|
||||||
string Name { get; }
|
string Name { get; }
|
||||||
|
|
||||||
/// <value>
|
/// <summary>
|
||||||
/// Determines whether the client thread is doing anything or not.
|
/// True if the client is active (sending and receiving new UDP messages). False if the client is being closed.
|
||||||
/// </value>
|
/// </summary>
|
||||||
bool IsActive { get; set; }
|
bool IsActive { get; set; }
|
||||||
|
|
||||||
/// <value>
|
/// <summary>
|
||||||
/// Determines whether the client is or has been removed from a given scene
|
/// Set if the client is closing due to a logout request
|
||||||
/// </value>
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Do not use this flag if you want to know if the client is closing, since it will not be set in other
|
||||||
|
/// circumstances (e.g. if a child agent is closed or the agent is kicked off the simulator). Use IsActive
|
||||||
|
/// instead with a IClientAPI.SceneAgent.IsChildAgent check if necessary.
|
||||||
|
///
|
||||||
|
/// Only set for root agents.
|
||||||
|
/// </remarks>
|
||||||
bool IsLoggingOut { get; set; }
|
bool IsLoggingOut { get; set; }
|
||||||
|
|
||||||
bool SendLogoutPacketWhenClosing { set; }
|
bool SendLogoutPacketWhenClosing { set; }
|
||||||
|
@ -1026,7 +1033,21 @@ namespace OpenSim.Framework
|
||||||
|
|
||||||
void InPacket(object NewPack);
|
void InPacket(object NewPack);
|
||||||
void ProcessInPacket(Packet NewPack);
|
void ProcessInPacket(Packet NewPack);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Close this client
|
||||||
|
/// </summary>
|
||||||
void Close();
|
void Close();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Close this client
|
||||||
|
/// </summary>
|
||||||
|
/// <param name='force'>
|
||||||
|
/// If true, attempts the close without checking active status. You do not want to try this except as a last
|
||||||
|
/// ditch attempt where Active == false but the ScenePresence still exists.
|
||||||
|
/// </param>
|
||||||
|
void Close(bool force);
|
||||||
|
|
||||||
void Kick(string message);
|
void Kick(string message);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -1347,7 +1368,6 @@ namespace OpenSim.Framework
|
||||||
void SendBlueBoxMessage(UUID FromAvatarID, String FromAvatarName, String Message);
|
void SendBlueBoxMessage(UUID FromAvatarID, String FromAvatarName, String Message);
|
||||||
|
|
||||||
void SendLogoutPacket();
|
void SendLogoutPacket();
|
||||||
EndPoint GetClientEP();
|
|
||||||
|
|
||||||
// WARNING WARNING WARNING
|
// WARNING WARNING WARNING
|
||||||
//
|
//
|
||||||
|
@ -1408,8 +1428,6 @@ namespace OpenSim.Framework
|
||||||
|
|
||||||
void SendGroupVoteHistory(UUID groupID, UUID transactionID, GroupVoteHistory[] Votes);
|
void SendGroupVoteHistory(UUID groupID, UUID transactionID, GroupVoteHistory[] Votes);
|
||||||
|
|
||||||
void KillEndDone();
|
|
||||||
|
|
||||||
bool AddGenericPacketHandler(string MethodName, GenericMessage handler);
|
bool AddGenericPacketHandler(string MethodName, GenericMessage handler);
|
||||||
|
|
||||||
void SendRebakeAvatarTextures(UUID textureID);
|
void SendRebakeAvatarTextures(UUID textureID);
|
||||||
|
|
|
@ -40,7 +40,7 @@ namespace OpenSim.Framework
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get help for the given help string
|
/// Get help for the given help string
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="helpParts">Parsed parts of the help string. If empty then general help is returned.</param>
|
/// <param name="cmd">Parsed parts of the help string. If empty then general help is returned.</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
List<string> GetHelp(string[] cmd);
|
List<string> GetHelp(string[] cmd);
|
||||||
|
|
||||||
|
|
|
@ -71,6 +71,7 @@ namespace OpenSim.Framework
|
||||||
bool IsEitherBannedOrRestricted(UUID avatar);
|
bool IsEitherBannedOrRestricted(UUID avatar);
|
||||||
bool IsBannedFromLand(UUID avatar);
|
bool IsBannedFromLand(UUID avatar);
|
||||||
bool IsRestrictedFromLand(UUID avatar);
|
bool IsRestrictedFromLand(UUID avatar);
|
||||||
|
bool IsInLandAccessList(UUID avatar);
|
||||||
void SendLandUpdateToClient(IClientAPI remote_client);
|
void SendLandUpdateToClient(IClientAPI remote_client);
|
||||||
void SendLandUpdateToClient(bool snap_selection, IClientAPI remote_client);
|
void SendLandUpdateToClient(bool snap_selection, IClientAPI remote_client);
|
||||||
List<LandAccessEntry> CreateAccessListArrayByFlag(AccessList flag);
|
List<LandAccessEntry> CreateAccessListArrayByFlag(AccessList flag);
|
||||||
|
|
|
@ -56,11 +56,29 @@ namespace OpenSim.Framework
|
||||||
|
|
||||||
public interface IScene
|
public interface IScene
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The name of this scene.
|
||||||
|
/// </summary>
|
||||||
|
string Name { get; }
|
||||||
|
|
||||||
RegionInfo RegionInfo { get; }
|
RegionInfo RegionInfo { get; }
|
||||||
RegionStatus RegionStatus { get; set; }
|
RegionStatus RegionStatus { get; set; }
|
||||||
|
|
||||||
IConfigSource Config { get; }
|
IConfigSource Config { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Are logins enabled on this simulator?
|
||||||
|
/// </summary>
|
||||||
|
bool LoginsEnabled { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Is this region ready for use?
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This does not mean that logins are enabled, merely that they can be.
|
||||||
|
/// </remarks>
|
||||||
|
bool Ready { get; set; }
|
||||||
|
|
||||||
float TimeDilation { get; }
|
float TimeDilation { get; }
|
||||||
|
|
||||||
bool AllowScriptCrossings { get; }
|
bool AllowScriptCrossings { get; }
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using OpenMetaverse;
|
||||||
|
|
||||||
namespace OpenSim.Framework
|
namespace OpenSim.Framework
|
||||||
{
|
{
|
||||||
|
@ -71,5 +72,11 @@ namespace OpenSim.Framework
|
||||||
/// This includes scene object data and the appearance data of other avatars.
|
/// This includes scene object data and the appearance data of other avatars.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
void SendInitialDataToMe();
|
void SendInitialDataToMe();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Direction in which the scene presence is looking.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>Will be Vector3.Zero for a child agent.</remarks>
|
||||||
|
Vector3 Lookat { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -69,7 +69,7 @@ namespace OpenSim.Framework
|
||||||
(uint) ParcelFlags.AllowAPrimitiveEntry |
|
(uint) ParcelFlags.AllowAPrimitiveEntry |
|
||||||
(uint) ParcelFlags.AllowDeedToGroup | (uint) ParcelFlags.AllowTerraform |
|
(uint) ParcelFlags.AllowDeedToGroup | (uint) ParcelFlags.AllowTerraform |
|
||||||
(uint) ParcelFlags.CreateObjects | (uint) ParcelFlags.AllowOtherScripts |
|
(uint) ParcelFlags.CreateObjects | (uint) ParcelFlags.AllowOtherScripts |
|
||||||
(uint) ParcelFlags.SoundLocal;
|
(uint) ParcelFlags.SoundLocal | (uint) ParcelFlags.AllowVoiceChat;
|
||||||
|
|
||||||
private byte _landingType = 0;
|
private byte _landingType = 0;
|
||||||
private string _name = "Your Parcel";
|
private string _name = "Your Parcel";
|
||||||
|
|
|
@ -101,6 +101,11 @@ namespace OpenSim.Framework
|
||||||
{
|
{
|
||||||
item = oldHeadNext.Item;
|
item = oldHeadNext.Item;
|
||||||
haveAdvancedHead = CAS(ref head, oldHead, oldHeadNext);
|
haveAdvancedHead = CAS(ref head, oldHead, oldHeadNext);
|
||||||
|
if (haveAdvancedHead)
|
||||||
|
{
|
||||||
|
oldHeadNext.Item = default(T);
|
||||||
|
oldHead.Next = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -111,6 +116,10 @@ namespace OpenSim.Framework
|
||||||
|
|
||||||
public void Clear()
|
public void Clear()
|
||||||
{
|
{
|
||||||
|
// ugly
|
||||||
|
T item;
|
||||||
|
while(count > 0)
|
||||||
|
Dequeue(out item);
|
||||||
Init();
|
Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,129 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSimulator Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Threading;
|
||||||
|
using log4net;
|
||||||
|
|
||||||
|
namespace OpenSim.Framework
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Experimental watchdog for memory usage.
|
||||||
|
/// </summary>
|
||||||
|
public static class MemoryWatchdog
|
||||||
|
{
|
||||||
|
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Is this watchdog active?
|
||||||
|
/// </summary>
|
||||||
|
public static bool Enabled
|
||||||
|
{
|
||||||
|
get { return m_enabled; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
// m_log.DebugFormat("[MEMORY WATCHDOG]: Setting MemoryWatchdog.Enabled to {0}", value);
|
||||||
|
|
||||||
|
if (value && !m_enabled)
|
||||||
|
UpdateLastRecord(GC.GetTotalMemory(false), Util.EnvironmentTickCount());
|
||||||
|
|
||||||
|
m_enabled = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private static bool m_enabled;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Average memory churn in bytes per millisecond.
|
||||||
|
/// </summary>
|
||||||
|
public static double AverageMemoryChurn
|
||||||
|
{
|
||||||
|
get { if (m_samples.Count > 0) return m_samples.Average(); else return 0; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Maximum number of statistical samples.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// At the moment this corresponds to 1 minute since the sampling rate is every 2.5 seconds as triggered from
|
||||||
|
/// the main Watchdog.
|
||||||
|
/// </remarks>
|
||||||
|
private static int m_maxSamples = 24;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Time when the watchdog was last updated.
|
||||||
|
/// </summary>
|
||||||
|
private static int m_lastUpdateTick;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Memory used at time of last watchdog update.
|
||||||
|
/// </summary>
|
||||||
|
private static long m_lastUpdateMemory;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Memory churn rate per millisecond.
|
||||||
|
/// </summary>
|
||||||
|
private static double m_churnRatePerMillisecond;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Historical samples for calculating moving average.
|
||||||
|
/// </summary>
|
||||||
|
private static Queue<double> m_samples = new Queue<double>(m_maxSamples);
|
||||||
|
|
||||||
|
public static void Update()
|
||||||
|
{
|
||||||
|
int now = Util.EnvironmentTickCount();
|
||||||
|
long memoryNow = GC.GetTotalMemory(false);
|
||||||
|
long memoryDiff = memoryNow - m_lastUpdateMemory;
|
||||||
|
|
||||||
|
if (memoryDiff >= 0)
|
||||||
|
{
|
||||||
|
if (m_samples.Count >= m_maxSamples)
|
||||||
|
m_samples.Dequeue();
|
||||||
|
|
||||||
|
double elapsed = Util.EnvironmentTickCountSubtract(now, m_lastUpdateTick);
|
||||||
|
|
||||||
|
// This should never happen since it's not useful for updates to occur with no time elapsed, but
|
||||||
|
// protect ourselves from a divide-by-zero just in case.
|
||||||
|
if (elapsed == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_samples.Enqueue(memoryDiff / (double)elapsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateLastRecord(memoryNow, now);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void UpdateLastRecord(long memoryNow, int timeNow)
|
||||||
|
{
|
||||||
|
m_lastUpdateMemory = memoryNow;
|
||||||
|
m_lastUpdateTick = timeNow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -63,12 +63,15 @@ namespace OpenSim.Framework
|
||||||
|
|
||||||
internal void Clear()
|
internal void Clear()
|
||||||
{
|
{
|
||||||
this.value = default(T);
|
|
||||||
if (this.handle != null)
|
if (this.handle != null)
|
||||||
{
|
|
||||||
this.handle.Clear();
|
this.handle.Clear();
|
||||||
this.handle = null;
|
ClearRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal void ClearRef()
|
||||||
|
{
|
||||||
|
this.value = default(T);
|
||||||
|
this.handle = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -285,6 +288,7 @@ namespace OpenSim.Framework
|
||||||
if (--this.size > 0 && index != this.size)
|
if (--this.size > 0 && index != this.size)
|
||||||
{
|
{
|
||||||
Set(this.items[this.size], index);
|
Set(this.items[this.size], index);
|
||||||
|
this.items[this.size].ClearRef();
|
||||||
if (!BubbleUp(index))
|
if (!BubbleUp(index))
|
||||||
BubbleDown(index);
|
BubbleDown(index);
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,8 +44,6 @@ namespace OpenSim.Framework.Serialization.External
|
||||||
{
|
{
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
protected static UTF8Encoding m_utf8Encoding = new UTF8Encoding();
|
|
||||||
|
|
||||||
private static Dictionary<string, Action<LandData, XmlTextReader>> m_ldProcessors
|
private static Dictionary<string, Action<LandData, XmlTextReader>> m_ldProcessors
|
||||||
= new Dictionary<string, Action<LandData, XmlTextReader>>();
|
= new Dictionary<string, Action<LandData, XmlTextReader>>();
|
||||||
|
|
||||||
|
@ -163,7 +161,7 @@ namespace OpenSim.Framework.Serialization.External
|
||||||
/// <exception cref="System.Xml.XmlException"></exception>
|
/// <exception cref="System.Xml.XmlException"></exception>
|
||||||
public static LandData Deserialize(byte[] serializedLandData)
|
public static LandData Deserialize(byte[] serializedLandData)
|
||||||
{
|
{
|
||||||
return Deserialize(m_utf8Encoding.GetString(serializedLandData, 0, serializedLandData.Length));
|
return Deserialize(Encoding.UTF8.GetString(serializedLandData, 0, serializedLandData.Length));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -38,8 +38,6 @@ namespace OpenSim.Framework.Serialization.External
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class RegionSettingsSerializer
|
public class RegionSettingsSerializer
|
||||||
{
|
{
|
||||||
protected static ASCIIEncoding m_asciiEncoding = new ASCIIEncoding();
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Deserialize settings
|
/// Deserialize settings
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -48,7 +46,7 @@ namespace OpenSim.Framework.Serialization.External
|
||||||
/// <exception cref="System.Xml.XmlException"></exception>
|
/// <exception cref="System.Xml.XmlException"></exception>
|
||||||
public static RegionSettings Deserialize(byte[] serializedSettings)
|
public static RegionSettings Deserialize(byte[] serializedSettings)
|
||||||
{
|
{
|
||||||
return Deserialize(m_asciiEncoding.GetString(serializedSettings, 0, serializedSettings.Length));
|
return Deserialize(Encoding.ASCII.GetString(serializedSettings, 0, serializedSettings.Length));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -53,8 +53,6 @@ namespace OpenSim.Framework.Serialization
|
||||||
TYPE_CONTIGUOUS_FILE = 8,
|
TYPE_CONTIGUOUS_FILE = 8,
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static ASCIIEncoding m_asciiEncoding = new ASCIIEncoding();
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Binary reader for the underlying stream
|
/// Binary reader for the underlying stream
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -120,13 +118,13 @@ namespace OpenSim.Framework.Serialization
|
||||||
if (header[156] == (byte)'L')
|
if (header[156] == (byte)'L')
|
||||||
{
|
{
|
||||||
int longNameLength = ConvertOctalBytesToDecimal(header, 124, 11);
|
int longNameLength = ConvertOctalBytesToDecimal(header, 124, 11);
|
||||||
tarHeader.FilePath = m_asciiEncoding.GetString(ReadData(longNameLength));
|
tarHeader.FilePath = Encoding.ASCII.GetString(ReadData(longNameLength));
|
||||||
//m_log.DebugFormat("[TAR ARCHIVE READER]: Got long file name {0}", tarHeader.FilePath);
|
//m_log.DebugFormat("[TAR ARCHIVE READER]: Got long file name {0}", tarHeader.FilePath);
|
||||||
header = m_br.ReadBytes(512);
|
header = m_br.ReadBytes(512);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tarHeader.FilePath = m_asciiEncoding.GetString(header, 0, 100);
|
tarHeader.FilePath = Encoding.ASCII.GetString(header, 0, 100);
|
||||||
tarHeader.FilePath = tarHeader.FilePath.Trim(m_nullCharArray);
|
tarHeader.FilePath = tarHeader.FilePath.Trim(m_nullCharArray);
|
||||||
//m_log.DebugFormat("[TAR ARCHIVE READER]: Got short file name {0}", tarHeader.FilePath);
|
//m_log.DebugFormat("[TAR ARCHIVE READER]: Got short file name {0}", tarHeader.FilePath);
|
||||||
}
|
}
|
||||||
|
@ -205,7 +203,7 @@ namespace OpenSim.Framework.Serialization
|
||||||
{
|
{
|
||||||
// Trim leading white space: ancient tars do that instead
|
// Trim leading white space: ancient tars do that instead
|
||||||
// of leading 0s :-( don't ask. really.
|
// of leading 0s :-( don't ask. really.
|
||||||
string oString = m_asciiEncoding.GetString(bytes, startIndex, count).TrimStart(m_spaceCharArray);
|
string oString = Encoding.ASCII.GetString(bytes, startIndex, count).TrimStart(m_spaceCharArray);
|
||||||
|
|
||||||
int d = 0;
|
int d = 0;
|
||||||
|
|
||||||
|
|
|
@ -41,9 +41,6 @@ namespace OpenSim.Framework.Serialization
|
||||||
{
|
{
|
||||||
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
protected static ASCIIEncoding m_asciiEncoding = new ASCIIEncoding();
|
|
||||||
protected static UTF8Encoding m_utf8Encoding = new UTF8Encoding();
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Binary writer for the underlying stream
|
/// Binary writer for the underlying stream
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -74,7 +71,7 @@ namespace OpenSim.Framework.Serialization
|
||||||
/// <param name="data"></param>
|
/// <param name="data"></param>
|
||||||
public void WriteFile(string filePath, string data)
|
public void WriteFile(string filePath, string data)
|
||||||
{
|
{
|
||||||
WriteFile(filePath, m_utf8Encoding.GetBytes(data));
|
WriteFile(filePath, Util.UTF8NoBomEncoding.GetBytes(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -85,7 +82,7 @@ namespace OpenSim.Framework.Serialization
|
||||||
public void WriteFile(string filePath, byte[] data)
|
public void WriteFile(string filePath, byte[] data)
|
||||||
{
|
{
|
||||||
if (filePath.Length > 100)
|
if (filePath.Length > 100)
|
||||||
WriteEntry("././@LongLink", m_asciiEncoding.GetBytes(filePath), 'L');
|
WriteEntry("././@LongLink", Encoding.ASCII.GetBytes(filePath), 'L');
|
||||||
|
|
||||||
char fileType;
|
char fileType;
|
||||||
|
|
||||||
|
@ -137,7 +134,7 @@ namespace OpenSim.Framework.Serialization
|
||||||
oString = "0" + oString;
|
oString = "0" + oString;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] oBytes = m_asciiEncoding.GetBytes(oString);
|
byte[] oBytes = Encoding.ASCII.GetBytes(oString);
|
||||||
|
|
||||||
return oBytes;
|
return oBytes;
|
||||||
}
|
}
|
||||||
|
@ -156,20 +153,20 @@ namespace OpenSim.Framework.Serialization
|
||||||
byte[] header = new byte[512];
|
byte[] header = new byte[512];
|
||||||
|
|
||||||
// file path field (100)
|
// file path field (100)
|
||||||
byte[] nameBytes = m_asciiEncoding.GetBytes(filePath);
|
byte[] nameBytes = Encoding.ASCII.GetBytes(filePath);
|
||||||
int nameSize = (nameBytes.Length >= 100) ? 100 : nameBytes.Length;
|
int nameSize = (nameBytes.Length >= 100) ? 100 : nameBytes.Length;
|
||||||
Array.Copy(nameBytes, header, nameSize);
|
Array.Copy(nameBytes, header, nameSize);
|
||||||
|
|
||||||
// file mode (8)
|
// file mode (8)
|
||||||
byte[] modeBytes = m_asciiEncoding.GetBytes("0000777");
|
byte[] modeBytes = Encoding.ASCII.GetBytes("0000777");
|
||||||
Array.Copy(modeBytes, 0, header, 100, 7);
|
Array.Copy(modeBytes, 0, header, 100, 7);
|
||||||
|
|
||||||
// owner user id (8)
|
// owner user id (8)
|
||||||
byte[] ownerIdBytes = m_asciiEncoding.GetBytes("0000764");
|
byte[] ownerIdBytes = Encoding.ASCII.GetBytes("0000764");
|
||||||
Array.Copy(ownerIdBytes, 0, header, 108, 7);
|
Array.Copy(ownerIdBytes, 0, header, 108, 7);
|
||||||
|
|
||||||
// group user id (8)
|
// group user id (8)
|
||||||
byte[] groupIdBytes = m_asciiEncoding.GetBytes("0000764");
|
byte[] groupIdBytes = Encoding.ASCII.GetBytes("0000764");
|
||||||
Array.Copy(groupIdBytes, 0, header, 116, 7);
|
Array.Copy(groupIdBytes, 0, header, 116, 7);
|
||||||
|
|
||||||
// file size in bytes (12)
|
// file size in bytes (12)
|
||||||
|
@ -181,17 +178,17 @@ namespace OpenSim.Framework.Serialization
|
||||||
Array.Copy(fileSizeBytes, 0, header, 124, 11);
|
Array.Copy(fileSizeBytes, 0, header, 124, 11);
|
||||||
|
|
||||||
// last modification time (12)
|
// last modification time (12)
|
||||||
byte[] lastModTimeBytes = m_asciiEncoding.GetBytes("11017037332");
|
byte[] lastModTimeBytes = Encoding.ASCII.GetBytes("11017037332");
|
||||||
Array.Copy(lastModTimeBytes, 0, header, 136, 11);
|
Array.Copy(lastModTimeBytes, 0, header, 136, 11);
|
||||||
|
|
||||||
// entry type indicator (1)
|
// entry type indicator (1)
|
||||||
header[156] = m_asciiEncoding.GetBytes(new char[] { fileType })[0];
|
header[156] = Encoding.ASCII.GetBytes(new char[] { fileType })[0];
|
||||||
|
|
||||||
Array.Copy(m_asciiEncoding.GetBytes("0000000"), 0, header, 329, 7);
|
Array.Copy(Encoding.ASCII.GetBytes("0000000"), 0, header, 329, 7);
|
||||||
Array.Copy(m_asciiEncoding.GetBytes("0000000"), 0, header, 337, 7);
|
Array.Copy(Encoding.ASCII.GetBytes("0000000"), 0, header, 337, 7);
|
||||||
|
|
||||||
// check sum for header block (8) [calculated last]
|
// check sum for header block (8) [calculated last]
|
||||||
Array.Copy(m_asciiEncoding.GetBytes(" "), 0, header, 148, 8);
|
Array.Copy(Encoding.ASCII.GetBytes(" "), 0, header, 148, 8);
|
||||||
|
|
||||||
int checksum = 0;
|
int checksum = 0;
|
||||||
foreach (byte b in header)
|
foreach (byte b in header)
|
||||||
|
|
|
@ -161,43 +161,43 @@ namespace OpenSim.Framework.Servers
|
||||||
Notice(String.Format("Console log level is {0}", m_consoleAppender.Threshold));
|
Notice(String.Format("Console log level is {0}", m_consoleAppender.Threshold));
|
||||||
}
|
}
|
||||||
|
|
||||||
m_console.Commands.AddCommand("base", false, "quit",
|
m_console.Commands.AddCommand("General", false, "quit",
|
||||||
"quit",
|
"quit",
|
||||||
"Quit the application", HandleQuit);
|
"Quit the application", HandleQuit);
|
||||||
|
|
||||||
m_console.Commands.AddCommand("base", false, "shutdown",
|
m_console.Commands.AddCommand("General", false, "shutdown",
|
||||||
"shutdown",
|
"shutdown",
|
||||||
"Quit the application", HandleQuit);
|
"Quit the application", HandleQuit);
|
||||||
|
|
||||||
m_console.Commands.AddCommand("base", false, "set log level",
|
m_console.Commands.AddCommand("General", false, "set log level",
|
||||||
"set log level <level>",
|
"set log level <level>",
|
||||||
"Set the console logging level", HandleLogLevel);
|
"Set the console logging level", HandleLogLevel);
|
||||||
|
|
||||||
m_console.Commands.AddCommand("base", false, "show info",
|
m_console.Commands.AddCommand("General", false, "show info",
|
||||||
"show info",
|
"show info",
|
||||||
"Show general information about the server", HandleShow);
|
"Show general information about the server", HandleShow);
|
||||||
|
|
||||||
m_console.Commands.AddCommand("base", false, "show stats",
|
m_console.Commands.AddCommand("General", false, "show stats",
|
||||||
"show stats",
|
"show stats",
|
||||||
"Show statistics", HandleShow);
|
"Show statistics", HandleShow);
|
||||||
|
|
||||||
m_console.Commands.AddCommand("base", false, "show threads",
|
m_console.Commands.AddCommand("General", false, "show threads",
|
||||||
"show threads",
|
"show threads",
|
||||||
"Show thread status", HandleShow);
|
"Show thread status", HandleShow);
|
||||||
|
|
||||||
m_console.Commands.AddCommand("base", false, "show uptime",
|
m_console.Commands.AddCommand("General", false, "show uptime",
|
||||||
"show uptime",
|
"show uptime",
|
||||||
"Show server uptime", HandleShow);
|
"Show server uptime", HandleShow);
|
||||||
|
|
||||||
m_console.Commands.AddCommand("base", false, "show version",
|
m_console.Commands.AddCommand("General", false, "show version",
|
||||||
"show version",
|
"show version",
|
||||||
"Show server version", HandleShow);
|
"Show server version", HandleShow);
|
||||||
|
|
||||||
m_console.Commands.AddCommand("base", false, "threads abort",
|
m_console.Commands.AddCommand("General", false, "threads abort",
|
||||||
"threads abort <thread-id>",
|
"threads abort <thread-id>",
|
||||||
"Abort a managed thread. Use \"show threads\" to find possible threads.", HandleThreadsAbort);
|
"Abort a managed thread. Use \"show threads\" to find possible threads.", HandleThreadsAbort);
|
||||||
|
|
||||||
m_console.Commands.AddCommand("base", false, "threads show",
|
m_console.Commands.AddCommand("General", false, "threads show",
|
||||||
"threads show",
|
"threads show",
|
||||||
"Show thread status. Synonym for \"show threads\"",
|
"Show thread status. Synonym for \"show threads\"",
|
||||||
(string module, string[] args) => Notice(GetThreadsReport()));
|
(string module, string[] args) => Notice(GetThreadsReport()));
|
||||||
|
@ -269,15 +269,19 @@ namespace OpenSim.Framework.Servers
|
||||||
t.Priority,
|
t.Priority,
|
||||||
t.ThreadState);
|
t.ThreadState);
|
||||||
|
|
||||||
sb.Append(Environment.NewLine);
|
sb.Append("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
int workers = 0, ports = 0, maxWorkers = 0, maxPorts = 0;
|
sb.Append("\n");
|
||||||
ThreadPool.GetAvailableThreads(out workers, out ports);
|
|
||||||
ThreadPool.GetMaxThreads(out maxWorkers, out maxPorts);
|
|
||||||
|
|
||||||
sb.Append(Environment.NewLine + "*** ThreadPool threads ***" + Environment.NewLine);
|
// For some reason mono 2.6.7 returns an empty threads set! Not going to confuse people by reporting
|
||||||
sb.Append("workers: " + (maxWorkers - workers) + " (" + maxWorkers + "); ports: " + (maxPorts - ports) + " (" + maxPorts + ")" + Environment.NewLine);
|
// zero active threads.
|
||||||
|
int totalThreads = Process.GetCurrentProcess().Threads.Count;
|
||||||
|
if (totalThreads > 0)
|
||||||
|
sb.AppendFormat("Total threads active: {0}\n\n", totalThreads);
|
||||||
|
|
||||||
|
sb.Append("Main threadpool (excluding script engine pools)\n");
|
||||||
|
sb.Append(Util.GetThreadPoolReport());
|
||||||
|
|
||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
|
@ -316,7 +320,9 @@ namespace OpenSim.Framework.Servers
|
||||||
|
|
||||||
TimeSpan timeTaken = DateTime.Now - m_startuptime;
|
TimeSpan timeTaken = DateTime.Now - m_startuptime;
|
||||||
|
|
||||||
m_log.InfoFormat("[STARTUP]: Startup took {0}m {1}s", timeTaken.Minutes, timeTaken.Seconds);
|
m_log.InfoFormat(
|
||||||
|
"[STARTUP]: Non-script portion of startup took {0}m {1}s. PLEASE WAIT FOR LOGINS TO BE ENABLED ON REGIONS ONCE SCRIPTS HAVE STARTED.",
|
||||||
|
timeTaken.Minutes, timeTaken.Seconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -585,8 +591,8 @@ namespace OpenSim.Framework.Servers
|
||||||
{
|
{
|
||||||
string pidstring = System.Diagnostics.Process.GetCurrentProcess().Id.ToString();
|
string pidstring = System.Diagnostics.Process.GetCurrentProcess().Id.ToString();
|
||||||
FileStream fs = File.Create(path);
|
FileStream fs = File.Create(path);
|
||||||
System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
|
|
||||||
Byte[] buf = enc.GetBytes(pidstring);
|
Byte[] buf = Encoding.ASCII.GetBytes(pidstring);
|
||||||
fs.Write(buf, 0, buf.Length);
|
fs.Write(buf, 0, buf.Length);
|
||||||
fs.Close();
|
fs.Close();
|
||||||
m_pidFile = path;
|
m_pidFile = path;
|
||||||
|
|
|
@ -33,9 +33,9 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
{
|
{
|
||||||
public abstract Hashtable Handle(string path, Hashtable Request);
|
public abstract Hashtable Handle(string path, Hashtable Request);
|
||||||
|
|
||||||
protected BaseHTTPHandler(string httpMethod, string path)
|
protected BaseHTTPHandler(string httpMethod, string path) : this(httpMethod, path, null, null) {}
|
||||||
: base(httpMethod, path)
|
|
||||||
{
|
protected BaseHTTPHandler(string httpMethod, string path, string name, string description)
|
||||||
}
|
: base(httpMethod, path, name, description) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -53,6 +53,8 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
private HttpServerLogWriter httpserverlog = new HttpServerLogWriter();
|
private HttpServerLogWriter httpserverlog = new HttpServerLogWriter();
|
||||||
|
|
||||||
|
public int DebugLevel { get; set; }
|
||||||
|
|
||||||
private volatile int NotSocketErrors = 0;
|
private volatile int NotSocketErrors = 0;
|
||||||
public volatile bool HTTPDRunning = false;
|
public volatile bool HTTPDRunning = false;
|
||||||
|
|
||||||
|
@ -79,11 +81,6 @@ 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; }
|
||||||
|
@ -356,7 +353,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
m_log.ErrorFormat("[BASE HTTP SERVER]: OnRequest() failed with {0}{1}", e.Message, e.StackTrace);
|
m_log.Error(String.Format("[BASE HTTP SERVER]: OnRequest() failed: {0} ", e.Message), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -408,7 +405,12 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
string uriString = request.RawUrl;
|
string uriString = request.RawUrl;
|
||||||
|
|
||||||
// string reqnum = "unknown";
|
// string reqnum = "unknown";
|
||||||
int tickstart = Environment.TickCount;
|
int requestStartTick = Environment.TickCount;
|
||||||
|
|
||||||
|
// Will be adjusted later on.
|
||||||
|
int requestEndTick = requestStartTick;
|
||||||
|
|
||||||
|
IRequestHandler requestHandler = null;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -431,6 +433,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
{
|
{
|
||||||
if (HandleAgentRequest(agentHandler, request, response))
|
if (HandleAgentRequest(agentHandler, request, response))
|
||||||
{
|
{
|
||||||
|
requestEndTick = Environment.TickCount;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -438,20 +441,14 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
//response.KeepAlive = true;
|
//response.KeepAlive = true;
|
||||||
response.SendChunked = false;
|
response.SendChunked = false;
|
||||||
|
|
||||||
IRequestHandler requestHandler;
|
|
||||||
|
|
||||||
string path = request.RawUrl;
|
string path = request.RawUrl;
|
||||||
string handlerKey = GetHandlerKey(request.HttpMethod, path);
|
string handlerKey = GetHandlerKey(request.HttpMethod, path);
|
||||||
|
byte[] buffer = null;
|
||||||
|
|
||||||
if (TryGetStreamHandler(handlerKey, out requestHandler))
|
if (TryGetStreamHandler(handlerKey, out requestHandler))
|
||||||
{
|
{
|
||||||
if (DebugLevel >= 1)
|
if (DebugLevel >= 3)
|
||||||
m_log.DebugFormat(
|
LogIncomingToStreamHandler(request, requestHandler);
|
||||||
"[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.
|
|
||||||
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.
|
||||||
|
|
||||||
|
@ -507,8 +504,8 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
//m_log.Warn("[HTTP]: " + requestBody);
|
//m_log.Warn("[HTTP]: " + requestBody);
|
||||||
|
|
||||||
}
|
}
|
||||||
DoHTTPGruntWork(HTTPRequestHandler.Handle(path, keysvals), response);
|
|
||||||
return;
|
buffer = DoHTTPGruntWork(HTTPRequestHandler.Handle(path, keysvals), response);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -521,88 +518,33 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
buffer = memoryStream.ToArray();
|
buffer = memoryStream.ToArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
request.InputStream.Close();
|
else
|
||||||
|
|
||||||
// HTTP IN support. The script engine takes it from here
|
|
||||||
// Nothing to worry about for us.
|
|
||||||
//
|
|
||||||
if (buffer == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!response.SendChunked)
|
|
||||||
response.ContentLength64 = buffer.LongLength;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
response.OutputStream.Write(buffer, 0, buffer.Length);
|
|
||||||
//response.OutputStream.Close();
|
|
||||||
}
|
|
||||||
catch (HttpListenerException)
|
|
||||||
{
|
|
||||||
m_log.WarnFormat("[BASE HTTP SERVER]: HTTP request abnormally terminated.");
|
|
||||||
}
|
|
||||||
//response.OutputStream.Close();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
response.Send();
|
|
||||||
//response.FreeContext();
|
|
||||||
}
|
|
||||||
catch (SocketException e)
|
|
||||||
{
|
|
||||||
// This has to be here to prevent a Linux/Mono crash
|
|
||||||
m_log.WarnFormat("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e);
|
|
||||||
}
|
|
||||||
catch (IOException e)
|
|
||||||
{
|
|
||||||
m_log.Warn("[BASE HTTP SERVER]: XmlRpcRequest issue: " + e.Message);
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (request.AcceptTypes != null && request.AcceptTypes.Length > 0)
|
|
||||||
{
|
|
||||||
foreach (string strAccept in request.AcceptTypes)
|
|
||||||
{
|
|
||||||
if (strAccept.Contains("application/llsd+xml") ||
|
|
||||||
strAccept.Contains("application/llsd+json"))
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (request.ContentType)
|
switch (request.ContentType)
|
||||||
{
|
{
|
||||||
case null:
|
case null:
|
||||||
case "text/html":
|
case "text/html":
|
||||||
|
|
||||||
if (DebugLevel >= 1)
|
if (DebugLevel >= 3)
|
||||||
m_log.DebugFormat(
|
m_log.DebugFormat(
|
||||||
"[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}",
|
"[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}",
|
||||||
request.ContentType, request.HttpMethod, request.Url.PathAndQuery);
|
request.ContentType, request.HttpMethod, request.Url.PathAndQuery);
|
||||||
|
|
||||||
HandleHTTPRequest(request, response);
|
buffer = HandleHTTPRequest(request, response);
|
||||||
return;
|
break;
|
||||||
|
|
||||||
case "application/llsd+xml":
|
case "application/llsd+xml":
|
||||||
case "application/xml+llsd":
|
case "application/xml+llsd":
|
||||||
case "application/llsd+json":
|
case "application/llsd+json":
|
||||||
|
|
||||||
if (DebugLevel >= 1)
|
if (DebugLevel >= 3)
|
||||||
m_log.DebugFormat(
|
m_log.DebugFormat(
|
||||||
"[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}",
|
"[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}",
|
||||||
request.ContentType, request.HttpMethod, request.Url.PathAndQuery);
|
request.ContentType, request.HttpMethod, request.Url.PathAndQuery);
|
||||||
|
|
||||||
HandleLLSDRequests(request, response);
|
buffer = HandleLLSDRequests(request, response);
|
||||||
return;
|
break;
|
||||||
|
|
||||||
case "text/xml":
|
case "text/xml":
|
||||||
case "application/xml":
|
case "application/xml":
|
||||||
|
@ -617,37 +559,52 @@ 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))
|
||||||
{
|
{
|
||||||
if (DebugLevel >= 1)
|
if (DebugLevel >= 3)
|
||||||
m_log.DebugFormat(
|
LogIncomingToContentTypeHandler(request);
|
||||||
"[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}",
|
|
||||||
request.ContentType, request.HttpMethod, request.Url.PathAndQuery);
|
|
||||||
|
|
||||||
HandleLLSDRequests(request, response);
|
buffer = HandleLLSDRequests(request, response);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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))
|
else if (DoWeHaveAHTTPHandler(request.RawUrl))
|
||||||
{
|
{
|
||||||
if (DebugLevel >= 1)
|
if (DebugLevel >= 3)
|
||||||
m_log.DebugFormat(
|
LogIncomingToContentTypeHandler(request);
|
||||||
"[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}",
|
|
||||||
request.ContentType, request.HttpMethod, request.Url.PathAndQuery);
|
|
||||||
|
|
||||||
HandleHTTPRequest(request, response);
|
buffer = HandleHTTPRequest(request, response);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
if (DebugLevel >= 1)
|
{
|
||||||
m_log.DebugFormat(
|
if (DebugLevel >= 3)
|
||||||
"[BASE HTTP SERVER]: Assuming a generic XMLRPC request for {0} {1}",
|
LogIncomingToXmlRpcHandler(request);
|
||||||
request.HttpMethod, request.Url.PathAndQuery);
|
|
||||||
|
|
||||||
// generic login request.
|
// generic login request.
|
||||||
HandleXmlRpcRequests(request, response);
|
buffer = HandleXmlRpcRequests(request, response);
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
request.InputStream.Close();
|
||||||
|
|
||||||
|
if (buffer != null)
|
||||||
|
{
|
||||||
|
if (!response.SendChunked)
|
||||||
|
response.ContentLength64 = buffer.LongLength;
|
||||||
|
|
||||||
|
response.OutputStream.Write(buffer, 0, buffer.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do not include the time taken to actually send the response to the caller in the measurement
|
||||||
|
// time. This is to avoid logging when it's the client that is slow to process rather than the
|
||||||
|
// server
|
||||||
|
requestEndTick = Environment.TickCount;
|
||||||
|
|
||||||
|
response.Send();
|
||||||
|
|
||||||
|
//response.OutputStream.Close();
|
||||||
|
|
||||||
|
//response.FreeContext();
|
||||||
}
|
}
|
||||||
catch (SocketException e)
|
catch (SocketException e)
|
||||||
{
|
{
|
||||||
|
@ -658,25 +615,85 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
//
|
//
|
||||||
// An alternative may be to turn off all response write exceptions on the HttpListener, but let's go
|
// An alternative may be to turn off all response write exceptions on the HttpListener, but let's go
|
||||||
// with the minimum first
|
// with the minimum first
|
||||||
m_log.WarnFormat("[BASE HTTP SERVER]: HandleRequest threw {0}.\nNOTE: this may be spurious on Linux", e);
|
m_log.Warn(String.Format("[BASE HTTP SERVER]: HandleRequest threw {0}.\nNOTE: this may be spurious on Linux ", e.Message), e);
|
||||||
}
|
}
|
||||||
catch (IOException e)
|
catch (IOException e)
|
||||||
{
|
{
|
||||||
m_log.ErrorFormat("[BASE HTTP SERVER]: HandleRequest() threw ", e);
|
m_log.Error(String.Format("[BASE HTTP SERVER]: HandleRequest() threw {0} ", e.Message), e);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
m_log.ErrorFormat("[BASE HTTP SERVER]: HandleRequest() threw " + e.ToString());
|
m_log.Error(String.Format("[BASE HTTP SERVER]: HandleRequest() threw {0} ", e.Message), e);
|
||||||
SendHTML500(response);
|
SendHTML500(response);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
// Every month or so this will wrap and give bad numbers, not really a problem
|
// Every month or so this will wrap and give bad numbers, not really a problem
|
||||||
// since its just for reporting, tickdiff limit can be adjusted
|
// since its just for reporting
|
||||||
int tickdiff = Environment.TickCount - tickstart;
|
int tickdiff = requestEndTick - requestStartTick;
|
||||||
if (tickdiff > 3000)
|
if (tickdiff > 3000)
|
||||||
|
{
|
||||||
m_log.InfoFormat(
|
m_log.InfoFormat(
|
||||||
"[BASE HTTP SERVER]: slow {0} request for {1} from {2} took {3} ms", requestMethod, uriString, request.RemoteIPEndPoint.ToString(), tickdiff);
|
"[BASE HTTP SERVER]: Slow handling of {0} {1} {2} {3} from {4} took {5}ms",
|
||||||
|
requestMethod,
|
||||||
|
uriString,
|
||||||
|
requestHandler != null ? requestHandler.Name : "",
|
||||||
|
requestHandler != null ? requestHandler.Description : "",
|
||||||
|
request.RemoteIPEndPoint.ToString(),
|
||||||
|
tickdiff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LogIncomingToStreamHandler(OSHttpRequest request, IRequestHandler requestHandler)
|
||||||
|
{
|
||||||
|
m_log.DebugFormat(
|
||||||
|
"[BASE HTTP SERVER]: Found stream handler for {0} {1} {2} {3}",
|
||||||
|
request.HttpMethod, request.Url.PathAndQuery, requestHandler.Name, requestHandler.Description);
|
||||||
|
|
||||||
|
if (DebugLevel >= 4)
|
||||||
|
LogIncomingInDetail(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LogIncomingToContentTypeHandler(OSHttpRequest request)
|
||||||
|
{
|
||||||
|
m_log.DebugFormat(
|
||||||
|
"[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}",
|
||||||
|
request.ContentType, request.HttpMethod, request.Url.PathAndQuery);
|
||||||
|
|
||||||
|
if (DebugLevel >= 4)
|
||||||
|
LogIncomingInDetail(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LogIncomingToXmlRpcHandler(OSHttpRequest request)
|
||||||
|
{
|
||||||
|
m_log.DebugFormat(
|
||||||
|
"[BASE HTTP SERVER]: Assuming a generic XMLRPC request for {0} {1}",
|
||||||
|
request.HttpMethod, request.Url.PathAndQuery);
|
||||||
|
|
||||||
|
if (DebugLevel >= 4)
|
||||||
|
LogIncomingInDetail(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LogIncomingInDetail(OSHttpRequest request)
|
||||||
|
{
|
||||||
|
using (StreamReader reader = new StreamReader(Util.Copy(request.InputStream), Encoding.UTF8))
|
||||||
|
{
|
||||||
|
string output;
|
||||||
|
|
||||||
|
if (DebugLevel == 4)
|
||||||
|
{
|
||||||
|
const int sampleLength = 80;
|
||||||
|
char[] sampleChars = new char[sampleLength];
|
||||||
|
reader.Read(sampleChars, 0, sampleLength);
|
||||||
|
output = string.Format("[BASE HTTP SERVER]: {0}...", new string(sampleChars).Replace("\n", @"\n"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
output = string.Format("[BASE HTTP SERVER]: {0}", reader.ReadToEnd());
|
||||||
|
}
|
||||||
|
|
||||||
|
m_log.Debug(output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -797,7 +814,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="request"></param>
|
/// <param name="request"></param>
|
||||||
/// <param name="response"></param>
|
/// <param name="response"></param>
|
||||||
private void HandleXmlRpcRequests(OSHttpRequest request, OSHttpResponse response)
|
private byte[] HandleXmlRpcRequests(OSHttpRequest request, OSHttpResponse response)
|
||||||
{
|
{
|
||||||
Stream requestStream = request.InputStream;
|
Stream requestStream = request.InputStream;
|
||||||
|
|
||||||
|
@ -816,8 +833,23 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
{
|
{
|
||||||
xmlRprcRequest = (XmlRpcRequest) (new XmlRpcRequestDeserializer()).Deserialize(requestBody);
|
xmlRprcRequest = (XmlRpcRequest) (new XmlRpcRequestDeserializer()).Deserialize(requestBody);
|
||||||
}
|
}
|
||||||
catch (XmlException)
|
catch (XmlException e)
|
||||||
{
|
{
|
||||||
|
if (DebugLevel >= 1)
|
||||||
|
{
|
||||||
|
if (DebugLevel >= 2)
|
||||||
|
m_log.Warn(
|
||||||
|
string.Format(
|
||||||
|
"[BASE HTTP SERVER]: Got XMLRPC request with invalid XML from {0}. XML was '{1}'. Sending blank response. Exception ",
|
||||||
|
request.RemoteIPEndPoint, requestBody),
|
||||||
|
e);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_log.WarnFormat(
|
||||||
|
"[BASE HTTP SERVER]: Got XMLRPC request with invalid XML from {0}, length {1}. Sending blank response.",
|
||||||
|
request.RemoteIPEndPoint, requestBody.Length);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xmlRprcRequest != null)
|
if (xmlRprcRequest != null)
|
||||||
|
@ -887,6 +919,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
String.Format("Requested method [{0}] not found", methodName));
|
String.Format("Requested method [{0}] not found", methodName));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
response.ContentType = "text/xml";
|
||||||
responseString = XmlRpcResponseSerializer.Singleton.Serialize(xmlRpcResponse);
|
responseString = XmlRpcResponseSerializer.Singleton.Serialize(xmlRpcResponse);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -896,82 +929,25 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
response.StatusCode = 404;
|
response.StatusCode = 404;
|
||||||
response.StatusDescription = "Not Found";
|
response.StatusDescription = "Not Found";
|
||||||
response.ProtocolVersion = "HTTP/1.0";
|
response.ProtocolVersion = "HTTP/1.0";
|
||||||
byte[] buf = Encoding.UTF8.GetBytes("Not found");
|
responseString = "Not found";
|
||||||
response.KeepAlive = false;
|
response.KeepAlive = false;
|
||||||
|
|
||||||
m_log.ErrorFormat(
|
m_log.ErrorFormat(
|
||||||
"[BASE HTTP SERVER]: Handler not found for http request {0} {1}",
|
"[BASE HTTP SERVER]: Handler not found for http request {0} {1}",
|
||||||
request.HttpMethod, request.Url.PathAndQuery);
|
request.HttpMethod, request.Url.PathAndQuery);
|
||||||
|
|
||||||
response.SendChunked = false;
|
|
||||||
response.ContentLength64 = buf.Length;
|
|
||||||
response.ContentEncoding = Encoding.UTF8;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
response.OutputStream.Write(buf, 0, buf.Length);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
m_log.Warn("[BASE HTTP SERVER]: Error - " + ex.Message);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
response.Send();
|
|
||||||
//response.FreeContext();
|
|
||||||
}
|
|
||||||
catch (SocketException e)
|
|
||||||
{
|
|
||||||
// This has to be here to prevent a Linux/Mono crash
|
|
||||||
m_log.WarnFormat("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e);
|
|
||||||
}
|
|
||||||
catch (IOException e)
|
|
||||||
{
|
|
||||||
m_log.Warn("[BASE HTTP SERVER]: XmlRpcRequest issue: " + e.Message);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
//responseString = "Error";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
response.ContentType = "text/xml";
|
|
||||||
|
|
||||||
byte[] buffer = Encoding.UTF8.GetBytes(responseString);
|
byte[] buffer = Encoding.UTF8.GetBytes(responseString);
|
||||||
|
|
||||||
response.SendChunked = false;
|
response.SendChunked = false;
|
||||||
response.ContentLength64 = buffer.Length;
|
response.ContentLength64 = buffer.Length;
|
||||||
response.ContentEncoding = Encoding.UTF8;
|
response.ContentEncoding = Encoding.UTF8;
|
||||||
try
|
|
||||||
{
|
return buffer;
|
||||||
response.OutputStream.Write(buffer, 0, buffer.Length);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
m_log.Warn("[BASE HTTP SERVER]: Error - " + ex.Message);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
response.Send();
|
|
||||||
//response.FreeContext();
|
|
||||||
}
|
|
||||||
catch (SocketException e)
|
|
||||||
{
|
|
||||||
// This has to be here to prevent a Linux/Mono crash
|
|
||||||
m_log.WarnFormat("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e);
|
|
||||||
}
|
|
||||||
catch (IOException e)
|
|
||||||
{
|
|
||||||
m_log.Warn("[BASE HTTP SERVER]: XmlRpcRequest issue: " + e.Message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleLLSDRequests(OSHttpRequest request, OSHttpResponse response)
|
private byte[] HandleLLSDRequests(OSHttpRequest request, OSHttpResponse response)
|
||||||
{
|
{
|
||||||
//m_log.Warn("[BASE HTTP SERVER]: We've figured out it's a LLSD Request");
|
//m_log.Warn("[BASE HTTP SERVER]: We've figured out it's a LLSD Request");
|
||||||
Stream requestStream = request.InputStream;
|
Stream requestStream = request.InputStream;
|
||||||
|
@ -1057,34 +1033,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
response.ContentEncoding = Encoding.UTF8;
|
response.ContentEncoding = Encoding.UTF8;
|
||||||
response.KeepAlive = true;
|
response.KeepAlive = true;
|
||||||
|
|
||||||
try
|
return buffer;
|
||||||
{
|
|
||||||
response.OutputStream.Write(buffer, 0, buffer.Length);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
m_log.Warn("[BASE HTTP SERVER]: Error - " + ex.Message);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
//response.OutputStream.Close();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
response.Send();
|
|
||||||
response.OutputStream.Flush();
|
|
||||||
//response.FreeContext();
|
|
||||||
//response.OutputStream.Close();
|
|
||||||
}
|
|
||||||
catch (IOException e)
|
|
||||||
{
|
|
||||||
m_log.WarnFormat("[BASE HTTP SERVER]: LLSD IOException {0}.", e);
|
|
||||||
}
|
|
||||||
catch (SocketException e)
|
|
||||||
{
|
|
||||||
// This has to be here to prevent a Linux/Mono crash
|
|
||||||
m_log.WarnFormat("[BASE HTTP SERVER]: LLSD issue {0}.\nNOTE: this may be spurious on Linux.", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte[] BuildLLSDResponse(OSHttpRequest request, OSHttpResponse response, OSD llsdResponse)
|
private byte[] BuildLLSDResponse(OSHttpRequest request, OSHttpResponse response, OSD llsdResponse)
|
||||||
|
@ -1334,8 +1283,8 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
catch (SocketException f)
|
catch (SocketException f)
|
||||||
{
|
{
|
||||||
// This has to be here to prevent a Linux/Mono crash
|
// This has to be here to prevent a Linux/Mono crash
|
||||||
m_log.WarnFormat(
|
m_log.Warn(
|
||||||
"[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", f);
|
String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux. ", f.Message), f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch(Exception)
|
catch(Exception)
|
||||||
|
@ -1349,7 +1298,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void HandleHTTPRequest(OSHttpRequest request, OSHttpResponse response)
|
public byte[] HandleHTTPRequest(OSHttpRequest request, OSHttpResponse response)
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat(
|
// m_log.DebugFormat(
|
||||||
// "[BASE HTTP SERVER]: HandleHTTPRequest for request to {0}, method {1}",
|
// "[BASE HTTP SERVER]: HandleHTTPRequest for request to {0}, method {1}",
|
||||||
|
@ -1359,15 +1308,14 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
{
|
{
|
||||||
case "OPTIONS":
|
case "OPTIONS":
|
||||||
response.StatusCode = (int)OSHttpStatusCode.SuccessOk;
|
response.StatusCode = (int)OSHttpStatusCode.SuccessOk;
|
||||||
return;
|
return null;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
HandleContentVerbs(request, response);
|
return HandleContentVerbs(request, response);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleContentVerbs(OSHttpRequest request, OSHttpResponse response)
|
private byte[] HandleContentVerbs(OSHttpRequest request, OSHttpResponse response)
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat("[BASE HTTP SERVER]: HandleContentVerbs for request to {0}", request.RawUrl);
|
// m_log.DebugFormat("[BASE HTTP SERVER]: HandleContentVerbs for request to {0}", request.RawUrl);
|
||||||
|
|
||||||
|
@ -1383,6 +1331,8 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
// to display the form, or process it.
|
// to display the form, or process it.
|
||||||
// a better way would be nifty.
|
// a better way would be nifty.
|
||||||
|
|
||||||
|
byte[] buffer;
|
||||||
|
|
||||||
Stream requestStream = request.InputStream;
|
Stream requestStream = request.InputStream;
|
||||||
|
|
||||||
Encoding encoding = Encoding.UTF8;
|
Encoding encoding = Encoding.UTF8;
|
||||||
|
@ -1443,14 +1393,14 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
if (foundHandler)
|
if (foundHandler)
|
||||||
{
|
{
|
||||||
Hashtable responsedata1 = requestprocessor(keysvals);
|
Hashtable responsedata1 = requestprocessor(keysvals);
|
||||||
DoHTTPGruntWork(responsedata1,response);
|
buffer = DoHTTPGruntWork(responsedata1,response);
|
||||||
|
|
||||||
//SendHTML500(response);
|
//SendHTML500(response);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// m_log.Warn("[BASE HTTP SERVER]: Handler Not Found");
|
// m_log.Warn("[BASE HTTP SERVER]: Handler Not Found");
|
||||||
SendHTML404(response, host);
|
buffer = SendHTML404(response, host);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1460,16 +1410,18 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
if (foundHandler)
|
if (foundHandler)
|
||||||
{
|
{
|
||||||
Hashtable responsedata2 = requestprocessor(keysvals);
|
Hashtable responsedata2 = requestprocessor(keysvals);
|
||||||
DoHTTPGruntWork(responsedata2, response);
|
buffer = DoHTTPGruntWork(responsedata2, response);
|
||||||
|
|
||||||
//SendHTML500(response);
|
//SendHTML500(response);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// m_log.Warn("[BASE HTTP SERVER]: Handler Not Found2");
|
// m_log.Warn("[BASE HTTP SERVER]: Handler Not Found2");
|
||||||
SendHTML404(response, host);
|
buffer = SendHTML404(response, host);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool TryGetHTTPHandlerPathBased(string path, out GenericHTTPMethod httpHandler)
|
private bool TryGetHTTPHandlerPathBased(string path, out GenericHTTPMethod httpHandler)
|
||||||
|
@ -1537,14 +1489,13 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void DoHTTPGruntWork(Hashtable responsedata, OSHttpResponse response)
|
internal byte[] DoHTTPGruntWork(Hashtable responsedata, OSHttpResponse response)
|
||||||
{
|
{
|
||||||
//m_log.Info("[BASE HTTP SERVER]: Doing HTTP Grunt work with response");
|
//m_log.Info("[BASE HTTP SERVER]: Doing HTTP Grunt work with response");
|
||||||
int responsecode = (int)responsedata["int_response_code"];
|
int responsecode = (int)responsedata["int_response_code"];
|
||||||
string responseString = (string)responsedata["str_response_string"];
|
string responseString = (string)responsedata["str_response_string"];
|
||||||
string contentType = (string)responsedata["content_type"];
|
string contentType = (string)responsedata["content_type"];
|
||||||
|
|
||||||
|
|
||||||
if (responsedata.ContainsKey("error_status_text"))
|
if (responsedata.ContainsKey("error_status_text"))
|
||||||
{
|
{
|
||||||
response.StatusDescription = (string)responsedata["error_status_text"];
|
response.StatusDescription = (string)responsedata["error_status_text"];
|
||||||
|
@ -1608,38 +1559,10 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
response.ContentLength64 = buffer.Length;
|
response.ContentLength64 = buffer.Length;
|
||||||
response.ContentEncoding = Encoding.UTF8;
|
response.ContentEncoding = Encoding.UTF8;
|
||||||
|
|
||||||
try
|
return buffer;
|
||||||
{
|
|
||||||
response.OutputStream.Write(buffer, 0, buffer.Length);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
m_log.Warn("[HTTPD]: Error - " + ex.Message);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
//response.OutputStream.Close();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
response.OutputStream.Flush();
|
|
||||||
response.Send();
|
|
||||||
|
|
||||||
//if (!response.KeepAlive && response.ReuseContext)
|
|
||||||
// response.FreeContext();
|
|
||||||
}
|
|
||||||
catch (SocketException e)
|
|
||||||
{
|
|
||||||
// This has to be here to prevent a Linux/Mono crash
|
|
||||||
m_log.WarnFormat("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e);
|
|
||||||
}
|
|
||||||
catch (IOException e)
|
|
||||||
{
|
|
||||||
m_log.Warn("[BASE HTTP SERVER]: XmlRpcRequest issue: " + e.Message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendHTML404(OSHttpResponse response, string host)
|
public byte[] SendHTML404(OSHttpResponse response, string host)
|
||||||
{
|
{
|
||||||
// I know this statuscode is dumb, but the client doesn't respond to 404s and 500s
|
// I know this statuscode is dumb, but the client doesn't respond to 404s and 500s
|
||||||
response.StatusCode = 404;
|
response.StatusCode = 404;
|
||||||
|
@ -1652,31 +1575,10 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
response.ContentLength64 = buffer.Length;
|
response.ContentLength64 = buffer.Length;
|
||||||
response.ContentEncoding = Encoding.UTF8;
|
response.ContentEncoding = Encoding.UTF8;
|
||||||
|
|
||||||
try
|
return buffer;
|
||||||
{
|
|
||||||
response.OutputStream.Write(buffer, 0, buffer.Length);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
m_log.Warn("[BASE HTTP SERVER]: Error - " + ex.Message);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
//response.OutputStream.Close();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
response.Send();
|
|
||||||
//response.FreeContext();
|
|
||||||
}
|
|
||||||
catch (SocketException e)
|
|
||||||
{
|
|
||||||
// This has to be here to prevent a Linux/Mono crash
|
|
||||||
m_log.WarnFormat("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendHTML500(OSHttpResponse response)
|
public byte[] SendHTML500(OSHttpResponse response)
|
||||||
{
|
{
|
||||||
// I know this statuscode is dumb, but the client doesn't respond to 404s and 500s
|
// I know this statuscode is dumb, but the client doesn't respond to 404s and 500s
|
||||||
response.StatusCode = (int)OSHttpStatusCode.SuccessOk;
|
response.StatusCode = (int)OSHttpStatusCode.SuccessOk;
|
||||||
|
@ -1688,28 +1590,8 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
response.SendChunked = false;
|
response.SendChunked = false;
|
||||||
response.ContentLength64 = buffer.Length;
|
response.ContentLength64 = buffer.Length;
|
||||||
response.ContentEncoding = Encoding.UTF8;
|
response.ContentEncoding = Encoding.UTF8;
|
||||||
try
|
|
||||||
{
|
return buffer;
|
||||||
response.OutputStream.Write(buffer, 0, buffer.Length);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
m_log.Warn("[BASE HTTP SERVER]: Error - " + ex.Message);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
//response.OutputStream.Close();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
response.Send();
|
|
||||||
//response.FreeContext();
|
|
||||||
}
|
|
||||||
catch (SocketException e)
|
|
||||||
{
|
|
||||||
// This has to be here to prevent a Linux/Mono crash
|
|
||||||
m_log.WarnFormat("[BASE HTTP SERVER] XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Start()
|
public void Start()
|
||||||
|
@ -1719,6 +1601,9 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
|
|
||||||
private void StartHTTP()
|
private void StartHTTP()
|
||||||
{
|
{
|
||||||
|
m_log.InfoFormat(
|
||||||
|
"[BASE HTTP SERVER]: Starting {0} server on port {1}", UseSSL ? "HTTPS" : "HTTP", Port);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
//m_httpListener = new HttpListener();
|
//m_httpListener = new HttpListener();
|
||||||
|
@ -1786,7 +1671,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
|
|
||||||
public void httpServerException(object source, Exception exception)
|
public void httpServerException(object source, Exception exception)
|
||||||
{
|
{
|
||||||
m_log.ErrorFormat("[BASE HTTP SERVER]: {0} had an exception {1}", source.ToString(), exception.ToString());
|
m_log.Error(String.Format("[BASE HTTP SERVER]: {0} had an exception: {1} ", source.ToString(), exception.Message), exception);
|
||||||
/*
|
/*
|
||||||
if (HTTPDRunning)// && NotSocketErrors > 5)
|
if (HTTPDRunning)// && NotSocketErrors > 5)
|
||||||
{
|
{
|
||||||
|
|
|
@ -45,8 +45,16 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
|
|
||||||
private readonly string m_path;
|
private readonly string m_path;
|
||||||
|
|
||||||
protected BaseRequestHandler(string httpMethod, string path)
|
public string Name { get; private set; }
|
||||||
|
|
||||||
|
public string Description { get; private set; }
|
||||||
|
|
||||||
|
protected BaseRequestHandler(string httpMethod, string path) : this(httpMethod, path, null, null) {}
|
||||||
|
|
||||||
|
protected BaseRequestHandler(string httpMethod, string path, string name, string description)
|
||||||
{
|
{
|
||||||
|
Name = name;
|
||||||
|
Description = description;
|
||||||
m_httpMethod = httpMethod;
|
m_httpMethod = httpMethod;
|
||||||
m_path = path;
|
m_path = path;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,8 +34,9 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
public abstract byte[] Handle(string path, Stream request,
|
public abstract byte[] Handle(string path, Stream request,
|
||||||
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse);
|
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse);
|
||||||
|
|
||||||
protected BaseStreamHandler(string httpMethod, string path) : base(httpMethod, path)
|
protected BaseStreamHandler(string httpMethod, string path) : this(httpMethod, path, null, null) {}
|
||||||
{
|
|
||||||
}
|
protected BaseStreamHandler(string httpMethod, string path, string name, string description)
|
||||||
|
: base(httpMethod, path, name, description) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -36,6 +36,15 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
{
|
{
|
||||||
private BinaryMethod m_method;
|
private BinaryMethod m_method;
|
||||||
|
|
||||||
|
public BinaryStreamHandler(string httpMethod, string path, BinaryMethod binaryMethod)
|
||||||
|
: this(httpMethod, path, binaryMethod, null, null) {}
|
||||||
|
|
||||||
|
public BinaryStreamHandler(string httpMethod, string path, BinaryMethod binaryMethod, string name, string description)
|
||||||
|
: base(httpMethod, path, name, description)
|
||||||
|
{
|
||||||
|
m_method = binaryMethod;
|
||||||
|
}
|
||||||
|
|
||||||
public override byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
public override byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
||||||
{
|
{
|
||||||
byte[] data = ReadFully(request);
|
byte[] data = ReadFully(request);
|
||||||
|
@ -45,12 +54,6 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
return Encoding.UTF8.GetBytes(responseString);
|
return Encoding.UTF8.GetBytes(responseString);
|
||||||
}
|
}
|
||||||
|
|
||||||
public BinaryStreamHandler(string httpMethod, string path, BinaryMethod binaryMethod)
|
|
||||||
: base(httpMethod, path)
|
|
||||||
{
|
|
||||||
m_method = binaryMethod;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static byte[] ReadFully(Stream stream)
|
private static byte[] ReadFully(Stream stream)
|
||||||
{
|
{
|
||||||
byte[] buffer = new byte[1024];
|
byte[] buffer = new byte[1024];
|
||||||
|
|
|
@ -128,11 +128,5 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
/// <param name="value">string containing the header field
|
/// <param name="value">string containing the header field
|
||||||
/// value</param>
|
/// value</param>
|
||||||
void AddHeader(string key, string value);
|
void AddHeader(string key, string value);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Send the response back to the remote client
|
|
||||||
/// </summary>
|
|
||||||
void Send();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,25 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
{
|
{
|
||||||
public interface IRequestHandler
|
public interface IRequestHandler
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Name for this handler.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Used for diagnostics. The path doesn't always describe what the handler does. Can be null if none
|
||||||
|
/// specified.
|
||||||
|
/// </remarks>
|
||||||
|
string Name { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Description for this handler.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Used for diagnostics. The path doesn't always describe what the handler does. Can be null if none
|
||||||
|
/// specified.
|
||||||
|
/// </remarks>
|
||||||
|
string Description { get; }
|
||||||
|
|
||||||
// Return response content type
|
// Return response content type
|
||||||
string ContentType { get; }
|
string ContentType { get; }
|
||||||
|
|
||||||
|
|
|
@ -321,13 +321,12 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
{
|
{
|
||||||
_httpResponse.Body.Flush();
|
_httpResponse.Body.Flush();
|
||||||
_httpResponse.Send();
|
_httpResponse.Send();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void FreeContext()
|
public void FreeContext()
|
||||||
{
|
{
|
||||||
if (_httpClientContext != null)
|
if (_httpClientContext != null)
|
||||||
_httpClientContext.Close();
|
_httpClientContext.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -28,6 +28,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
|
|
||||||
namespace OpenSim.Framework.Servers.HttpServer
|
namespace OpenSim.Framework.Servers.HttpServer
|
||||||
{
|
{
|
||||||
public delegate void RequestMethod(UUID requestID, Hashtable request);
|
public delegate void RequestMethod(UUID requestID, Hashtable request);
|
||||||
|
@ -44,7 +45,11 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
public NoEventsMethod NoEvents;
|
public NoEventsMethod NoEvents;
|
||||||
public RequestMethod Request;
|
public RequestMethod Request;
|
||||||
public UUID Id;
|
public UUID Id;
|
||||||
public PollServiceEventArgs(RequestMethod pRequest, HasEventsMethod pHasEvents, GetEventsMethod pGetEvents, NoEventsMethod pNoEvents,UUID pId)
|
|
||||||
|
public PollServiceEventArgs(
|
||||||
|
RequestMethod pRequest,
|
||||||
|
HasEventsMethod pHasEvents, GetEventsMethod pGetEvents, NoEventsMethod pNoEvents,
|
||||||
|
UUID pId)
|
||||||
{
|
{
|
||||||
Request = pRequest;
|
Request = pRequest;
|
||||||
HasEvents = pHasEvents;
|
HasEvents = pHasEvents;
|
||||||
|
|
|
@ -31,7 +31,6 @@ using OpenMetaverse;
|
||||||
|
|
||||||
namespace OpenSim.Framework.Servers.HttpServer
|
namespace OpenSim.Framework.Servers.HttpServer
|
||||||
{
|
{
|
||||||
|
|
||||||
public class PollServiceHttpRequest
|
public class PollServiceHttpRequest
|
||||||
{
|
{
|
||||||
public readonly PollServiceEventArgs PollServiceArgs;
|
public readonly PollServiceEventArgs PollServiceArgs;
|
||||||
|
@ -39,7 +38,9 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
public readonly IHttpRequest Request;
|
public readonly IHttpRequest Request;
|
||||||
public readonly int RequestTime;
|
public readonly int RequestTime;
|
||||||
public readonly UUID RequestID;
|
public readonly UUID RequestID;
|
||||||
public PollServiceHttpRequest(PollServiceEventArgs pPollServiceArgs, IHttpClientContext pHttpContext, IHttpRequest pRequest)
|
|
||||||
|
public PollServiceHttpRequest(
|
||||||
|
PollServiceEventArgs pPollServiceArgs, IHttpClientContext pHttpContext, IHttpRequest pRequest)
|
||||||
{
|
{
|
||||||
PollServiceArgs = pPollServiceArgs;
|
PollServiceArgs = pPollServiceArgs;
|
||||||
HttpContext = pHttpContext;
|
HttpContext = pHttpContext;
|
||||||
|
|
|
@ -66,6 +66,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
ThreadPriority.Normal,
|
ThreadPriority.Normal,
|
||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
|
null,
|
||||||
int.MaxValue);
|
int.MaxValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,6 +76,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
ThreadPriority.Normal,
|
ThreadPriority.Normal,
|
||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
|
null,
|
||||||
1000 * 60 * 10);
|
1000 * 60 * 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,9 +140,8 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
foreach (object o in m_requests)
|
foreach (object o in m_requests)
|
||||||
{
|
{
|
||||||
PollServiceHttpRequest req = (PollServiceHttpRequest) o;
|
PollServiceHttpRequest req = (PollServiceHttpRequest) o;
|
||||||
m_server.DoHTTPGruntWork(
|
PollServiceWorkerThread.DoHTTPGruntWork(
|
||||||
req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id),
|
m_server, req, req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id));
|
||||||
new OSHttpResponse(new HttpResponse(req.HttpContext, req.Request), req.HttpContext));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_requests.Clear();
|
m_requests.Clear();
|
||||||
|
@ -149,6 +150,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
{
|
{
|
||||||
t.Abort();
|
t.Abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_running = false;
|
m_running = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,15 +90,16 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
}
|
}
|
||||||
|
|
||||||
Hashtable responsedata = req.PollServiceArgs.GetEvents(req.RequestID, req.PollServiceArgs.Id, str.ReadToEnd());
|
Hashtable responsedata = req.PollServiceArgs.GetEvents(req.RequestID, req.PollServiceArgs.Id, str.ReadToEnd());
|
||||||
m_server.DoHTTPGruntWork(responsedata,
|
DoHTTPGruntWork(m_server, req, responsedata);
|
||||||
new OSHttpResponse(new HttpResponse(req.HttpContext, req.Request),req.HttpContext));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ((Environment.TickCount - req.RequestTime) > m_timeout)
|
if ((Environment.TickCount - req.RequestTime) > m_timeout)
|
||||||
{
|
{
|
||||||
m_server.DoHTTPGruntWork(req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id),
|
DoHTTPGruntWork(
|
||||||
new OSHttpResponse(new HttpResponse(req.HttpContext, req.Request),req.HttpContext));
|
m_server,
|
||||||
|
req,
|
||||||
|
req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -119,5 +120,45 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
{
|
{
|
||||||
m_request.Enqueue(pPollServiceHttpRequest);
|
m_request.Enqueue(pPollServiceHttpRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// FIXME: This should be part of BaseHttpServer
|
||||||
|
/// </summary>
|
||||||
|
internal static void DoHTTPGruntWork(BaseHttpServer server, PollServiceHttpRequest req, Hashtable responsedata)
|
||||||
|
{
|
||||||
|
OSHttpResponse response
|
||||||
|
= new OSHttpResponse(new HttpResponse(req.HttpContext, req.Request), req.HttpContext);
|
||||||
|
|
||||||
|
byte[] buffer = server.DoHTTPGruntWork(responsedata, response);
|
||||||
|
|
||||||
|
response.SendChunked = false;
|
||||||
|
response.ContentLength64 = buffer.Length;
|
||||||
|
response.ContentEncoding = Encoding.UTF8;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
response.OutputStream.Write(buffer, 0, buffer.Length);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
m_log.Warn(string.Format("[POLL SERVICE WORKER THREAD]: Error ", ex));
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
//response.OutputStream.Close();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
response.OutputStream.Flush();
|
||||||
|
response.Send();
|
||||||
|
|
||||||
|
//if (!response.KeepAlive && response.ReuseContext)
|
||||||
|
// response.FreeContext();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
m_log.Warn(String.Format("[POLL SERVICE WORKER THREAD]: Error ", e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -39,7 +39,11 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
private RestDeserialiseMethod<TRequest, TResponse> m_method;
|
private RestDeserialiseMethod<TRequest, TResponse> m_method;
|
||||||
|
|
||||||
public RestDeserialiseHandler(string httpMethod, string path, RestDeserialiseMethod<TRequest, TResponse> method)
|
public RestDeserialiseHandler(string httpMethod, string path, RestDeserialiseMethod<TRequest, TResponse> method)
|
||||||
: base(httpMethod, path)
|
: this(httpMethod, path, method, null, null) {}
|
||||||
|
|
||||||
|
public RestDeserialiseHandler(
|
||||||
|
string httpMethod, string path, RestDeserialiseMethod<TRequest, TResponse> method, string name, string description)
|
||||||
|
: base(httpMethod, path, name, description)
|
||||||
{
|
{
|
||||||
m_method = method;
|
m_method = method;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,19 +38,25 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
get { return m_dhttpMethod; }
|
get { return m_dhttpMethod; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Hashtable Handle(string path, Hashtable request)
|
|
||||||
{
|
|
||||||
|
|
||||||
string param = GetParam(path);
|
|
||||||
request.Add("param", param);
|
|
||||||
request.Add("path", path);
|
|
||||||
return m_dhttpMethod(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
public RestHTTPHandler(string httpMethod, string path, GenericHTTPMethod dhttpMethod)
|
public RestHTTPHandler(string httpMethod, string path, GenericHTTPMethod dhttpMethod)
|
||||||
: base(httpMethod, path)
|
: base(httpMethod, path)
|
||||||
{
|
{
|
||||||
m_dhttpMethod = dhttpMethod;
|
m_dhttpMethod = dhttpMethod;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public RestHTTPHandler(
|
||||||
|
string httpMethod, string path, GenericHTTPMethod dhttpMethod, string name, string description)
|
||||||
|
: base(httpMethod, path, name, description)
|
||||||
|
{
|
||||||
|
m_dhttpMethod = dhttpMethod;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Hashtable Handle(string path, Hashtable request)
|
||||||
|
{
|
||||||
|
string param = GetParam(path);
|
||||||
|
request.Add("param", param);
|
||||||
|
request.Add("path", path);
|
||||||
|
return m_dhttpMethod(request);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,15 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
get { return m_restMethod; }
|
get { return m_restMethod; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public RestStreamHandler(string httpMethod, string path, RestMethod restMethod)
|
||||||
|
: this(httpMethod, path, restMethod, null, null) {}
|
||||||
|
|
||||||
|
public RestStreamHandler(string httpMethod, string path, RestMethod restMethod, string name, string description)
|
||||||
|
: base(httpMethod, path, name, description)
|
||||||
|
{
|
||||||
|
m_restMethod = restMethod;
|
||||||
|
}
|
||||||
|
|
||||||
public override byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
public override byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
||||||
{
|
{
|
||||||
Encoding encoding = Encoding.UTF8;
|
Encoding encoding = Encoding.UTF8;
|
||||||
|
@ -52,10 +61,5 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
|
|
||||||
return Encoding.UTF8.GetBytes(responseString);
|
return Encoding.UTF8.GetBytes(responseString);
|
||||||
}
|
}
|
||||||
|
|
||||||
public RestStreamHandler(string httpMethod, string path, RestMethod restMethod) : base(httpMethod, path)
|
|
||||||
{
|
|
||||||
m_restMethod = restMethod;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,45 +25,250 @@
|
||||||
* 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.Reflection;
|
using System.Reflection;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
using System.Text;
|
||||||
using log4net;
|
using log4net;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Framework.Console;
|
||||||
using OpenSim.Framework.Servers.HttpServer;
|
using OpenSim.Framework.Servers.HttpServer;
|
||||||
|
|
||||||
namespace OpenSim.Framework.Servers
|
namespace OpenSim.Framework.Servers
|
||||||
{
|
{
|
||||||
public class MainServer
|
public class MainServer
|
||||||
{
|
{
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
private static BaseHttpServer instance = null;
|
private static BaseHttpServer instance = null;
|
||||||
private static Dictionary<uint, BaseHttpServer> m_Servers =
|
private static Dictionary<uint, BaseHttpServer> m_Servers = new Dictionary<uint, BaseHttpServer>();
|
||||||
new Dictionary<uint, BaseHttpServer>();
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Control the printing of certain debug messages.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// If DebugLevel >= 1, then short warnings are logged when receiving bad input data.
|
||||||
|
/// If DebugLevel >= 2, then long warnings are logged when receiving bad input data.
|
||||||
|
/// If DebugLevel >= 3, then short notices about all incoming non-poll HTTP requests are logged.
|
||||||
|
/// </remarks>
|
||||||
|
public static int DebugLevel
|
||||||
|
{
|
||||||
|
get { return s_debugLevel; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
s_debugLevel = value;
|
||||||
|
|
||||||
|
lock (m_Servers)
|
||||||
|
foreach (BaseHttpServer server in m_Servers.Values)
|
||||||
|
server.DebugLevel = s_debugLevel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int s_debugLevel;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set the main HTTP server instance.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This will be used to register all handlers that listen to the default port.
|
||||||
|
/// </remarks>
|
||||||
|
/// <exception cref='Exception'>
|
||||||
|
/// Thrown if the HTTP server has not already been registered via AddHttpServer()
|
||||||
|
/// </exception>
|
||||||
public static BaseHttpServer Instance
|
public static BaseHttpServer Instance
|
||||||
{
|
{
|
||||||
get { return instance; }
|
get { return instance; }
|
||||||
set { instance = value; }
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
lock (m_Servers)
|
||||||
|
if (!m_Servers.ContainsValue(value))
|
||||||
|
throw new Exception("HTTP server must already have been registered to be set as the main instance");
|
||||||
|
|
||||||
|
instance = value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get all the registered servers.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Returns a copy of the dictionary so this can be iterated through without locking.
|
||||||
|
/// </remarks>
|
||||||
|
/// <value></value>
|
||||||
|
public static Dictionary<uint, BaseHttpServer> Servers
|
||||||
|
{
|
||||||
|
get { return new Dictionary<uint, BaseHttpServer>(m_Servers); }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void RegisterHttpConsoleCommands(ICommandConsole console)
|
||||||
|
{
|
||||||
|
console.Commands.AddCommand(
|
||||||
|
"Comms", false, "show http-handlers",
|
||||||
|
"show http-handlers",
|
||||||
|
"Show all registered http handlers", HandleShowHttpHandlersCommand);
|
||||||
|
|
||||||
|
console.Commands.AddCommand(
|
||||||
|
"Debug", false, "debug http", "debug http [<level>]",
|
||||||
|
"Turn on inbound non-poll http request debugging.",
|
||||||
|
"If level <= 0, then no extra logging is done.\n"
|
||||||
|
+ "If level >= 1, then short warnings are logged when receiving bad input data.\n"
|
||||||
|
+ "If level >= 2, then long warnings are logged when receiving bad input data.\n"
|
||||||
|
+ "If level >= 3, then short notices about all incoming non-poll HTTP requests are logged.\n"
|
||||||
|
+ "If level >= 4, then a sample from the beginning of the incoming data is logged.\n"
|
||||||
|
+ "If level >= 5, then the entire incoming data is logged.\n"
|
||||||
|
+ "If no level is specified then the current level is returned.",
|
||||||
|
HandleDebugHttpCommand);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Turn on some debugging values for OpenSim.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="args"></param>
|
||||||
|
private static void HandleDebugHttpCommand(string module, string[] args)
|
||||||
|
{
|
||||||
|
if (args.Length == 3)
|
||||||
|
{
|
||||||
|
int newDebug;
|
||||||
|
if (int.TryParse(args[2], out newDebug))
|
||||||
|
{
|
||||||
|
MainServer.DebugLevel = newDebug;
|
||||||
|
MainConsole.Instance.OutputFormat("Debug http level set to {0}", newDebug);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (args.Length == 2)
|
||||||
|
{
|
||||||
|
MainConsole.Instance.OutputFormat("Current debug http level is {0}", MainServer.DebugLevel);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MainConsole.Instance.Output("Usage: debug http 0..5");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void HandleShowHttpHandlersCommand(string module, string[] args)
|
||||||
|
{
|
||||||
|
if (args.Length != 2)
|
||||||
|
{
|
||||||
|
MainConsole.Instance.Output("Usage: show http-handlers");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder handlers = new StringBuilder();
|
||||||
|
|
||||||
|
lock (m_Servers)
|
||||||
|
{
|
||||||
|
foreach (BaseHttpServer httpServer in m_Servers.Values)
|
||||||
|
{
|
||||||
|
handlers.AppendFormat(
|
||||||
|
"Registered HTTP Handlers for server at {0}:{1}\n", httpServer.ListenIPAddress, httpServer.Port);
|
||||||
|
|
||||||
|
handlers.AppendFormat("* XMLRPC:\n");
|
||||||
|
foreach (String s in httpServer.GetXmlRpcHandlerKeys())
|
||||||
|
handlers.AppendFormat("\t{0}\n", s);
|
||||||
|
|
||||||
|
handlers.AppendFormat("* HTTP:\n");
|
||||||
|
List<String> poll = httpServer.GetPollServiceHandlerKeys();
|
||||||
|
foreach (String s in httpServer.GetHTTPHandlerKeys())
|
||||||
|
handlers.AppendFormat("\t{0} {1}\n", s, (poll.Contains(s) ? "(poll service)" : string.Empty));
|
||||||
|
|
||||||
|
handlers.AppendFormat("* Agent:\n");
|
||||||
|
foreach (String s in httpServer.GetAgentHandlerKeys())
|
||||||
|
handlers.AppendFormat("\t{0}\n", s);
|
||||||
|
|
||||||
|
handlers.AppendFormat("* LLSD:\n");
|
||||||
|
foreach (String s in httpServer.GetLLSDHandlerKeys())
|
||||||
|
handlers.AppendFormat("\t{0}\n", s);
|
||||||
|
|
||||||
|
handlers.AppendFormat("* StreamHandlers ({0}):\n", httpServer.GetStreamHandlerKeys().Count);
|
||||||
|
foreach (String s in httpServer.GetStreamHandlerKeys())
|
||||||
|
handlers.AppendFormat("\t{0}\n", s);
|
||||||
|
|
||||||
|
handlers.Append("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MainConsole.Instance.Output(handlers.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Register an already started HTTP server to the collection of known servers.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name='server'></param>
|
||||||
|
public static void AddHttpServer(BaseHttpServer server)
|
||||||
|
{
|
||||||
|
lock (m_Servers)
|
||||||
|
{
|
||||||
|
if (m_Servers.ContainsKey(server.Port))
|
||||||
|
throw new Exception(string.Format("HTTP server for port {0} already exists.", server.Port));
|
||||||
|
|
||||||
|
m_Servers.Add(server.Port, server);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Removes the http server listening on the given port.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// It is the responsibility of the caller to do clean up.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name='port'></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static bool RemoveHttpServer(uint port)
|
||||||
|
{
|
||||||
|
lock (m_Servers)
|
||||||
|
return m_Servers.Remove(port);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Does this collection of servers contain one with the given port?
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Unlike GetHttpServer, this will not instantiate a server if one does not exist on that port.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name='port'></param>
|
||||||
|
/// <returns>true if a server with the given port is registered, false otherwise.</returns>
|
||||||
|
public static bool ContainsHttpServer(uint port)
|
||||||
|
{
|
||||||
|
lock (m_Servers)
|
||||||
|
return m_Servers.ContainsKey(port);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the default http server or an http server for a specific port.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// If the requested HTTP server doesn't already exist then a new one is instantiated and started.
|
||||||
|
/// </remarks>
|
||||||
|
/// <returns></returns>
|
||||||
|
/// <param name='port'>If 0 then the default HTTP server is returned.</param>
|
||||||
public static IHttpServer GetHttpServer(uint port)
|
public static IHttpServer GetHttpServer(uint port)
|
||||||
{
|
{
|
||||||
return GetHttpServer(port, null);
|
return GetHttpServer(port, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void AddHttpServer(BaseHttpServer server)
|
/// <summary>
|
||||||
{
|
/// Get the default http server, an http server for a specific port
|
||||||
m_Servers.Add(server.Port, server);
|
/// and/or an http server bound to a specific address
|
||||||
}
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// If the requested HTTP server doesn't already exist then a new one is instantiated and started.
|
||||||
|
/// </remarks>
|
||||||
|
/// <returns></returns>
|
||||||
|
/// <param name='port'>If 0 then the default HTTP server is returned.</param>
|
||||||
|
/// <param name='ipaddr'>A specific IP address to bind to. If null then the default IP address is used.</param>
|
||||||
public static IHttpServer GetHttpServer(uint port, IPAddress ipaddr)
|
public static IHttpServer GetHttpServer(uint port, IPAddress ipaddr)
|
||||||
{
|
{
|
||||||
if (port == 0)
|
if (port == 0)
|
||||||
return Instance;
|
return Instance;
|
||||||
|
|
||||||
if (instance != null && port == Instance.Port)
|
if (instance != null && port == Instance.Port)
|
||||||
return Instance;
|
return Instance;
|
||||||
|
|
||||||
|
lock (m_Servers)
|
||||||
|
{
|
||||||
if (m_Servers.ContainsKey(port))
|
if (m_Servers.ContainsKey(port))
|
||||||
return m_Servers[port];
|
return m_Servers[port];
|
||||||
|
|
||||||
|
@ -72,10 +277,10 @@ namespace OpenSim.Framework.Servers
|
||||||
if (ipaddr != null)
|
if (ipaddr != null)
|
||||||
m_Servers[port].ListenIPAddress = ipaddr;
|
m_Servers[port].ListenIPAddress = ipaddr;
|
||||||
|
|
||||||
m_log.InfoFormat("[MAIN HTTP SERVER]: Starting main http server on port {0}", port);
|
|
||||||
m_Servers[port].Start();
|
m_Servers[port].Start();
|
||||||
|
|
||||||
return m_Servers[port];
|
return m_Servers[port];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
|
@ -30,7 +30,7 @@ namespace OpenSim
|
||||||
public class VersionInfo
|
public class VersionInfo
|
||||||
{
|
{
|
||||||
private const string VERSION_NUMBER = "0.7.3";
|
private const string VERSION_NUMBER = "0.7.3";
|
||||||
private const Flavour VERSION_FLAVOUR = Flavour.Dev;
|
private const Flavour VERSION_FLAVOUR = Flavour.Extended;
|
||||||
|
|
||||||
public enum Flavour
|
public enum Flavour
|
||||||
{
|
{
|
||||||
|
@ -39,7 +39,8 @@ namespace OpenSim
|
||||||
RC1,
|
RC1,
|
||||||
RC2,
|
RC2,
|
||||||
Release,
|
Release,
|
||||||
Post_Fixes
|
Post_Fixes,
|
||||||
|
Extended
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string Version
|
public static string Version
|
||||||
|
|
|
@ -26,8 +26,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
using OpenMetaverse.StructuredData;
|
using OpenMetaverse.StructuredData;
|
||||||
|
|
||||||
|
@ -44,10 +44,18 @@ namespace OpenSim.Framework.Statistics
|
||||||
StringBuilder sb = new StringBuilder(Environment.NewLine);
|
StringBuilder sb = new StringBuilder(Environment.NewLine);
|
||||||
sb.Append("MEMORY STATISTICS");
|
sb.Append("MEMORY STATISTICS");
|
||||||
sb.Append(Environment.NewLine);
|
sb.Append(Environment.NewLine);
|
||||||
sb.Append(
|
|
||||||
string.Format(
|
sb.AppendFormat(
|
||||||
"Allocated to OpenSim : {0} MB" + Environment.NewLine,
|
"Allocated to OpenSim objects: {0} MB\n",
|
||||||
Math.Round(GC.GetTotalMemory(false) / 1024.0 / 1024.0)));
|
Math.Round(GC.GetTotalMemory(false) / 1024.0 / 1024.0));
|
||||||
|
|
||||||
|
sb.AppendFormat(
|
||||||
|
"OpenSim object memory churn : {0} MB/s\n",
|
||||||
|
Math.Round((MemoryWatchdog.AverageMemoryChurn * 1000) / 1024.0 / 1024, 3));
|
||||||
|
|
||||||
|
sb.AppendFormat(
|
||||||
|
"Process memory : {0} MB\n",
|
||||||
|
Math.Round(Process.GetCurrentProcess().WorkingSet64 / 1024.0 / 1024.0));
|
||||||
|
|
||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,14 +34,12 @@ namespace OpenSim.Framework.Statistics
|
||||||
{
|
{
|
||||||
private static AssetStatsCollector assetStats;
|
private static AssetStatsCollector assetStats;
|
||||||
private static UserStatsCollector userStats;
|
private static UserStatsCollector userStats;
|
||||||
private static SimExtraStatsCollector simExtraStats;
|
private static SimExtraStatsCollector simExtraStats = new SimExtraStatsCollector();
|
||||||
|
|
||||||
public static AssetStatsCollector AssetStats { get { return assetStats; } }
|
public static AssetStatsCollector AssetStats { get { return assetStats; } }
|
||||||
public static UserStatsCollector UserStats { get { return userStats; } }
|
public static UserStatsCollector UserStats { get { return userStats; } }
|
||||||
public static SimExtraStatsCollector SimExtraStats { get { return simExtraStats; } }
|
public static SimExtraStatsCollector SimExtraStats { get { return simExtraStats; } }
|
||||||
|
|
||||||
private StatsManager() {}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Start collecting statistics related to assets.
|
/// Start collecting statistics related to assets.
|
||||||
/// Should only be called once.
|
/// Should only be called once.
|
||||||
|
@ -63,16 +61,5 @@ namespace OpenSim.Framework.Statistics
|
||||||
|
|
||||||
return userStats;
|
return userStats;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Start collecting extra sim statistics apart from those collected for the client.
|
|
||||||
/// Should only be called once.
|
|
||||||
/// </summary>
|
|
||||||
public static SimExtraStatsCollector StartCollectingSimExtraStats()
|
|
||||||
{
|
|
||||||
simExtraStats = new SimExtraStatsCollector();
|
|
||||||
|
|
||||||
return simExtraStats;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -81,12 +81,15 @@ namespace OpenSim.Framework
|
||||||
|
|
||||||
private static uint nextXferID = 5000;
|
private static uint nextXferID = 5000;
|
||||||
private static Random randomClass = new Random();
|
private static Random randomClass = new Random();
|
||||||
|
|
||||||
// Get a list of invalid file characters (OS dependent)
|
// Get a list of invalid file characters (OS dependent)
|
||||||
private static string regexInvalidFileChars = "[" + new String(Path.GetInvalidFileNameChars()) + "]";
|
private static string regexInvalidFileChars = "[" + new String(Path.GetInvalidFileNameChars()) + "]";
|
||||||
private static string regexInvalidPathChars = "[" + new String(Path.GetInvalidPathChars()) + "]";
|
private static string regexInvalidPathChars = "[" + new String(Path.GetInvalidPathChars()) + "]";
|
||||||
private static object XferLock = new object();
|
private static object XferLock = new object();
|
||||||
/// <summary>Thread pool used for Util.FireAndForget if
|
|
||||||
/// FireAndForgetMethod.SmartThreadPool is used</summary>
|
/// <summary>
|
||||||
|
/// Thread pool used for Util.FireAndForget if FireAndForgetMethod.SmartThreadPool is used
|
||||||
|
/// </summary>
|
||||||
private static SmartThreadPool m_ThreadPool;
|
private static SmartThreadPool m_ThreadPool;
|
||||||
|
|
||||||
// Unix-epoch starts at January 1st 1970, 00:00:00 UTC. And all our times in the server are (or at least should be) in UTC.
|
// Unix-epoch starts at January 1st 1970, 00:00:00 UTC. And all our times in the server are (or at least should be) in UTC.
|
||||||
|
@ -144,8 +147,8 @@ namespace OpenSim.Framework
|
||||||
return lerp(y, lerp(x, a, b), lerp(x, c, d));
|
return lerp(y, lerp(x, a, b), lerp(x, c, d));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static Encoding UTF8 = Encoding.UTF8;
|
public static Encoding UTF8 = Encoding.UTF8;
|
||||||
|
public static Encoding UTF8NoBomEncoding = new UTF8Encoding(false);
|
||||||
|
|
||||||
/// <value>
|
/// <value>
|
||||||
/// Well known UUID for the blank texture used in the Linden SL viewer version 1.20 (and hopefully onwards)
|
/// Well known UUID for the blank texture used in the Linden SL viewer version 1.20 (and hopefully onwards)
|
||||||
|
@ -998,6 +1001,38 @@ namespace OpenSim.Framework
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Copy data from one stream to another, leaving the read position of both streams at the beginning.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name='inputStream'>
|
||||||
|
/// Input stream. Must be seekable.
|
||||||
|
/// </param>
|
||||||
|
/// <exception cref='ArgumentException'>
|
||||||
|
/// Thrown if the input stream is not seekable.
|
||||||
|
/// </exception>
|
||||||
|
public static Stream Copy(Stream inputStream)
|
||||||
|
{
|
||||||
|
if (!inputStream.CanSeek)
|
||||||
|
throw new ArgumentException("Util.Copy(Stream inputStream) must receive an inputStream that can seek");
|
||||||
|
|
||||||
|
const int readSize = 256;
|
||||||
|
byte[] buffer = new byte[readSize];
|
||||||
|
MemoryStream ms = new MemoryStream();
|
||||||
|
|
||||||
|
int count = inputStream.Read(buffer, 0, readSize);
|
||||||
|
|
||||||
|
while (count > 0)
|
||||||
|
{
|
||||||
|
ms.Write(buffer, 0, count);
|
||||||
|
count = inputStream.Read(buffer, 0, readSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
ms.Position = 0;
|
||||||
|
inputStream.Position = 0;
|
||||||
|
|
||||||
|
return ms;
|
||||||
|
}
|
||||||
|
|
||||||
public static XmlRpcResponse XmlRpcCommand(string url, string methodName, params object[] args)
|
public static XmlRpcResponse XmlRpcCommand(string url, string methodName, params object[] args)
|
||||||
{
|
{
|
||||||
return SendXmlRpcCommand(url, methodName, args);
|
return SendXmlRpcCommand(url, methodName, args);
|
||||||
|
@ -1234,8 +1269,7 @@ namespace OpenSim.Framework
|
||||||
|
|
||||||
public static string Base64ToString(string str)
|
public static string Base64ToString(string str)
|
||||||
{
|
{
|
||||||
UTF8Encoding encoder = new UTF8Encoding();
|
Decoder utf8Decode = Encoding.UTF8.GetDecoder();
|
||||||
Decoder utf8Decode = encoder.GetDecoder();
|
|
||||||
|
|
||||||
byte[] todecode_byte = Convert.FromBase64String(str);
|
byte[] todecode_byte = Convert.FromBase64String(str);
|
||||||
int charCount = utf8Decode.GetCharCount(todecode_byte, 0, todecode_byte.Length);
|
int charCount = utf8Decode.GetCharCount(todecode_byte, 0, todecode_byte.Length);
|
||||||
|
@ -1671,6 +1705,61 @@ namespace OpenSim.Framework
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get a thread pool report.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static string GetThreadPoolReport()
|
||||||
|
{
|
||||||
|
string threadPoolUsed = null;
|
||||||
|
int maxThreads = 0;
|
||||||
|
int minThreads = 0;
|
||||||
|
int allocatedThreads = 0;
|
||||||
|
int inUseThreads = 0;
|
||||||
|
int waitingCallbacks = 0;
|
||||||
|
int completionPortThreads = 0;
|
||||||
|
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
if (FireAndForgetMethod == FireAndForgetMethod.SmartThreadPool)
|
||||||
|
{
|
||||||
|
threadPoolUsed = "SmartThreadPool";
|
||||||
|
maxThreads = m_ThreadPool.MaxThreads;
|
||||||
|
minThreads = m_ThreadPool.MinThreads;
|
||||||
|
inUseThreads = m_ThreadPool.InUseThreads;
|
||||||
|
allocatedThreads = m_ThreadPool.ActiveThreads;
|
||||||
|
waitingCallbacks = m_ThreadPool.WaitingCallbacks;
|
||||||
|
}
|
||||||
|
else if (
|
||||||
|
FireAndForgetMethod == FireAndForgetMethod.UnsafeQueueUserWorkItem
|
||||||
|
|| FireAndForgetMethod == FireAndForgetMethod.UnsafeQueueUserWorkItem)
|
||||||
|
{
|
||||||
|
threadPoolUsed = "BuiltInThreadPool";
|
||||||
|
ThreadPool.GetMaxThreads(out maxThreads, out completionPortThreads);
|
||||||
|
ThreadPool.GetMinThreads(out minThreads, out completionPortThreads);
|
||||||
|
int availableThreads;
|
||||||
|
ThreadPool.GetAvailableThreads(out availableThreads, out completionPortThreads);
|
||||||
|
inUseThreads = maxThreads - availableThreads;
|
||||||
|
allocatedThreads = -1;
|
||||||
|
waitingCallbacks = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (threadPoolUsed != null)
|
||||||
|
{
|
||||||
|
sb.AppendFormat("Thread pool used : {0}\n", threadPoolUsed);
|
||||||
|
sb.AppendFormat("Max threads : {0}\n", maxThreads);
|
||||||
|
sb.AppendFormat("Min threads : {0}\n", minThreads);
|
||||||
|
sb.AppendFormat("Allocated threads : {0}\n", allocatedThreads < 0 ? "not applicable" : allocatedThreads.ToString());
|
||||||
|
sb.AppendFormat("In use threads : {0}\n", inUseThreads);
|
||||||
|
sb.AppendFormat("Work items waiting : {0}\n", waitingCallbacks < 0 ? "not available" : waitingCallbacks.ToString());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sb.AppendFormat("Thread pool not used\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
private static object SmartThreadPoolCallback(object o)
|
private static object SmartThreadPoolCallback(object o)
|
||||||
{
|
{
|
||||||
object[] array = (object[])o;
|
object[] array = (object[])o;
|
||||||
|
@ -1696,6 +1785,20 @@ namespace OpenSim.Framework
|
||||||
}
|
}
|
||||||
const Int32 EnvironmentTickCountMask = 0x3fffffff;
|
const Int32 EnvironmentTickCountMask = 0x3fffffff;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Environment.TickCount is an int but it counts all 32 bits so it goes positive
|
||||||
|
/// and negative every 24.9 days. Subtracts the passed value (previously fetched by
|
||||||
|
/// 'EnvironmentTickCount()') and accounts for any wrapping.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="newValue"></param>
|
||||||
|
/// <param name="prevValue"></param>
|
||||||
|
/// <returns>subtraction of passed prevValue from current Environment.TickCount</returns>
|
||||||
|
public static Int32 EnvironmentTickCountSubtract(Int32 newValue, Int32 prevValue)
|
||||||
|
{
|
||||||
|
Int32 diff = newValue - prevValue;
|
||||||
|
return (diff >= 0) ? diff : (diff + EnvironmentTickCountMask + 1);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Environment.TickCount is an int but it counts all 32 bits so it goes positive
|
/// Environment.TickCount is an int but it counts all 32 bits so it goes positive
|
||||||
/// and negative every 24.9 days. Subtracts the passed value (previously fetched by
|
/// and negative every 24.9 days. Subtracts the passed value (previously fetched by
|
||||||
|
@ -1704,8 +1807,7 @@ namespace OpenSim.Framework
|
||||||
/// <returns>subtraction of passed prevValue from current Environment.TickCount</returns>
|
/// <returns>subtraction of passed prevValue from current Environment.TickCount</returns>
|
||||||
public static Int32 EnvironmentTickCountSubtract(Int32 prevValue)
|
public static Int32 EnvironmentTickCountSubtract(Int32 prevValue)
|
||||||
{
|
{
|
||||||
Int32 diff = EnvironmentTickCount() - prevValue;
|
return EnvironmentTickCountSubtract(EnvironmentTickCount(), prevValue);
|
||||||
return (diff >= 0) ? diff : (diff + EnvironmentTickCountMask + 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns value of Tick Count A - TickCount B accounting for wrapping of TickCount
|
// Returns value of Tick Count A - TickCount B accounting for wrapping of TickCount
|
||||||
|
|
|
@ -41,8 +41,8 @@ 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>Default timeout in milliseconds before a thread is considered dead</summary>
|
||||||
const int WATCHDOG_TIMEOUT_MS = 5000;
|
public const int DEFAULT_WATCHDOG_TIMEOUT_MS = 5000;
|
||||||
|
|
||||||
[System.Diagnostics.DebuggerDisplay("{Thread.Name}")]
|
[System.Diagnostics.DebuggerDisplay("{Thread.Name}")]
|
||||||
public class ThreadWatchdogInfo
|
public class ThreadWatchdogInfo
|
||||||
|
@ -58,7 +58,7 @@ namespace OpenSim.Framework
|
||||||
public int FirstTick { get; private set; }
|
public int FirstTick { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// First time this heartbeat update was invoked
|
/// Last time this heartbeat update was invoked
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int LastTick { get; set; }
|
public int LastTick { get; set; }
|
||||||
|
|
||||||
|
@ -77,6 +77,11 @@ namespace OpenSim.Framework
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool AlarmIfTimeout { get; set; }
|
public bool AlarmIfTimeout { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Method execute if alarm goes off. If null then no alarm method is fired.
|
||||||
|
/// </summary>
|
||||||
|
public Func<string> AlarmMethod { get; set; }
|
||||||
|
|
||||||
public ThreadWatchdogInfo(Thread thread, int timeout)
|
public ThreadWatchdogInfo(Thread thread, int timeout)
|
||||||
{
|
{
|
||||||
Thread = thread;
|
Thread = thread;
|
||||||
|
@ -87,27 +92,33 @@ namespace OpenSim.Framework
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This event is called whenever a tracked thread is stopped or
|
/// This event is called whenever a tracked thread is
|
||||||
/// has not called UpdateThread() in time
|
/// stopped or has not called UpdateThread() in time<
|
||||||
/// </summary>
|
/// /summary>
|
||||||
/// <param name="thread">The thread that has been identified as dead</param>
|
public static event Action<ThreadWatchdogInfo> OnWatchdogTimeout;
|
||||||
/// <param name="lastTick">The last time this thread called UpdateThread()</param>
|
|
||||||
public delegate void WatchdogTimeout(Thread thread, int lastTick);
|
|
||||||
|
|
||||||
/// <summary>This event is called whenever a tracked thread is
|
|
||||||
/// stopped or has not called UpdateThread() in time</summary>
|
|
||||||
public static event WatchdogTimeout OnWatchdogTimeout;
|
|
||||||
|
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
private static Dictionary<int, ThreadWatchdogInfo> m_threads;
|
private static Dictionary<int, ThreadWatchdogInfo> m_threads;
|
||||||
private static System.Timers.Timer m_watchdogTimer;
|
private static System.Timers.Timer m_watchdogTimer;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Last time the watchdog thread ran.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Should run every WATCHDOG_INTERVAL_MS
|
||||||
|
/// </remarks>
|
||||||
|
public static int LastWatchdogThreadTick { get; private set; }
|
||||||
|
|
||||||
static Watchdog()
|
static Watchdog()
|
||||||
{
|
{
|
||||||
m_threads = new Dictionary<int, ThreadWatchdogInfo>();
|
m_threads = new Dictionary<int, ThreadWatchdogInfo>();
|
||||||
m_watchdogTimer = new System.Timers.Timer(WATCHDOG_INTERVAL_MS);
|
m_watchdogTimer = new System.Timers.Timer(WATCHDOG_INTERVAL_MS);
|
||||||
m_watchdogTimer.AutoReset = false;
|
m_watchdogTimer.AutoReset = false;
|
||||||
m_watchdogTimer.Elapsed += WatchdogTimerElapsed;
|
m_watchdogTimer.Elapsed += WatchdogTimerElapsed;
|
||||||
|
|
||||||
|
// Set now so we don't get alerted on the first run
|
||||||
|
LastWatchdogThreadTick = Environment.TickCount & Int32.MaxValue;
|
||||||
|
|
||||||
m_watchdogTimer.Start();
|
m_watchdogTimer.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,7 +134,7 @@ namespace OpenSim.Framework
|
||||||
public static Thread StartThread(
|
public static Thread StartThread(
|
||||||
ThreadStart start, string name, ThreadPriority priority, bool isBackground, bool alarmIfTimeout)
|
ThreadStart start, string name, ThreadPriority priority, bool isBackground, bool alarmIfTimeout)
|
||||||
{
|
{
|
||||||
return StartThread(start, name, priority, isBackground, alarmIfTimeout, WATCHDOG_TIMEOUT_MS);
|
return StartThread(start, name, priority, isBackground, alarmIfTimeout, null, DEFAULT_WATCHDOG_TIMEOUT_MS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -135,17 +146,24 @@ namespace OpenSim.Framework
|
||||||
/// <param name="isBackground">True to run this thread as a background
|
/// <param name="isBackground">True to run this thread as a background
|
||||||
/// thread, otherwise false</param>
|
/// thread, otherwise false</param>
|
||||||
/// <param name="alarmIfTimeout">Trigger an alarm function is we have timed out</param>
|
/// <param name="alarmIfTimeout">Trigger an alarm function is we have timed out</param>
|
||||||
|
/// <param name="alarmMethod">
|
||||||
|
/// Alarm method to call if alarmIfTimeout is true and there is a timeout.
|
||||||
|
/// Normally, this will just return some useful debugging information.
|
||||||
|
/// </param>
|
||||||
/// <param name="timeout">Number of milliseconds to wait until we issue a warning about timeout.</param>
|
/// <param name="timeout">Number of milliseconds to wait until we issue a warning about timeout.</param>
|
||||||
/// <returns>The newly created Thread object</returns>
|
/// <returns>The newly created Thread object</returns>
|
||||||
public static Thread StartThread(
|
public static Thread StartThread(
|
||||||
ThreadStart start, string name, ThreadPriority priority, bool isBackground, bool alarmIfTimeout, int timeout)
|
ThreadStart start, string name, ThreadPriority priority, bool isBackground,
|
||||||
|
bool alarmIfTimeout, Func<string> alarmMethod, 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) { AlarmIfTimeout = alarmIfTimeout };
|
ThreadWatchdogInfo twi
|
||||||
|
= new ThreadWatchdogInfo(thread, timeout)
|
||||||
|
{ AlarmIfTimeout = alarmIfTimeout, AlarmMethod = alarmMethod };
|
||||||
|
|
||||||
m_log.DebugFormat(
|
m_log.DebugFormat(
|
||||||
"[WATCHDOG]: Started tracking thread {0}, ID {1}", twi.Thread.Name, twi.Thread.ManagedThreadId);
|
"[WATCHDOG]: Started tracking thread {0}, ID {1}", twi.Thread.Name, twi.Thread.ManagedThreadId);
|
||||||
|
@ -258,7 +276,17 @@ namespace OpenSim.Framework
|
||||||
/// <param name="e"></param>
|
/// <param name="e"></param>
|
||||||
private static void WatchdogTimerElapsed(object sender, System.Timers.ElapsedEventArgs e)
|
private static void WatchdogTimerElapsed(object sender, System.Timers.ElapsedEventArgs e)
|
||||||
{
|
{
|
||||||
WatchdogTimeout callback = OnWatchdogTimeout;
|
int now = Environment.TickCount & Int32.MaxValue;
|
||||||
|
int msElapsed = now - LastWatchdogThreadTick;
|
||||||
|
|
||||||
|
if (msElapsed > WATCHDOG_INTERVAL_MS * 2)
|
||||||
|
m_log.WarnFormat(
|
||||||
|
"[WATCHDOG]: {0} ms since Watchdog last ran. Interval should be approximately {1} ms",
|
||||||
|
msElapsed, WATCHDOG_INTERVAL_MS);
|
||||||
|
|
||||||
|
LastWatchdogThreadTick = Environment.TickCount & Int32.MaxValue;
|
||||||
|
|
||||||
|
Action<ThreadWatchdogInfo> callback = OnWatchdogTimeout;
|
||||||
|
|
||||||
if (callback != null)
|
if (callback != null)
|
||||||
{
|
{
|
||||||
|
@ -266,8 +294,6 @@ namespace OpenSim.Framework
|
||||||
|
|
||||||
lock (m_threads)
|
lock (m_threads)
|
||||||
{
|
{
|
||||||
int now = Environment.TickCount & Int32.MaxValue;
|
|
||||||
|
|
||||||
foreach (ThreadWatchdogInfo threadInfo in m_threads.Values)
|
foreach (ThreadWatchdogInfo threadInfo in m_threads.Values)
|
||||||
{
|
{
|
||||||
if (threadInfo.Thread.ThreadState == ThreadState.Stopped)
|
if (threadInfo.Thread.ThreadState == ThreadState.Stopped)
|
||||||
|
@ -296,9 +322,12 @@ namespace OpenSim.Framework
|
||||||
|
|
||||||
if (callbackInfos != null)
|
if (callbackInfos != null)
|
||||||
foreach (ThreadWatchdogInfo callbackInfo in callbackInfos)
|
foreach (ThreadWatchdogInfo callbackInfo in callbackInfos)
|
||||||
callback(callbackInfo.Thread, callbackInfo.LastTick);
|
callback(callbackInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (MemoryWatchdog.Enabled)
|
||||||
|
MemoryWatchdog.Update();
|
||||||
|
|
||||||
m_watchdogTimer.Start();
|
m_watchdogTimer.Start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,45 +53,36 @@ namespace OpenSim.Framework
|
||||||
LogManager.GetLogger(
|
LogManager.GetLogger(
|
||||||
MethodBase.GetCurrentMethod().DeclaringType);
|
MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
private static int m_requestNumber = 0;
|
/// <summary>
|
||||||
|
/// Request number for diagnostic purposes.
|
||||||
|
/// </summary>
|
||||||
|
public static int RequestNumber = 0;
|
||||||
|
|
||||||
// this is the header field used to communicate the local request id
|
/// <summary>
|
||||||
// used for performance and debugging
|
/// this is the header field used to communicate the local request id
|
||||||
|
/// used for performance and debugging
|
||||||
|
/// </summary>
|
||||||
public const string OSHeaderRequestID = "opensim-request-id";
|
public const string OSHeaderRequestID = "opensim-request-id";
|
||||||
|
|
||||||
// number of milliseconds a call can take before it is considered
|
/// <summary>
|
||||||
// a "long" call for warning & debugging purposes
|
/// Number of milliseconds a call can take before it is considered
|
||||||
public const int LongCallTime = 500;
|
/// a "long" call for warning & debugging purposes
|
||||||
|
/// </summary>
|
||||||
|
public const int LongCallTime = 3000;
|
||||||
|
|
||||||
// /// <summary>
|
/// <summary>
|
||||||
// /// Send LLSD to an HTTP client in application/llsd+json form
|
/// The maximum length of any data logged because of a long request time.
|
||||||
// /// </summary>
|
/// </summary>
|
||||||
// /// <param name="response">HTTP response to send the data in</param>
|
/// <remarks>
|
||||||
// /// <param name="body">LLSD to send to the client</param>
|
/// This is to truncate any really large post data, such as an asset. In theory, the first section should
|
||||||
// public static void SendJSONResponse(OSHttpResponse response, OSDMap body)
|
/// give us useful information about the call (which agent it relates to if applicable, etc.).
|
||||||
// {
|
/// </remarks>
|
||||||
// byte[] responseData = Encoding.UTF8.GetBytes(OSDParser.SerializeJsonString(body));
|
public const int MaxRequestDiagLength = 100;
|
||||||
//
|
|
||||||
// response.ContentEncoding = Encoding.UTF8;
|
/// <summary>
|
||||||
// response.ContentLength = responseData.Length;
|
/// Dictionary of end points
|
||||||
// response.ContentType = "application/llsd+json";
|
/// </summary>
|
||||||
// response.Body.Write(responseData, 0, responseData.Length);
|
private static Dictionary<string,object> m_endpointSerializer = new Dictionary<string,object>();
|
||||||
// }
|
|
||||||
//
|
|
||||||
// /// <summary>
|
|
||||||
// /// Send LLSD to an HTTP client in application/llsd+xml form
|
|
||||||
// /// </summary>
|
|
||||||
// /// <param name="response">HTTP response to send the data in</param>
|
|
||||||
// /// <param name="body">LLSD to send to the client</param>
|
|
||||||
// public static void SendXMLResponse(OSHttpResponse response, OSDMap body)
|
|
||||||
// {
|
|
||||||
// byte[] responseData = OSDParser.SerializeLLSDXmlBytes(body);
|
|
||||||
//
|
|
||||||
// response.ContentEncoding = Encoding.UTF8;
|
|
||||||
// response.ContentLength = responseData.Length;
|
|
||||||
// response.ContentType = "application/llsd+xml";
|
|
||||||
// response.Body.Write(responseData, 0, responseData.Length);
|
|
||||||
// }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <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
|
||||||
|
@ -166,12 +157,14 @@ namespace OpenSim.Framework
|
||||||
|
|
||||||
public static OSDMap ServiceOSDRequest(string url, OSDMap data, string method, int timeout, bool compressed)
|
public static OSDMap ServiceOSDRequest(string url, OSDMap data, string method, int timeout, bool compressed)
|
||||||
{
|
{
|
||||||
int reqnum = m_requestNumber++;
|
int reqnum = RequestNumber++;
|
||||||
|
|
||||||
// m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method);
|
// m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method);
|
||||||
|
|
||||||
string errorMessage = "unknown error";
|
string errorMessage = "unknown error";
|
||||||
int tickstart = Util.EnvironmentTickCount();
|
int tickstart = Util.EnvironmentTickCount();
|
||||||
int tickdata = 0;
|
int tickdata = 0;
|
||||||
|
string strBuffer = null;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -186,7 +179,7 @@ namespace OpenSim.Framework
|
||||||
// If there is some input, write it into the request
|
// If there is some input, write it into the request
|
||||||
if (data != null)
|
if (data != null)
|
||||||
{
|
{
|
||||||
string strBuffer = OSDParser.SerializeJsonString(data);
|
strBuffer = OSDParser.SerializeJsonString(data);
|
||||||
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(strBuffer);
|
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(strBuffer);
|
||||||
|
|
||||||
if (compressed)
|
if (compressed)
|
||||||
|
@ -246,14 +239,23 @@ namespace OpenSim.Framework
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
// This just dumps a warning for any operation that takes more than 100 ms
|
|
||||||
int tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
|
int tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
|
||||||
if (tickdiff > LongCallTime)
|
if (tickdiff > LongCallTime)
|
||||||
m_log.DebugFormat("[WEB UTIL]: osd request <{0}> (URI:{1}, METHOD:{2}) took {3}ms overall, {4}ms writing",
|
m_log.InfoFormat(
|
||||||
reqnum,url,method,tickdiff,tickdata);
|
"[OSD REQUEST]: Slow request to <{0}> {1} {2} took {3}ms, {4}ms writing, {5}",
|
||||||
|
reqnum,
|
||||||
|
method,
|
||||||
|
url,
|
||||||
|
tickdiff,
|
||||||
|
tickdata,
|
||||||
|
strBuffer != null
|
||||||
|
? (strBuffer.Length > MaxRequestDiagLength ? strBuffer.Remove(MaxRequestDiagLength) : strBuffer)
|
||||||
|
: "");
|
||||||
}
|
}
|
||||||
|
|
||||||
m_log.DebugFormat("[WEB UTIL]: <{0}> osd request for {1}, method {2} FAILED: {3}", reqnum, url, method, errorMessage);
|
m_log.DebugFormat(
|
||||||
|
"[WEB UTIL]: <{0}> osd request for {1}, method {2} FAILED: {3}", reqnum, url, method, errorMessage);
|
||||||
|
|
||||||
return ErrorResponseMap(errorMessage);
|
return ErrorResponseMap(errorMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -314,17 +316,17 @@ namespace OpenSim.Framework
|
||||||
|
|
||||||
public static OSDMap ServiceFormRequest(string url, NameValueCollection data, int timeout)
|
public static OSDMap ServiceFormRequest(string url, NameValueCollection data, int timeout)
|
||||||
{
|
{
|
||||||
int reqnum = m_requestNumber++;
|
int reqnum = RequestNumber++;
|
||||||
string method = (data != null && data["RequestMethod"] != null) ? data["RequestMethod"] : "unknown";
|
string method = (data != null && data["RequestMethod"] != null) ? data["RequestMethod"] : "unknown";
|
||||||
// m_log.DebugFormat("[WEB UTIL]: <{0}> start form request for {1}, method {2}",reqnum,url,method);
|
// m_log.DebugFormat("[WEB UTIL]: <{0}> start form request for {1}, method {2}",reqnum,url,method);
|
||||||
|
|
||||||
string errorMessage = "unknown error";
|
string errorMessage = "unknown error";
|
||||||
int tickstart = Util.EnvironmentTickCount();
|
int tickstart = Util.EnvironmentTickCount();
|
||||||
int tickdata = 0;
|
int tickdata = 0;
|
||||||
|
string queryString = null;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
||||||
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
|
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
|
||||||
request.Method = "POST";
|
request.Method = "POST";
|
||||||
request.Timeout = timeout;
|
request.Timeout = timeout;
|
||||||
|
@ -335,7 +337,7 @@ namespace OpenSim.Framework
|
||||||
|
|
||||||
if (data != null)
|
if (data != null)
|
||||||
{
|
{
|
||||||
string queryString = BuildQueryString(data);
|
queryString = BuildQueryString(data);
|
||||||
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(queryString);
|
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(queryString);
|
||||||
|
|
||||||
request.ContentLength = buffer.Length;
|
request.ContentLength = buffer.Length;
|
||||||
|
@ -378,11 +380,20 @@ namespace OpenSim.Framework
|
||||||
{
|
{
|
||||||
int tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
|
int tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
|
||||||
if (tickdiff > LongCallTime)
|
if (tickdiff > LongCallTime)
|
||||||
m_log.InfoFormat("[WEB UTIL]: form request <{0}> (URI:{1}, METHOD:{2}) took {3}ms overall, {4}ms writing",
|
m_log.InfoFormat(
|
||||||
reqnum,url,method,tickdiff,tickdata);
|
"[SERVICE FORM]: Slow request to <{0}> {1} {2} took {3}ms, {4}ms writing, {5}",
|
||||||
|
reqnum,
|
||||||
|
method,
|
||||||
|
url,
|
||||||
|
tickdiff,
|
||||||
|
tickdata,
|
||||||
|
queryString != null
|
||||||
|
? (queryString.Length > MaxRequestDiagLength) ? queryString.Remove(MaxRequestDiagLength) : queryString
|
||||||
|
: "");
|
||||||
}
|
}
|
||||||
|
|
||||||
m_log.WarnFormat("[WEB UTIL]: <{0}> form request failed: {1}",reqnum,errorMessage);
|
m_log.WarnFormat("[SERVICE FORM]: <{0}> form request to {1} failed: {2}", reqnum, url, errorMessage);
|
||||||
|
|
||||||
return ErrorResponseMap(errorMessage);
|
return ErrorResponseMap(errorMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -655,8 +666,6 @@ namespace OpenSim.Framework
|
||||||
|
|
||||||
return new string[0];
|
return new string[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class AsynchronousRestObjectRequester
|
public static class AsynchronousRestObjectRequester
|
||||||
|
@ -679,6 +688,12 @@ namespace OpenSim.Framework
|
||||||
public static void MakeRequest<TRequest, TResponse>(string verb,
|
public static void MakeRequest<TRequest, TResponse>(string verb,
|
||||||
string requestUrl, TRequest obj, Action<TResponse> action)
|
string requestUrl, TRequest obj, Action<TResponse> action)
|
||||||
{
|
{
|
||||||
|
int reqnum = WebUtil.RequestNumber++;
|
||||||
|
// m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method);
|
||||||
|
|
||||||
|
int tickstart = Util.EnvironmentTickCount();
|
||||||
|
int tickdata = 0;
|
||||||
|
|
||||||
// m_log.DebugFormat("[ASYNC REQUEST]: Starting {0} {1}", verb, requestUrl);
|
// m_log.DebugFormat("[ASYNC REQUEST]: Starting {0} {1}", verb, requestUrl);
|
||||||
|
|
||||||
Type type = typeof(TRequest);
|
Type type = typeof(TRequest);
|
||||||
|
@ -689,12 +704,13 @@ namespace OpenSim.Framework
|
||||||
XmlSerializer deserializer = new XmlSerializer(typeof(TResponse));
|
XmlSerializer deserializer = new XmlSerializer(typeof(TResponse));
|
||||||
|
|
||||||
request.Method = verb;
|
request.Method = verb;
|
||||||
|
MemoryStream buffer = null;
|
||||||
|
|
||||||
if (verb == "POST")
|
if (verb == "POST")
|
||||||
{
|
{
|
||||||
request.ContentType = "text/xml";
|
request.ContentType = "text/xml";
|
||||||
|
|
||||||
MemoryStream buffer = new MemoryStream();
|
buffer = new MemoryStream();
|
||||||
|
|
||||||
XmlWriterSettings settings = new XmlWriterSettings();
|
XmlWriterSettings settings = new XmlWriterSettings();
|
||||||
settings.Encoding = Encoding.UTF8;
|
settings.Encoding = Encoding.UTF8;
|
||||||
|
@ -716,6 +732,9 @@ namespace OpenSim.Framework
|
||||||
requestStream.Write(buffer.ToArray(), 0, length);
|
requestStream.Write(buffer.ToArray(), 0, length);
|
||||||
requestStream.Close();
|
requestStream.Close();
|
||||||
|
|
||||||
|
// capture how much time was spent writing
|
||||||
|
tickdata = Util.EnvironmentTickCountSubtract(tickstart);
|
||||||
|
|
||||||
request.BeginGetResponse(delegate(IAsyncResult ar)
|
request.BeginGetResponse(delegate(IAsyncResult ar)
|
||||||
{
|
{
|
||||||
response = request.EndGetResponse(ar);
|
response = request.EndGetResponse(ar);
|
||||||
|
@ -741,11 +760,9 @@ namespace OpenSim.Framework
|
||||||
|
|
||||||
}, null);
|
}, null);
|
||||||
}, null);
|
}, null);
|
||||||
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
request.BeginGetResponse(delegate(IAsyncResult res2)
|
request.BeginGetResponse(delegate(IAsyncResult res2)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -789,12 +806,16 @@ namespace OpenSim.Framework
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_log.ErrorFormat("[ASYNC REQUEST]: Request {0} {1} failed with status {2} and message {3}", verb, requestUrl, e.Status, e.Message);
|
m_log.ErrorFormat(
|
||||||
|
"[ASYNC REQUEST]: Request {0} {1} failed with status {2} and message {3}",
|
||||||
|
verb, requestUrl, e.Status, e.Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
m_log.ErrorFormat("[ASYNC REQUEST]: Request {0} {1} failed with exception {2}", verb, requestUrl, e);
|
m_log.ErrorFormat(
|
||||||
|
"[ASYNC REQUEST]: Request {0} {1} failed with exception {2}{3}",
|
||||||
|
verb, requestUrl, e.Message, e.StackTrace);
|
||||||
}
|
}
|
||||||
|
|
||||||
// m_log.DebugFormat("[ASYNC REQUEST]: Received {0}", deserial.ToString());
|
// m_log.DebugFormat("[ASYNC REQUEST]: Received {0}", deserial.ToString());
|
||||||
|
@ -806,18 +827,41 @@ namespace OpenSim.Framework
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
m_log.ErrorFormat(
|
m_log.ErrorFormat(
|
||||||
"[ASYNC REQUEST]: Request {0} {1} callback failed with exception {2}", verb, requestUrl, e);
|
"[ASYNC REQUEST]: Request {0} {1} callback failed with exception {2}{3}",
|
||||||
|
verb, requestUrl, e.Message, e.StackTrace);
|
||||||
}
|
}
|
||||||
|
|
||||||
}, null);
|
}, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
|
||||||
|
if (tickdiff > WebUtil.LongCallTime)
|
||||||
|
{
|
||||||
|
string originalRequest = null;
|
||||||
|
|
||||||
|
if (buffer != null)
|
||||||
|
{
|
||||||
|
originalRequest = Encoding.UTF8.GetString(buffer.ToArray());
|
||||||
|
|
||||||
|
if (originalRequest.Length > WebUtil.MaxRequestDiagLength)
|
||||||
|
originalRequest = originalRequest.Remove(WebUtil.MaxRequestDiagLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_log.InfoFormat(
|
||||||
|
"[ASYNC REQUEST]: Slow request to <{0}> {1} {2} took {3}ms, {4}ms writing, {5}",
|
||||||
|
reqnum,
|
||||||
|
verb,
|
||||||
|
requestUrl,
|
||||||
|
tickdiff,
|
||||||
|
tickdata,
|
||||||
|
originalRequest);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class SynchronousRestFormsRequester
|
public static class SynchronousRestFormsRequester
|
||||||
{
|
{
|
||||||
private static readonly ILog m_log =
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
LogManager.GetLogger(
|
|
||||||
MethodBase.GetCurrentMethod().DeclaringType);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Perform a synchronous REST request.
|
/// Perform a synchronous REST request.
|
||||||
|
@ -831,6 +875,12 @@ namespace OpenSim.Framework
|
||||||
/// the request. You'll want to make sure you deal with this as they're not uncommon</exception>
|
/// the request. You'll want to make sure you deal with this as they're not uncommon</exception>
|
||||||
public static string MakeRequest(string verb, string requestUrl, string obj)
|
public static string MakeRequest(string verb, string requestUrl, string obj)
|
||||||
{
|
{
|
||||||
|
int reqnum = WebUtil.RequestNumber++;
|
||||||
|
// m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method);
|
||||||
|
|
||||||
|
int tickstart = Util.EnvironmentTickCount();
|
||||||
|
int tickdata = 0;
|
||||||
|
|
||||||
WebRequest request = WebRequest.Create(requestUrl);
|
WebRequest request = WebRequest.Create(requestUrl);
|
||||||
request.Method = verb;
|
request.Method = verb;
|
||||||
string respstring = String.Empty;
|
string respstring = String.Empty;
|
||||||
|
@ -859,12 +909,16 @@ namespace OpenSim.Framework
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
m_log.DebugFormat("[FORMS]: exception occured on sending request to {0}: " + e.ToString(), requestUrl);
|
m_log.DebugFormat(
|
||||||
|
"[FORMS]: exception occured {0} {1}: {2}{3}", verb, requestUrl, e.Message, e.StackTrace);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
if (requestStream != null)
|
if (requestStream != null)
|
||||||
requestStream.Close();
|
requestStream.Close();
|
||||||
|
|
||||||
|
// capture how much time was spent writing
|
||||||
|
tickdata = Util.EnvironmentTickCountSubtract(tickstart);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -885,7 +939,9 @@ namespace OpenSim.Framework
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
m_log.DebugFormat("[FORMS]: exception occured on receiving reply " + e.ToString());
|
m_log.DebugFormat(
|
||||||
|
"[FORMS]: Exception occured on receiving {0} {1}: {2}{3}",
|
||||||
|
verb, requestUrl, e.Message, e.StackTrace);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
@ -898,9 +954,21 @@ namespace OpenSim.Framework
|
||||||
catch (System.InvalidOperationException)
|
catch (System.InvalidOperationException)
|
||||||
{
|
{
|
||||||
// This is what happens when there is invalid XML
|
// This is what happens when there is invalid XML
|
||||||
m_log.DebugFormat("[FORMS]: InvalidOperationException on receiving request");
|
m_log.DebugFormat("[FORMS]: InvalidOperationException on receiving {0} {1}", verb, requestUrl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
|
||||||
|
if (tickdiff > WebUtil.LongCallTime)
|
||||||
|
m_log.InfoFormat(
|
||||||
|
"[FORMS]: Slow request to <{0}> {1} {2} took {3}ms, {4}ms writing, {5}",
|
||||||
|
reqnum,
|
||||||
|
verb,
|
||||||
|
requestUrl,
|
||||||
|
tickdiff,
|
||||||
|
tickdata,
|
||||||
|
obj.Length > WebUtil.MaxRequestDiagLength ? obj.Remove(WebUtil.MaxRequestDiagLength) : obj);
|
||||||
|
|
||||||
return respstring;
|
return respstring;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -923,17 +991,24 @@ namespace OpenSim.Framework
|
||||||
/// the request. You'll want to make sure you deal with this as they're not uncommon</exception>
|
/// the request. You'll want to make sure you deal with this as they're not uncommon</exception>
|
||||||
public static TResponse MakeRequest<TRequest, TResponse>(string verb, string requestUrl, TRequest obj)
|
public static TResponse MakeRequest<TRequest, TResponse>(string verb, string requestUrl, TRequest obj)
|
||||||
{
|
{
|
||||||
|
int reqnum = WebUtil.RequestNumber++;
|
||||||
|
// m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method);
|
||||||
|
|
||||||
|
int tickstart = Util.EnvironmentTickCount();
|
||||||
|
int tickdata = 0;
|
||||||
|
|
||||||
Type type = typeof(TRequest);
|
Type type = typeof(TRequest);
|
||||||
TResponse deserial = default(TResponse);
|
TResponse deserial = default(TResponse);
|
||||||
|
|
||||||
WebRequest request = WebRequest.Create(requestUrl);
|
WebRequest request = WebRequest.Create(requestUrl);
|
||||||
request.Method = verb;
|
request.Method = verb;
|
||||||
|
MemoryStream buffer = null;
|
||||||
|
|
||||||
if ((verb == "POST") || (verb == "PUT"))
|
if ((verb == "POST") || (verb == "PUT"))
|
||||||
{
|
{
|
||||||
request.ContentType = "text/xml";
|
request.ContentType = "text/xml";
|
||||||
|
|
||||||
MemoryStream buffer = new MemoryStream();
|
buffer = new MemoryStream();
|
||||||
|
|
||||||
XmlWriterSettings settings = new XmlWriterSettings();
|
XmlWriterSettings settings = new XmlWriterSettings();
|
||||||
settings.Encoding = Encoding.UTF8;
|
settings.Encoding = Encoding.UTF8;
|
||||||
|
@ -956,13 +1031,19 @@ namespace OpenSim.Framework
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
m_log.DebugFormat("[SynchronousRestObjectRequester]: exception in sending data to {0}: {1}", requestUrl, e);
|
m_log.DebugFormat(
|
||||||
|
"[SynchronousRestObjectRequester]: Exception in making request {0} {1}: {2}{3}",
|
||||||
|
verb, requestUrl, e.Message, e.StackTrace);
|
||||||
|
|
||||||
return deserial;
|
return deserial;
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
if (requestStream != null)
|
if (requestStream != null)
|
||||||
requestStream.Close();
|
requestStream.Close();
|
||||||
|
|
||||||
|
// capture how much time was spent writing
|
||||||
|
tickdata = Util.EnvironmentTickCountSubtract(tickstart);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -978,7 +1059,11 @@ namespace OpenSim.Framework
|
||||||
respStream.Close();
|
respStream.Close();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
m_log.DebugFormat("[SynchronousRestObjectRequester]: Oops! no content found in response stream from {0} {1}", requestUrl, verb);
|
{
|
||||||
|
m_log.DebugFormat(
|
||||||
|
"[SynchronousRestObjectRequester]: Oops! no content found in response stream from {0} {1}",
|
||||||
|
verb, requestUrl);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (WebException e)
|
catch (WebException e)
|
||||||
|
@ -989,17 +1074,44 @@ namespace OpenSim.Framework
|
||||||
return deserial;
|
return deserial;
|
||||||
else
|
else
|
||||||
m_log.ErrorFormat(
|
m_log.ErrorFormat(
|
||||||
"[SynchronousRestObjectRequester]: WebException {0} {1} {2} {3}",
|
"[SynchronousRestObjectRequester]: WebException for {0} {1} {2}: {3} {4}",
|
||||||
requestUrl, typeof(TResponse).ToString(), e.Message, e.StackTrace);
|
verb, requestUrl, typeof(TResponse).ToString(), e.Message, e.StackTrace);
|
||||||
}
|
}
|
||||||
catch (System.InvalidOperationException)
|
catch (System.InvalidOperationException)
|
||||||
{
|
{
|
||||||
// This is what happens when there is invalid XML
|
// This is what happens when there is invalid XML
|
||||||
m_log.DebugFormat("[SynchronousRestObjectRequester]: Invalid XML {0} {1}", requestUrl, typeof(TResponse).ToString());
|
m_log.DebugFormat(
|
||||||
|
"[SynchronousRestObjectRequester]: Invalid XML from {0} {1} {2}",
|
||||||
|
verb, requestUrl, typeof(TResponse).ToString());
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
m_log.DebugFormat("[SynchronousRestObjectRequester]: Exception on response from {0} {1}", requestUrl, e);
|
m_log.DebugFormat(
|
||||||
|
"[SynchronousRestObjectRequester]: Exception on response from {0} {1}: {2}{3}",
|
||||||
|
verb, requestUrl, e.Message, e.StackTrace);
|
||||||
|
}
|
||||||
|
|
||||||
|
int tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
|
||||||
|
if (tickdiff > WebUtil.LongCallTime)
|
||||||
|
{
|
||||||
|
string originalRequest = null;
|
||||||
|
|
||||||
|
if (buffer != null)
|
||||||
|
{
|
||||||
|
originalRequest = Encoding.UTF8.GetString(buffer.ToArray());
|
||||||
|
|
||||||
|
if (originalRequest.Length > WebUtil.MaxRequestDiagLength)
|
||||||
|
originalRequest = originalRequest.Remove(WebUtil.MaxRequestDiagLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_log.InfoFormat(
|
||||||
|
"[SynchronousRestObjectRequester]: Slow request to <{0}> {1} {2} took {3}ms, {4}ms writing, {5}",
|
||||||
|
reqnum,
|
||||||
|
verb,
|
||||||
|
requestUrl,
|
||||||
|
tickdiff,
|
||||||
|
tickdata,
|
||||||
|
originalRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
return deserial;
|
return deserial;
|
||||||
|
|
|
@ -92,9 +92,14 @@ namespace OpenSim
|
||||||
m_log.Info("[OPENSIM MAIN]: configured log4net using default OpenSim.exe.config");
|
m_log.Info("[OPENSIM MAIN]: configured log4net using default OpenSim.exe.config");
|
||||||
}
|
}
|
||||||
|
|
||||||
m_log.DebugFormat(
|
m_log.InfoFormat(
|
||||||
"[OPENSIM MAIN]: System Locale is {0}", System.Threading.Thread.CurrentThread.CurrentCulture);
|
"[OPENSIM MAIN]: System Locale is {0}", System.Threading.Thread.CurrentThread.CurrentCulture);
|
||||||
|
|
||||||
|
string monoThreadsPerCpu = System.Environment.GetEnvironmentVariable("MONO_THREADS_PER_CPU");
|
||||||
|
|
||||||
|
m_log.InfoFormat(
|
||||||
|
"[OPENSIM MAIN]: Environment variable MONO_THREADS_PER_CPU is {0}", monoThreadsPerCpu ?? "unset");
|
||||||
|
|
||||||
// Increase the number of IOCP threads available. Mono defaults to a tragically low number
|
// Increase the number of IOCP threads available. Mono defaults to a tragically low number
|
||||||
int workerThreads, iocpThreads;
|
int workerThreads, iocpThreads;
|
||||||
System.Threading.ThreadPool.GetMaxThreads(out workerThreads, out iocpThreads);
|
System.Threading.ThreadPool.GetMaxThreads(out workerThreads, out iocpThreads);
|
||||||
|
@ -109,7 +114,6 @@ namespace OpenSim
|
||||||
|
|
||||||
// Check if the system is compatible with OpenSimulator.
|
// Check if the system is compatible with OpenSimulator.
|
||||||
// Ensures that the minimum system requirements are met
|
// Ensures that the minimum system requirements are met
|
||||||
m_log.Info("Performing compatibility checks... \n");
|
|
||||||
string supported = String.Empty;
|
string supported = String.Empty;
|
||||||
if (Util.IsEnvironmentSupported(ref supported))
|
if (Util.IsEnvironmentSupported(ref supported))
|
||||||
{
|
{
|
||||||
|
|
|
@ -28,12 +28,14 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using System.Timers;
|
using System.Timers;
|
||||||
using log4net;
|
using log4net;
|
||||||
|
using NDesk.Options;
|
||||||
using Nini.Config;
|
using Nini.Config;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
|
@ -194,9 +196,9 @@ namespace OpenSim
|
||||||
PrintFileToConsole("startuplogo.txt");
|
PrintFileToConsole("startuplogo.txt");
|
||||||
|
|
||||||
// For now, start at the 'root' level by default
|
// For now, start at the 'root' level by default
|
||||||
if (m_sceneManager.Scenes.Count == 1) // If there is only one region, select it
|
if (SceneManager.Scenes.Count == 1) // If there is only one region, select it
|
||||||
ChangeSelectedRegion("region",
|
ChangeSelectedRegion("region",
|
||||||
new string[] {"change", "region", m_sceneManager.Scenes[0].RegionInfo.RegionName});
|
new string[] {"change", "region", SceneManager.Scenes[0].RegionInfo.RegionName});
|
||||||
else
|
else
|
||||||
ChangeSelectedRegion("region", new string[] {"change", "region", "root"});
|
ChangeSelectedRegion("region", new string[] {"change", "region", "root"});
|
||||||
|
|
||||||
|
@ -225,12 +227,14 @@ namespace OpenSim
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void RegisterConsoleCommands()
|
private void RegisterConsoleCommands()
|
||||||
{
|
{
|
||||||
m_console.Commands.AddCommand("region", false, "force update",
|
MainServer.RegisterHttpConsoleCommands(m_console);
|
||||||
|
|
||||||
|
m_console.Commands.AddCommand("Objects", 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("Debug", false, "debug packet",
|
||||||
"debug packet <level> [<avatar-first-name> <avatar-last-name>]",
|
"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"
|
||||||
|
@ -242,45 +246,37 @@ namespace OpenSim
|
||||||
+ "If an avatar name is given then only packets from that avatar are logged",
|
+ "If an avatar name is given then only packets from that avatar are logged",
|
||||||
Debug);
|
Debug);
|
||||||
|
|
||||||
m_console.Commands.AddCommand("region", false, "debug http",
|
m_console.Commands.AddCommand("Debug", false, "debug teleport", "debug teleport", "Toggle teleport route debugging", Debug);
|
||||||
"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);
|
|
||||||
|
|
||||||
m_console.Commands.AddCommand("region", false, "debug teleport", "debug teleport", "Toggle teleport route debugging", Debug);
|
m_console.Commands.AddCommand("Debug", false, "debug scene",
|
||||||
|
|
||||||
m_console.Commands.AddCommand("region", false, "debug scene",
|
|
||||||
"debug scene <scripting> <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("General", false, "change region",
|
||||||
"change region <region name>",
|
"change region <region name>",
|
||||||
"Change current console region", ChangeSelectedRegion);
|
"Change current console region", ChangeSelectedRegion);
|
||||||
|
|
||||||
m_console.Commands.AddCommand("region", false, "save xml",
|
m_console.Commands.AddCommand("Archiving", false, "save xml",
|
||||||
"save xml",
|
"save xml",
|
||||||
"Save a region's data in XML format", SaveXml);
|
"Save a region's data in XML format", SaveXml);
|
||||||
|
|
||||||
m_console.Commands.AddCommand("region", false, "save xml2",
|
m_console.Commands.AddCommand("Archiving", false, "save xml2",
|
||||||
"save xml2",
|
"save xml2",
|
||||||
"Save a region's data in XML2 format", SaveXml2);
|
"Save a region's data in XML2 format", SaveXml2);
|
||||||
|
|
||||||
m_console.Commands.AddCommand("region", false, "load xml",
|
m_console.Commands.AddCommand("Archiving", false, "load xml",
|
||||||
"load xml [-newIDs [<x> <y> <z>]]",
|
"load xml [-newIDs [<x> <y> <z>]]",
|
||||||
"Load a region's data from XML format", LoadXml);
|
"Load a region's data from XML format", LoadXml);
|
||||||
|
|
||||||
m_console.Commands.AddCommand("region", false, "load xml2",
|
m_console.Commands.AddCommand("Archiving", false, "load xml2",
|
||||||
"load xml2",
|
"load xml2",
|
||||||
"Load a region's data from XML2 format", LoadXml2);
|
"Load a region's data from XML2 format", LoadXml2);
|
||||||
|
|
||||||
m_console.Commands.AddCommand("region", false, "save prims xml2",
|
m_console.Commands.AddCommand("Archiving", false, "save prims xml2",
|
||||||
"save prims xml2 [<prim name> <file name>]",
|
"save prims xml2 [<prim name> <file name>]",
|
||||||
"Save named prim to XML2", SavePrimsXml2);
|
"Save named prim to XML2", SavePrimsXml2);
|
||||||
|
|
||||||
m_console.Commands.AddCommand("region", false, "load oar",
|
m_console.Commands.AddCommand("Archiving", false, "load oar",
|
||||||
"load oar [--merge] [--skip-assets] [<OAR path>]",
|
"load oar [--merge] [--skip-assets] [<OAR path>]",
|
||||||
"Load a region's data from an OAR archive.",
|
"Load a region's data from an OAR archive.",
|
||||||
"--merge will merge the OAR with the existing scene." + Environment.NewLine
|
"--merge will merge the OAR with the existing scene." + Environment.NewLine
|
||||||
|
@ -289,7 +285,7 @@ namespace OpenSim
|
||||||
+ " If this is not given then the command looks for an OAR named region.oar in the current directory.",
|
+ " If this is not given then the command looks for an OAR named region.oar in the current directory.",
|
||||||
LoadOar);
|
LoadOar);
|
||||||
|
|
||||||
m_console.Commands.AddCommand("region", false, "save oar",
|
m_console.Commands.AddCommand("Archiving", false, "save oar",
|
||||||
//"save oar [-v|--version=<N>] [-p|--profile=<url>] [<OAR path>]",
|
//"save oar [-v|--version=<N>] [-p|--profile=<url>] [<OAR path>]",
|
||||||
"save oar [-h|--home=<url>] [--noassets] [--publish] [--perm=<permissions>] [<OAR path>]",
|
"save oar [-h|--home=<url>] [--noassets] [--publish] [--perm=<permissions>] [<OAR path>]",
|
||||||
"Save a region's data to an OAR archive.",
|
"Save a region's data to an OAR archive.",
|
||||||
|
@ -306,54 +302,53 @@ namespace OpenSim
|
||||||
+ " If this is not given then the oar is saved to region.oar in the current directory.",
|
+ " If this is not given then the oar is saved to region.oar in the current directory.",
|
||||||
SaveOar);
|
SaveOar);
|
||||||
|
|
||||||
m_console.Commands.AddCommand("region", false, "edit scale",
|
m_console.Commands.AddCommand("Objects", false, "edit scale",
|
||||||
"edit scale <name> <x> <y> <z>",
|
"edit scale <name> <x> <y> <z>",
|
||||||
"Change the scale of a named prim", HandleEditScale);
|
"Change the scale of a named prim", HandleEditScale);
|
||||||
|
|
||||||
m_console.Commands.AddCommand("region", false, "kick user",
|
m_console.Commands.AddCommand("Users", false, "kick user",
|
||||||
"kick user <first> <last> [message]",
|
"kick user <first> <last> [--force] [message]",
|
||||||
"Kick a user off the simulator", KickUserCommand);
|
"Kick a user off the simulator",
|
||||||
|
"The --force option will kick the user without any checks to see whether it's already in the process of closing\n"
|
||||||
|
+ "Only use this option if you are sure the avatar is inactive and a normal kick user operation does not removed them",
|
||||||
|
KickUserCommand);
|
||||||
|
|
||||||
m_console.Commands.AddCommand("region", false, "show users",
|
m_console.Commands.AddCommand("Users", false, "show users",
|
||||||
"show users [full]",
|
"show users [full]",
|
||||||
"Show user data for users currently on the region",
|
"Show user data for users currently on the region",
|
||||||
"Without the 'full' option, only users actually on the region are shown."
|
"Without the 'full' option, only users actually on the region are shown."
|
||||||
+ " With the 'full' option child agents of users in neighbouring regions are also shown.",
|
+ " With the 'full' option child agents of users in neighbouring regions are also shown.",
|
||||||
HandleShow);
|
HandleShow);
|
||||||
|
|
||||||
m_console.Commands.AddCommand("region", false, "show connections",
|
m_console.Commands.AddCommand("Comms", false, "show connections",
|
||||||
"show connections",
|
"show connections",
|
||||||
"Show connection data", HandleShow);
|
"Show connection data", HandleShow);
|
||||||
|
|
||||||
m_console.Commands.AddCommand("region", false, "show circuits",
|
m_console.Commands.AddCommand("Comms", false, "show circuits",
|
||||||
"show circuits",
|
"show circuits",
|
||||||
"Show agent circuit data", HandleShow);
|
"Show agent circuit data", HandleShow);
|
||||||
|
|
||||||
m_console.Commands.AddCommand("region", false, "show http-handlers",
|
m_console.Commands.AddCommand("Comms", false, "show pending-objects",
|
||||||
"show http-handlers",
|
|
||||||
"Show all registered http handlers", HandleShow);
|
|
||||||
|
|
||||||
m_console.Commands.AddCommand("region", false, "show pending-objects",
|
|
||||||
"show pending-objects",
|
"show pending-objects",
|
||||||
"Show # of objects on the pending queues of all scene viewers", HandleShow);
|
"Show # of objects on the pending queues of all scene viewers", HandleShow);
|
||||||
|
|
||||||
m_console.Commands.AddCommand("region", false, "show modules",
|
m_console.Commands.AddCommand("General", false, "show modules",
|
||||||
"show modules",
|
"show modules",
|
||||||
"Show module data", HandleShow);
|
"Show module data", HandleShow);
|
||||||
|
|
||||||
m_console.Commands.AddCommand("region", false, "show regions",
|
m_console.Commands.AddCommand("Regions", false, "show regions",
|
||||||
"show regions",
|
"show regions",
|
||||||
"Show region data", HandleShow);
|
"Show region data", HandleShow);
|
||||||
|
|
||||||
m_console.Commands.AddCommand("region", false, "show ratings",
|
m_console.Commands.AddCommand("Regions", false, "show ratings",
|
||||||
"show ratings",
|
"show ratings",
|
||||||
"Show rating data", HandleShow);
|
"Show rating data", HandleShow);
|
||||||
|
|
||||||
m_console.Commands.AddCommand("region", false, "backup",
|
m_console.Commands.AddCommand("Objects", false, "backup",
|
||||||
"backup",
|
"backup",
|
||||||
"Persist currently unsaved object changes immediately instead of waiting for the normal persistence call.", 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("Regions", false, "create region",
|
||||||
"create region [\"region name\"] <region_file.ini>",
|
"create region [\"region name\"] <region_file.ini>",
|
||||||
"Create a new region.",
|
"Create a new region.",
|
||||||
"The settings for \"region name\" are read from <region_file.ini>. Paths specified with <region_file.ini> are relative to your Regions directory, unless an absolute path is given."
|
"The settings for \"region name\" are read from <region_file.ini>. Paths specified with <region_file.ini> are relative to your Regions directory, unless an absolute path is given."
|
||||||
|
@ -362,62 +357,57 @@ namespace OpenSim
|
||||||
+ "If <region_file.ini> does not exist, it will be created.",
|
+ "If <region_file.ini> does not exist, it will be created.",
|
||||||
HandleCreateRegion);
|
HandleCreateRegion);
|
||||||
|
|
||||||
m_console.Commands.AddCommand("region", false, "restart",
|
m_console.Commands.AddCommand("Regions", false, "restart",
|
||||||
"restart",
|
"restart",
|
||||||
"Restart all sims in this instance", RunCommand);
|
"Restart all sims in this instance", RunCommand);
|
||||||
|
|
||||||
m_console.Commands.AddCommand("region", false, "config set",
|
m_console.Commands.AddCommand("General", false, "config set",
|
||||||
"config set <section> <key> <value>",
|
"config set <section> <key> <value>",
|
||||||
"Set a config option. In most cases this is not useful since changed parameters are not dynamically reloaded. Neither do changed parameters persist - you will have to change a config file manually and restart.", HandleConfig);
|
"Set a config option. In most cases this is not useful since changed parameters are not dynamically reloaded. Neither do changed parameters persist - you will have to change a config file manually and restart.", HandleConfig);
|
||||||
|
|
||||||
m_console.Commands.AddCommand("region", false, "config get",
|
m_console.Commands.AddCommand("General", false, "config get",
|
||||||
"config get [<section>] [<key>]",
|
"config get [<section>] [<key>]",
|
||||||
"Synonym for config show",
|
"Synonym for config show",
|
||||||
HandleConfig);
|
HandleConfig);
|
||||||
|
|
||||||
m_console.Commands.AddCommand("region", false, "config show",
|
m_console.Commands.AddCommand("General", false, "config show",
|
||||||
"config show [<section>] [<key>]",
|
"config show [<section>] [<key>]",
|
||||||
"Show config information",
|
"Show config information",
|
||||||
"If neither section nor field are specified, then the whole current configuration is printed." + Environment.NewLine
|
"If neither section nor field are specified, then the whole current configuration is printed." + Environment.NewLine
|
||||||
+ "If a section is given but not a field, then all fields in that section are printed.",
|
+ "If a section is given but not a field, then all fields in that section are printed.",
|
||||||
HandleConfig);
|
HandleConfig);
|
||||||
|
|
||||||
m_console.Commands.AddCommand("region", false, "config save",
|
m_console.Commands.AddCommand("General", false, "config save",
|
||||||
"config save <path>",
|
"config save <path>",
|
||||||
"Save current configuration to a file at the given path", HandleConfig);
|
"Save current configuration to a file at the given path", HandleConfig);
|
||||||
|
|
||||||
m_console.Commands.AddCommand("region", false, "command-script",
|
m_console.Commands.AddCommand("General", false, "command-script",
|
||||||
"command-script <script>",
|
"command-script <script>",
|
||||||
"Run a command script from file", RunCommand);
|
"Run a command script from file", RunCommand);
|
||||||
|
|
||||||
m_console.Commands.AddCommand("region", false, "remove-region",
|
m_console.Commands.AddCommand("Regions", false, "remove-region",
|
||||||
"remove-region <name>",
|
"remove-region <name>",
|
||||||
"Remove a region from this simulator", RunCommand);
|
"Remove a region from this simulator", RunCommand);
|
||||||
|
|
||||||
m_console.Commands.AddCommand("region", false, "delete-region",
|
m_console.Commands.AddCommand("Regions", false, "delete-region",
|
||||||
"delete-region <name>",
|
"delete-region <name>",
|
||||||
"Delete a region from disk", RunCommand);
|
"Delete a region from disk", RunCommand);
|
||||||
|
|
||||||
m_console.Commands.AddCommand("region", false, "modules list",
|
m_console.Commands.AddCommand("General", false, "modules list",
|
||||||
"modules list",
|
"modules list",
|
||||||
"List modules", HandleModules);
|
"List modules", HandleModules);
|
||||||
|
|
||||||
m_console.Commands.AddCommand("region", false, "modules load",
|
m_console.Commands.AddCommand("General", false, "modules load",
|
||||||
"modules load <name>",
|
"modules load <name>",
|
||||||
"Load a module", HandleModules);
|
"Load a module", HandleModules);
|
||||||
|
|
||||||
m_console.Commands.AddCommand("region", false, "modules unload",
|
m_console.Commands.AddCommand("General", false, "modules unload",
|
||||||
"modules unload <name>",
|
"modules unload <name>",
|
||||||
"Unload a module", HandleModules);
|
"Unload a module", HandleModules);
|
||||||
|
|
||||||
m_console.Commands.AddCommand("region", false, "Add-InventoryHost",
|
m_console.Commands.AddCommand("Objects", false, "kill uuid",
|
||||||
"Add-InventoryHost <host>",
|
|
||||||
String.Empty, RunCommand);
|
|
||||||
|
|
||||||
m_console.Commands.AddCommand("region", false, "kill uuid",
|
|
||||||
"kill uuid <UUID>",
|
"kill uuid <UUID>",
|
||||||
"Kill an object by UUID", KillUUID);
|
"Kill an object by UUID", KillUUID);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void ShutdownSpecific()
|
public override void ShutdownSpecific()
|
||||||
|
@ -442,12 +432,16 @@ namespace OpenSim
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WatchdogTimeoutHandler(System.Threading.Thread thread, int lastTick)
|
private void WatchdogTimeoutHandler(Watchdog.ThreadWatchdogInfo twi)
|
||||||
{
|
{
|
||||||
int now = Environment.TickCount & Int32.MaxValue;
|
int now = Environment.TickCount & Int32.MaxValue;
|
||||||
|
|
||||||
m_log.ErrorFormat("[WATCHDOG]: Timeout detected for thread \"{0}\". ThreadState={1}. Last tick was {2}ms ago",
|
m_log.ErrorFormat(
|
||||||
thread.Name, thread.ThreadState, now - lastTick);
|
"[WATCHDOG]: Timeout detected for thread \"{0}\". ThreadState={1}. Last tick was {2}ms ago. {3}",
|
||||||
|
twi.Thread.Name,
|
||||||
|
twi.Thread.ThreadState,
|
||||||
|
now - twi.LastTick,
|
||||||
|
twi.AlarmMethod != null ? string.Format("Data: {0}", twi.AlarmMethod()) : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Console Commands
|
#region Console Commands
|
||||||
|
@ -459,21 +453,27 @@ namespace OpenSim
|
||||||
/// <param name="cmdparams">name of avatar to kick</param>
|
/// <param name="cmdparams">name of avatar to kick</param>
|
||||||
private void KickUserCommand(string module, string[] cmdparams)
|
private void KickUserCommand(string module, string[] cmdparams)
|
||||||
{
|
{
|
||||||
if (cmdparams.Length < 4)
|
bool force = false;
|
||||||
|
|
||||||
|
OptionSet options = new OptionSet().Add("f|force", delegate (string v) { force = v != null; });
|
||||||
|
|
||||||
|
List<string> mainParams = options.Parse(cmdparams);
|
||||||
|
|
||||||
|
if (mainParams.Count < 4)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
string alert = null;
|
string alert = null;
|
||||||
if (cmdparams.Length > 4)
|
if (mainParams.Count > 4)
|
||||||
alert = String.Format("\n{0}\n", String.Join(" ", cmdparams, 4, cmdparams.Length - 4));
|
alert = String.Format("\n{0}\n", String.Join(" ", cmdparams, 4, cmdparams.Length - 4));
|
||||||
|
|
||||||
IList agents = m_sceneManager.GetCurrentSceneAvatars();
|
IList agents = SceneManager.GetCurrentSceneAvatars();
|
||||||
|
|
||||||
foreach (ScenePresence presence in agents)
|
foreach (ScenePresence presence in agents)
|
||||||
{
|
{
|
||||||
RegionInfo regionInfo = presence.Scene.RegionInfo;
|
RegionInfo regionInfo = presence.Scene.RegionInfo;
|
||||||
|
|
||||||
if (presence.Firstname.ToLower().Contains(cmdparams[2].ToLower()) &&
|
if (presence.Firstname.ToLower().Contains(mainParams[2].ToLower()) &&
|
||||||
presence.Lastname.ToLower().Contains(cmdparams[3].ToLower()))
|
presence.Lastname.ToLower().Contains(mainParams[3].ToLower()))
|
||||||
{
|
{
|
||||||
MainConsole.Instance.Output(
|
MainConsole.Instance.Output(
|
||||||
String.Format(
|
String.Format(
|
||||||
|
@ -486,10 +486,10 @@ namespace OpenSim
|
||||||
else
|
else
|
||||||
presence.ControllingClient.Kick("\nThe OpenSim manager kicked you out.\n");
|
presence.ControllingClient.Kick("\nThe OpenSim manager kicked you out.\n");
|
||||||
|
|
||||||
// ...and close on our side
|
presence.Scene.IncomingCloseAgent(presence.UUID, force);
|
||||||
presence.Scene.IncomingCloseAgent(presence.UUID);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MainConsole.Instance.Output("");
|
MainConsole.Instance.Output("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -543,7 +543,7 @@ namespace OpenSim
|
||||||
private void HandleForceUpdate(string module, string[] args)
|
private void HandleForceUpdate(string module, string[] args)
|
||||||
{
|
{
|
||||||
MainConsole.Instance.Output("Updating all clients");
|
MainConsole.Instance.Output("Updating all clients");
|
||||||
m_sceneManager.ForceCurrentSceneClientUpdate();
|
SceneManager.ForceCurrentSceneClientUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -555,7 +555,7 @@ namespace OpenSim
|
||||||
{
|
{
|
||||||
if (args.Length == 6)
|
if (args.Length == 6)
|
||||||
{
|
{
|
||||||
m_sceneManager.HandleEditCommandOnCurrentScene(args);
|
SceneManager.HandleEditCommandOnCurrentScene(args);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -765,7 +765,7 @@ namespace OpenSim
|
||||||
case "load":
|
case "load":
|
||||||
if (cmdparams.Length > 1)
|
if (cmdparams.Length > 1)
|
||||||
{
|
{
|
||||||
foreach (Scene s in new ArrayList(m_sceneManager.Scenes))
|
foreach (Scene s in new ArrayList(SceneManager.Scenes))
|
||||||
{
|
{
|
||||||
MainConsole.Instance.Output(String.Format("Loading module: {0}", cmdparams[1]));
|
MainConsole.Instance.Output(String.Format("Loading module: {0}", cmdparams[1]));
|
||||||
m_moduleLoader.LoadRegionModules(cmdparams[1], s);
|
m_moduleLoader.LoadRegionModules(cmdparams[1], s);
|
||||||
|
@ -803,14 +803,14 @@ namespace OpenSim
|
||||||
|
|
||||||
case "backup":
|
case "backup":
|
||||||
MainConsole.Instance.Output("Triggering save of pending object updates to persistent store");
|
MainConsole.Instance.Output("Triggering save of pending object updates to persistent store");
|
||||||
m_sceneManager.BackupCurrentScene();
|
SceneManager.BackupCurrentScene();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "remove-region":
|
case "remove-region":
|
||||||
string regRemoveName = CombineParams(cmdparams, 0);
|
string regRemoveName = CombineParams(cmdparams, 0);
|
||||||
|
|
||||||
Scene removeScene;
|
Scene removeScene;
|
||||||
if (m_sceneManager.TryGetScene(regRemoveName, out removeScene))
|
if (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");
|
||||||
|
@ -820,23 +820,15 @@ namespace OpenSim
|
||||||
string regDeleteName = CombineParams(cmdparams, 0);
|
string regDeleteName = CombineParams(cmdparams, 0);
|
||||||
|
|
||||||
Scene killScene;
|
Scene killScene;
|
||||||
if (m_sceneManager.TryGetScene(regDeleteName, out killScene))
|
if (SceneManager.TryGetScene(regDeleteName, out killScene))
|
||||||
RemoveRegion(killScene, true);
|
RemoveRegion(killScene, true);
|
||||||
else
|
else
|
||||||
MainConsole.Instance.Output("no region with that name");
|
MainConsole.Instance.Output("no region with that name");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "restart":
|
case "restart":
|
||||||
m_sceneManager.RestartCurrentScene();
|
SceneManager.RestartCurrentScene();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "Add-InventoryHost":
|
|
||||||
if (cmdparams.Length > 0)
|
|
||||||
{
|
|
||||||
MainConsole.Instance.Output("Not implemented.");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -850,7 +842,7 @@ namespace OpenSim
|
||||||
{
|
{
|
||||||
string newRegionName = CombineParams(cmdparams, 2);
|
string newRegionName = CombineParams(cmdparams, 2);
|
||||||
|
|
||||||
if (!m_sceneManager.TrySetCurrentScene(newRegionName))
|
if (!SceneManager.TrySetCurrentScene(newRegionName))
|
||||||
MainConsole.Instance.Output(String.Format("Couldn't select region {0}", newRegionName));
|
MainConsole.Instance.Output(String.Format("Couldn't select region {0}", newRegionName));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -858,7 +850,7 @@ namespace OpenSim
|
||||||
MainConsole.Instance.Output("Usage: change region <region name>");
|
MainConsole.Instance.Output("Usage: change region <region name>");
|
||||||
}
|
}
|
||||||
|
|
||||||
string regionName = (m_sceneManager.CurrentScene == null ? "root" : m_sceneManager.CurrentScene.RegionInfo.RegionName);
|
string regionName = (SceneManager.CurrentScene == null ? "root" : SceneManager.CurrentScene.RegionInfo.RegionName);
|
||||||
MainConsole.Instance.Output(String.Format("Currently selected region is {0}", regionName));
|
MainConsole.Instance.Output(String.Format("Currently selected region is {0}", regionName));
|
||||||
|
|
||||||
// m_log.DebugFormat("Original prompt is {0}", m_consolePrompt);
|
// m_log.DebugFormat("Original prompt is {0}", m_consolePrompt);
|
||||||
|
@ -876,7 +868,7 @@ namespace OpenSim
|
||||||
});
|
});
|
||||||
|
|
||||||
m_console.DefaultPrompt = prompt;
|
m_console.DefaultPrompt = prompt;
|
||||||
m_console.ConsoleScene = m_sceneManager.CurrentScene;
|
m_console.ConsoleScene = SceneManager.CurrentScene;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -900,7 +892,7 @@ namespace OpenSim
|
||||||
int newDebug;
|
int newDebug;
|
||||||
if (int.TryParse(args[2], out newDebug))
|
if (int.TryParse(args[2], out newDebug))
|
||||||
{
|
{
|
||||||
m_sceneManager.SetDebugPacketLevelOnCurrentScene(newDebug, name);
|
SceneManager.SetDebugPacketLevelOnCurrentScene(newDebug, name);
|
||||||
// We provide user information elsewhere if any clients had their debug level set.
|
// We provide user information elsewhere if any clients had their debug level set.
|
||||||
// MainConsole.Instance.OutputFormat("Debug packet level set to {0}", newDebug);
|
// MainConsole.Instance.OutputFormat("Debug packet level set to {0}", newDebug);
|
||||||
}
|
}
|
||||||
|
@ -912,63 +904,30 @@ namespace OpenSim
|
||||||
|
|
||||||
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 == 4)
|
||||||
{
|
{
|
||||||
if (m_sceneManager.CurrentScene == null)
|
if (SceneManager.CurrentScene == null)
|
||||||
{
|
{
|
||||||
MainConsole.Instance.Output("Please use 'change region <regioname>' first");
|
MainConsole.Instance.Output("Please use 'change region <regioname>' first");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bool scriptingOn = !Convert.ToBoolean(args[2]);
|
string key = args[2];
|
||||||
bool collisionsOn = !Convert.ToBoolean(args[3]);
|
string value = args[3];
|
||||||
bool physicsOn = !Convert.ToBoolean(args[4]);
|
SceneManager.CurrentScene.SetSceneCoreDebug(
|
||||||
m_sceneManager.CurrentScene.SetSceneCoreDebug(scriptingOn, collisionsOn, physicsOn);
|
new Dictionary<string, string>() { { key, value } });
|
||||||
|
|
||||||
MainConsole.Instance.Output(
|
MainConsole.Instance.OutputFormat("Set debug scene {0} = {1}", key, value);
|
||||||
String.Format(
|
|
||||||
"Set debug scene scripting = {0}, collisions = {1}, physics = {2}",
|
|
||||||
!scriptingOn, !collisionsOn, !physicsOn));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MainConsole.Instance.Output("Usage: debug scene <scripting> <collisions> <physics> (where inside <> is true/false)");
|
MainConsole.Instance.Output("Usage: debug scene scripting|collisions|physics|teleport true|false");
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "teleport":
|
|
||||||
foreach(Scene s in m_sceneManager.Scenes)
|
|
||||||
{
|
|
||||||
if (s.DEBUG)
|
|
||||||
{
|
|
||||||
s.DEBUG = false;
|
|
||||||
MainConsole.Instance.Output("Teleport debugging is disabled!");
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
s.DEBUG = true;
|
|
||||||
MainConsole.Instance.Output("Teleport debugging is enabled!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
MainConsole.Instance.Output("Unknown debug command");
|
MainConsole.Instance.Output("Unknown debug command");
|
||||||
break;
|
break;
|
||||||
|
@ -995,11 +954,10 @@ namespace OpenSim
|
||||||
IList agents;
|
IList agents;
|
||||||
if (showParams.Length > 1 && showParams[1] == "full")
|
if (showParams.Length > 1 && showParams[1] == "full")
|
||||||
{
|
{
|
||||||
agents = m_sceneManager.GetCurrentScenePresences();
|
agents = SceneManager.GetCurrentScenePresences();
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
{
|
{
|
||||||
agents = m_sceneManager.GetCurrentSceneAvatars();
|
agents = SceneManager.GetCurrentSceneAvatars();
|
||||||
}
|
}
|
||||||
|
|
||||||
MainConsole.Instance.Output(String.Format("\nAgents connected: {0}\n", agents.Count));
|
MainConsole.Instance.Output(String.Format("\nAgents connected: {0}\n", agents.Count));
|
||||||
|
@ -1037,63 +995,11 @@ namespace OpenSim
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "connections":
|
case "connections":
|
||||||
System.Text.StringBuilder connections = new System.Text.StringBuilder("Connections:\n");
|
HandleShowConnections();
|
||||||
m_sceneManager.ForEachScene(
|
|
||||||
delegate(Scene scene)
|
|
||||||
{
|
|
||||||
scene.ForEachClient(
|
|
||||||
delegate(IClientAPI client)
|
|
||||||
{
|
|
||||||
connections.AppendFormat("{0}: {1} ({2}) from {3} on circuit {4}\n",
|
|
||||||
scene.RegionInfo.RegionName, client.Name, client.AgentId, client.RemoteEndPoint, client.CircuitCode);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
MainConsole.Instance.Output(connections.ToString());
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "circuits":
|
case "circuits":
|
||||||
System.Text.StringBuilder acd = new System.Text.StringBuilder("Agent Circuits:\n");
|
HandleShowCircuits();
|
||||||
m_sceneManager.ForEachScene(
|
|
||||||
delegate(Scene scene)
|
|
||||||
{
|
|
||||||
//this.HttpServer.
|
|
||||||
acd.AppendFormat("{0}:\n", scene.RegionInfo.RegionName);
|
|
||||||
foreach (AgentCircuitData aCircuit in scene.AuthenticateHandler.GetAgentCircuits().Values)
|
|
||||||
acd.AppendFormat("\t{0} {1} ({2})\n", aCircuit.firstname, aCircuit.lastname, (aCircuit.child ? "Child" : "Root"));
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
MainConsole.Instance.Output(acd.ToString());
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "http-handlers":
|
|
||||||
System.Text.StringBuilder handlers = new System.Text.StringBuilder("Registered HTTP Handlers:\n");
|
|
||||||
|
|
||||||
handlers.AppendFormat("* XMLRPC:\n");
|
|
||||||
foreach (String s in HttpServer.GetXmlRpcHandlerKeys())
|
|
||||||
handlers.AppendFormat("\t{0}\n", s);
|
|
||||||
|
|
||||||
handlers.AppendFormat("* HTTP:\n");
|
|
||||||
List<String> poll = HttpServer.GetPollServiceHandlerKeys();
|
|
||||||
foreach (String s in HttpServer.GetHTTPHandlerKeys())
|
|
||||||
handlers.AppendFormat("\t{0} {1}\n", s, (poll.Contains(s) ? "(poll service)" : string.Empty));
|
|
||||||
|
|
||||||
handlers.AppendFormat("* Agent:\n");
|
|
||||||
foreach (String s in HttpServer.GetAgentHandlerKeys())
|
|
||||||
handlers.AppendFormat("\t{0}\n", s);
|
|
||||||
|
|
||||||
handlers.AppendFormat("* LLSD:\n");
|
|
||||||
foreach (String s in HttpServer.GetLLSDHandlerKeys())
|
|
||||||
handlers.AppendFormat("\t{0}\n", s);
|
|
||||||
|
|
||||||
handlers.AppendFormat("* StreamHandlers ({0}):\n", HttpServer.GetStreamHandlerKeys().Count);
|
|
||||||
foreach (String s in HttpServer.GetStreamHandlerKeys())
|
|
||||||
handlers.AppendFormat("\t{0}\n", s);
|
|
||||||
|
|
||||||
MainConsole.Instance.Output(handlers.ToString());
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "modules":
|
case "modules":
|
||||||
|
@ -1103,10 +1009,10 @@ namespace OpenSim
|
||||||
MainConsole.Instance.Output("Shared Module: " + module.Name);
|
MainConsole.Instance.Output("Shared Module: " + module.Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_sceneManager.ForEachScene(
|
SceneManager.ForEachScene(
|
||||||
delegate(Scene scene)
|
delegate(Scene scene) {
|
||||||
{
|
|
||||||
m_log.Error("The currently loaded modules in " + scene.RegionInfo.RegionName + " are:");
|
m_log.Error("The currently loaded modules in " + scene.RegionInfo.RegionName + " are:");
|
||||||
|
|
||||||
foreach (IRegionModule module in scene.Modules.Values)
|
foreach (IRegionModule module in scene.Modules.Values)
|
||||||
{
|
{
|
||||||
if (!module.IsSharedModule)
|
if (!module.IsSharedModule)
|
||||||
|
@ -1114,13 +1020,26 @@ namespace OpenSim
|
||||||
m_log.Error("Region Module: " + module.Name);
|
m_log.Error("Region Module: " + module.Name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
SceneManager.ForEachScene(
|
||||||
|
delegate(Scene scene) {
|
||||||
|
MainConsole.Instance.Output("Loaded new region modules in" + scene.RegionInfo.RegionName + " are:");
|
||||||
|
foreach (IRegionModuleBase module in scene.RegionModules.Values)
|
||||||
|
{
|
||||||
|
Type type = module.GetType().GetInterface("ISharedRegionModule");
|
||||||
|
string module_type = type != null ? "Shared" : "Non-Shared";
|
||||||
|
MainConsole.Instance.OutputFormat("New Region Module ({0}): {1}", module_type, module.Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
MainConsole.Instance.Output("");
|
MainConsole.Instance.Output("");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "regions":
|
case "regions":
|
||||||
m_sceneManager.ForEachScene(
|
SceneManager.ForEachScene(
|
||||||
delegate(Scene scene)
|
delegate(Scene scene)
|
||||||
{
|
{
|
||||||
MainConsole.Instance.Output(String.Format(
|
MainConsole.Instance.Output(String.Format(
|
||||||
|
@ -1134,7 +1053,7 @@ namespace OpenSim
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "ratings":
|
case "ratings":
|
||||||
m_sceneManager.ForEachScene(
|
SceneManager.ForEachScene(
|
||||||
delegate(Scene scene)
|
delegate(Scene scene)
|
||||||
{
|
{
|
||||||
string rating = "";
|
string rating = "";
|
||||||
|
@ -1159,6 +1078,53 @@ namespace OpenSim
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void HandleShowCircuits()
|
||||||
|
{
|
||||||
|
ConsoleDisplayTable cdt = new ConsoleDisplayTable();
|
||||||
|
cdt.AddColumn("Region", 20);
|
||||||
|
cdt.AddColumn("Avatar name", 24);
|
||||||
|
cdt.AddColumn("Type", 5);
|
||||||
|
cdt.AddColumn("Code", 10);
|
||||||
|
cdt.AddColumn("IP", 16);
|
||||||
|
cdt.AddColumn("Viewer Name", 24);
|
||||||
|
|
||||||
|
SceneManager.ForEachScene(
|
||||||
|
s =>
|
||||||
|
{
|
||||||
|
foreach (AgentCircuitData aCircuit in s.AuthenticateHandler.GetAgentCircuits().Values)
|
||||||
|
cdt.AddRow(
|
||||||
|
s.Name,
|
||||||
|
aCircuit.Name,
|
||||||
|
aCircuit.child ? "child" : "root",
|
||||||
|
aCircuit.circuitcode.ToString(),
|
||||||
|
aCircuit.IPAddress.ToString(),
|
||||||
|
aCircuit.Viewer);
|
||||||
|
});
|
||||||
|
|
||||||
|
MainConsole.Instance.Output(cdt.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleShowConnections()
|
||||||
|
{
|
||||||
|
ConsoleDisplayTable cdt = new ConsoleDisplayTable();
|
||||||
|
cdt.AddColumn("Region", 20);
|
||||||
|
cdt.AddColumn("Avatar name", 24);
|
||||||
|
cdt.AddColumn("Circuit code", 12);
|
||||||
|
cdt.AddColumn("Endpoint", 23);
|
||||||
|
cdt.AddColumn("Active?", 7);
|
||||||
|
|
||||||
|
SceneManager.ForEachScene(
|
||||||
|
s => s.ForEachClient(
|
||||||
|
c => cdt.AddRow(
|
||||||
|
s.Name,
|
||||||
|
c.Name,
|
||||||
|
c.CircuitCode.ToString(),
|
||||||
|
c.RemoteEndPoint.ToString(),
|
||||||
|
c.IsActive.ToString())));
|
||||||
|
|
||||||
|
MainConsole.Instance.Output(cdt.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Use XML2 format to serialize data to a file
|
/// Use XML2 format to serialize data to a file
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -1168,11 +1134,11 @@ namespace OpenSim
|
||||||
{
|
{
|
||||||
if (cmdparams.Length > 5)
|
if (cmdparams.Length > 5)
|
||||||
{
|
{
|
||||||
m_sceneManager.SaveNamedPrimsToXml2(cmdparams[3], cmdparams[4]);
|
SceneManager.SaveNamedPrimsToXml2(cmdparams[3], cmdparams[4]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_sceneManager.SaveNamedPrimsToXml2("Primitive", DEFAULT_PRIM_BACKUP_FILENAME);
|
SceneManager.SaveNamedPrimsToXml2("Primitive", DEFAULT_PRIM_BACKUP_FILENAME);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1187,11 +1153,11 @@ namespace OpenSim
|
||||||
|
|
||||||
if (cmdparams.Length > 0)
|
if (cmdparams.Length > 0)
|
||||||
{
|
{
|
||||||
m_sceneManager.SaveCurrentSceneToXml(cmdparams[2]);
|
SceneManager.SaveCurrentSceneToXml(cmdparams[2]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_sceneManager.SaveCurrentSceneToXml(DEFAULT_PRIM_BACKUP_FILENAME);
|
SceneManager.SaveCurrentSceneToXml(DEFAULT_PRIM_BACKUP_FILENAME);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1228,13 +1194,13 @@ namespace OpenSim
|
||||||
MainConsole.Instance.Output(String.Format("loadOffsets <X,Y,Z> = <{0},{1},{2}>",loadOffset.X,loadOffset.Y,loadOffset.Z));
|
MainConsole.Instance.Output(String.Format("loadOffsets <X,Y,Z> = <{0},{1},{2}>",loadOffset.X,loadOffset.Y,loadOffset.Z));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_sceneManager.LoadCurrentSceneFromXml(cmdparams[2], generateNewIDS, loadOffset);
|
SceneManager.LoadCurrentSceneFromXml(cmdparams[2], generateNewIDS, loadOffset);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
m_sceneManager.LoadCurrentSceneFromXml(DEFAULT_PRIM_BACKUP_FILENAME, false, loadOffset);
|
SceneManager.LoadCurrentSceneFromXml(DEFAULT_PRIM_BACKUP_FILENAME, false, loadOffset);
|
||||||
}
|
}
|
||||||
catch (FileNotFoundException)
|
catch (FileNotFoundException)
|
||||||
{
|
{
|
||||||
|
@ -1251,11 +1217,11 @@ namespace OpenSim
|
||||||
{
|
{
|
||||||
if (cmdparams.Length > 2)
|
if (cmdparams.Length > 2)
|
||||||
{
|
{
|
||||||
m_sceneManager.SaveCurrentSceneToXml2(cmdparams[2]);
|
SceneManager.SaveCurrentSceneToXml2(cmdparams[2]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_sceneManager.SaveCurrentSceneToXml2(DEFAULT_PRIM_BACKUP_FILENAME);
|
SceneManager.SaveCurrentSceneToXml2(DEFAULT_PRIM_BACKUP_FILENAME);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1270,7 +1236,7 @@ namespace OpenSim
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
m_sceneManager.LoadCurrentSceneFromXml2(cmdparams[2]);
|
SceneManager.LoadCurrentSceneFromXml2(cmdparams[2]);
|
||||||
}
|
}
|
||||||
catch (FileNotFoundException)
|
catch (FileNotFoundException)
|
||||||
{
|
{
|
||||||
|
@ -1281,7 +1247,7 @@ namespace OpenSim
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
m_sceneManager.LoadCurrentSceneFromXml2(DEFAULT_PRIM_BACKUP_FILENAME);
|
SceneManager.LoadCurrentSceneFromXml2(DEFAULT_PRIM_BACKUP_FILENAME);
|
||||||
}
|
}
|
||||||
catch (FileNotFoundException)
|
catch (FileNotFoundException)
|
||||||
{
|
{
|
||||||
|
@ -1298,7 +1264,7 @@ namespace OpenSim
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
m_sceneManager.LoadArchiveToCurrentScene(cmdparams);
|
SceneManager.LoadArchiveToCurrentScene(cmdparams);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
@ -1312,7 +1278,7 @@ namespace OpenSim
|
||||||
/// <param name="cmdparams"></param>
|
/// <param name="cmdparams"></param>
|
||||||
protected void SaveOar(string module, string[] cmdparams)
|
protected void SaveOar(string module, string[] cmdparams)
|
||||||
{
|
{
|
||||||
m_sceneManager.SaveCurrentSceneToArchive(cmdparams);
|
SceneManager.SaveCurrentSceneToArchive(cmdparams);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string CombineParams(string[] commandParams, int pos)
|
private static string CombineParams(string[] commandParams, int pos)
|
||||||
|
@ -1344,7 +1310,7 @@ namespace OpenSim
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_sceneManager.ForEachScene(
|
SceneManager.ForEachScene(
|
||||||
delegate(Scene scene)
|
delegate(Scene scene)
|
||||||
{
|
{
|
||||||
SceneObjectPart part = scene.GetSceneObjectPart(id);
|
SceneObjectPart part = scene.GetSceneObjectPart(id);
|
||||||
|
|
|
@ -219,7 +219,7 @@ namespace OpenSim
|
||||||
|
|
||||||
base.StartupSpecific();
|
base.StartupSpecific();
|
||||||
|
|
||||||
m_stats = StatsManager.StartCollectingSimExtraStats();
|
m_stats = StatsManager.SimExtraStats;
|
||||||
|
|
||||||
// Create a ModuleLoader instance
|
// Create a ModuleLoader instance
|
||||||
m_moduleLoader = new ModuleLoader(m_config.Source);
|
m_moduleLoader = new ModuleLoader(m_config.Source);
|
||||||
|
@ -242,15 +242,18 @@ namespace OpenSim
|
||||||
|
|
||||||
foreach (string topic in topics)
|
foreach (string topic in topics)
|
||||||
{
|
{
|
||||||
m_console.Commands.AddCommand("plugin", false, "help " + topic,
|
string capitalizedTopic = char.ToUpper(topic[0]) + topic.Substring(1);
|
||||||
"help " + topic,
|
|
||||||
|
// This is a hack to allow the user to enter the help command in upper or lowercase. This will go
|
||||||
|
// away at some point.
|
||||||
|
m_console.Commands.AddCommand(capitalizedTopic, false, "help " + topic,
|
||||||
|
"help " + capitalizedTopic,
|
||||||
|
"Get help on plugin command '" + topic + "'",
|
||||||
|
HandleCommanderHelp);
|
||||||
|
m_console.Commands.AddCommand(capitalizedTopic, false, "help " + capitalizedTopic,
|
||||||
|
"help " + capitalizedTopic,
|
||||||
"Get help on plugin command '" + topic + "'",
|
"Get help on plugin command '" + topic + "'",
|
||||||
HandleCommanderHelp);
|
HandleCommanderHelp);
|
||||||
|
|
||||||
m_console.Commands.AddCommand("plugin", false, topic,
|
|
||||||
topic,
|
|
||||||
"Execute subcommand for plugin '" + topic + "'",
|
|
||||||
null);
|
|
||||||
|
|
||||||
ICommander commander = null;
|
ICommander commander = null;
|
||||||
|
|
||||||
|
@ -267,7 +270,7 @@ namespace OpenSim
|
||||||
|
|
||||||
foreach (string command in commander.Commands.Keys)
|
foreach (string command in commander.Commands.Keys)
|
||||||
{
|
{
|
||||||
m_console.Commands.AddCommand(topic, false,
|
m_console.Commands.AddCommand(capitalizedTopic, false,
|
||||||
topic + " " + command,
|
topic + " " + command,
|
||||||
topic + " " + commander.Commands[command].ShortHelp(),
|
topic + " " + commander.Commands[command].ShortHelp(),
|
||||||
String.Empty, HandleCommanderCommand);
|
String.Empty, HandleCommanderCommand);
|
||||||
|
@ -278,7 +281,7 @@ namespace OpenSim
|
||||||
|
|
||||||
private void HandleCommanderCommand(string module, string[] cmd)
|
private void HandleCommanderCommand(string module, string[] cmd)
|
||||||
{
|
{
|
||||||
m_sceneManager.SendCommandToPluginModules(cmd);
|
SceneManager.SendCommandToPluginModules(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleCommanderHelp(string module, string[] cmd)
|
private void HandleCommanderHelp(string module, string[] cmd)
|
||||||
|
@ -286,7 +289,7 @@ namespace OpenSim
|
||||||
// Only safe for the interactive console, since it won't
|
// Only safe for the interactive console, since it won't
|
||||||
// let us come here unless both scene and commander exist
|
// let us come here unless both scene and commander exist
|
||||||
//
|
//
|
||||||
ICommander moduleCommander = SceneManager.CurrentOrFirstScene.GetCommander(cmd[1]);
|
ICommander moduleCommander = SceneManager.CurrentOrFirstScene.GetCommander(cmd[1].ToLower());
|
||||||
if (moduleCommander != null)
|
if (moduleCommander != null)
|
||||||
m_console.Output(moduleCommander.Help);
|
m_console.Output(moduleCommander.Help);
|
||||||
}
|
}
|
||||||
|
@ -296,7 +299,10 @@ namespace OpenSim
|
||||||
// Called from base.StartUp()
|
// Called from base.StartUp()
|
||||||
|
|
||||||
m_httpServerPort = m_networkServersInfo.HttpListenerPort;
|
m_httpServerPort = m_networkServersInfo.HttpListenerPort;
|
||||||
m_sceneManager.OnRestartSim += handleRestartRegion;
|
SceneManager.OnRestartSim += handleRestartRegion;
|
||||||
|
|
||||||
|
// Only start the memory watchdog once all regions are ready
|
||||||
|
SceneManager.OnRegionsReadyStatusChange += sm => MemoryWatchdog.Enabled = sm.AllRegionsReady;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -381,7 +387,7 @@ namespace OpenSim
|
||||||
scene.LoadPrimsFromStorage(regionInfo.originRegionID);
|
scene.LoadPrimsFromStorage(regionInfo.originRegionID);
|
||||||
|
|
||||||
// TODO : Try setting resource for region xstats here on scene
|
// TODO : Try setting resource for region xstats here on scene
|
||||||
MainServer.Instance.AddStreamHandler(new Region.Framework.Scenes.RegionStatsHandler(regionInfo));
|
MainServer.Instance.AddStreamHandler(new RegionStatsHandler(regionInfo));
|
||||||
|
|
||||||
scene.loadAllLandObjectsFromStorage(regionInfo.originRegionID);
|
scene.loadAllLandObjectsFromStorage(regionInfo.originRegionID);
|
||||||
scene.EventManager.TriggerParcelPrimCountUpdate();
|
scene.EventManager.TriggerParcelPrimCountUpdate();
|
||||||
|
@ -405,7 +411,7 @@ namespace OpenSim
|
||||||
// scripting engines.
|
// scripting engines.
|
||||||
scene.CreateScriptInstances();
|
scene.CreateScriptInstances();
|
||||||
|
|
||||||
m_sceneManager.Add(scene);
|
SceneManager.Add(scene);
|
||||||
|
|
||||||
if (m_autoCreateClientStack)
|
if (m_autoCreateClientStack)
|
||||||
{
|
{
|
||||||
|
@ -424,8 +430,7 @@ namespace OpenSim
|
||||||
|
|
||||||
mscene = scene;
|
mscene = scene;
|
||||||
|
|
||||||
scene.StartTimer();
|
scene.Start();
|
||||||
|
|
||||||
scene.StartScripts();
|
scene.StartScripts();
|
||||||
|
|
||||||
return clientServer;
|
return clientServer;
|
||||||
|
@ -512,14 +517,14 @@ namespace OpenSim
|
||||||
{
|
{
|
||||||
// only need to check this if we are not at the
|
// only need to check this if we are not at the
|
||||||
// root level
|
// root level
|
||||||
if ((m_sceneManager.CurrentScene != null) &&
|
if ((SceneManager.CurrentScene != null) &&
|
||||||
(m_sceneManager.CurrentScene.RegionInfo.RegionID == scene.RegionInfo.RegionID))
|
(SceneManager.CurrentScene.RegionInfo.RegionID == scene.RegionInfo.RegionID))
|
||||||
{
|
{
|
||||||
m_sceneManager.TrySetCurrentScene("..");
|
SceneManager.TrySetCurrentScene("..");
|
||||||
}
|
}
|
||||||
|
|
||||||
scene.DeleteAllSceneObjects();
|
scene.DeleteAllSceneObjects();
|
||||||
m_sceneManager.CloseScene(scene);
|
SceneManager.CloseScene(scene);
|
||||||
ShutdownClientServer(scene.RegionInfo);
|
ShutdownClientServer(scene.RegionInfo);
|
||||||
|
|
||||||
if (!cleanup)
|
if (!cleanup)
|
||||||
|
@ -561,7 +566,7 @@ namespace OpenSim
|
||||||
public void RemoveRegion(string name, bool cleanUp)
|
public void RemoveRegion(string name, bool cleanUp)
|
||||||
{
|
{
|
||||||
Scene target;
|
Scene target;
|
||||||
if (m_sceneManager.TryGetScene(name, out target))
|
if (SceneManager.TryGetScene(name, out target))
|
||||||
RemoveRegion(target, cleanUp);
|
RemoveRegion(target, cleanUp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -574,13 +579,13 @@ namespace OpenSim
|
||||||
{
|
{
|
||||||
// only need to check this if we are not at the
|
// only need to check this if we are not at the
|
||||||
// root level
|
// root level
|
||||||
if ((m_sceneManager.CurrentScene != null) &&
|
if ((SceneManager.CurrentScene != null) &&
|
||||||
(m_sceneManager.CurrentScene.RegionInfo.RegionID == scene.RegionInfo.RegionID))
|
(SceneManager.CurrentScene.RegionInfo.RegionID == scene.RegionInfo.RegionID))
|
||||||
{
|
{
|
||||||
m_sceneManager.TrySetCurrentScene("..");
|
SceneManager.TrySetCurrentScene("..");
|
||||||
}
|
}
|
||||||
|
|
||||||
m_sceneManager.CloseScene(scene);
|
SceneManager.CloseScene(scene);
|
||||||
ShutdownClientServer(scene.RegionInfo);
|
ShutdownClientServer(scene.RegionInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -592,7 +597,7 @@ namespace OpenSim
|
||||||
public void CloseRegion(string name)
|
public void CloseRegion(string name)
|
||||||
{
|
{
|
||||||
Scene target;
|
Scene target;
|
||||||
if (m_sceneManager.TryGetScene(name, out target))
|
if (SceneManager.TryGetScene(name, out target))
|
||||||
CloseRegion(target);
|
CloseRegion(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -724,6 +729,9 @@ namespace OpenSim
|
||||||
return Util.UTF8.GetBytes("OK");
|
return Util.UTF8.GetBytes("OK");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string Name { get { return "SimStatus"; } }
|
||||||
|
public string Description { get { return "Simulator Status"; } }
|
||||||
|
|
||||||
public string ContentType
|
public string ContentType
|
||||||
{
|
{
|
||||||
get { return "text/plain"; }
|
get { return "text/plain"; }
|
||||||
|
@ -749,6 +757,9 @@ namespace OpenSim
|
||||||
OpenSimBase m_opensim;
|
OpenSimBase m_opensim;
|
||||||
string osXStatsURI = String.Empty;
|
string osXStatsURI = String.Empty;
|
||||||
|
|
||||||
|
public string Name { get { return "XSimStatus"; } }
|
||||||
|
public string Description { get { return "Simulator XStatus"; } }
|
||||||
|
|
||||||
public XSimStatusHandler(OpenSimBase sim)
|
public XSimStatusHandler(OpenSimBase sim)
|
||||||
{
|
{
|
||||||
m_opensim = sim;
|
m_opensim = sim;
|
||||||
|
@ -789,6 +800,9 @@ namespace OpenSim
|
||||||
OpenSimBase m_opensim;
|
OpenSimBase m_opensim;
|
||||||
string osUXStatsURI = String.Empty;
|
string osUXStatsURI = String.Empty;
|
||||||
|
|
||||||
|
public string Name { get { return "UXSimStatus"; } }
|
||||||
|
public string Description { get { return "Simulator UXStatus"; } }
|
||||||
|
|
||||||
public UXSimStatusHandler(OpenSimBase sim)
|
public UXSimStatusHandler(OpenSimBase sim)
|
||||||
{
|
{
|
||||||
m_opensim = sim;
|
m_opensim = sim;
|
||||||
|
@ -839,7 +853,7 @@ namespace OpenSim
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
m_sceneManager.Close();
|
SceneManager.Close();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
@ -864,7 +878,7 @@ namespace OpenSim
|
||||||
/// <param name="usernum">The first out parameter describing the number of all the avatars in the Region server</param>
|
/// <param name="usernum">The first out parameter describing the number of all the avatars in the Region server</param>
|
||||||
public void GetAvatarNumber(out int usernum)
|
public void GetAvatarNumber(out int usernum)
|
||||||
{
|
{
|
||||||
usernum = m_sceneManager.GetCurrentSceneAvatars().Count;
|
usernum = SceneManager.GetCurrentSceneAvatars().Count;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -873,7 +887,7 @@ namespace OpenSim
|
||||||
/// <param name="regionnum">The first out parameter describing the number of regions</param>
|
/// <param name="regionnum">The first out parameter describing the number of regions</param>
|
||||||
public void GetRegionNumber(out int regionnum)
|
public void GetRegionNumber(out int regionnum)
|
||||||
{
|
{
|
||||||
regionnum = m_sceneManager.Scenes.Count;
|
regionnum = SceneManager.Scenes.Count;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -151,7 +151,9 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// the root of all evil
|
// the root of all evil
|
||||||
m_HostCapsObj.RegisterHandler("SEED", new RestStreamHandler("POST", capsBase + m_requestPath, SeedCapRequest));
|
m_HostCapsObj.RegisterHandler(
|
||||||
|
"SEED", new RestStreamHandler("POST", capsBase + m_requestPath, SeedCapRequest, "SEED", null));
|
||||||
|
|
||||||
m_log.DebugFormat(
|
m_log.DebugFormat(
|
||||||
"[CAPS]: Registered seed capability {0} for {1}", capsBase + m_requestPath, m_HostCapsObj.AgentID);
|
"[CAPS]: Registered seed capability {0} for {1}", capsBase + m_requestPath, m_HostCapsObj.AgentID);
|
||||||
|
|
||||||
|
@ -159,7 +161,10 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
// new LLSDStreamhandler<OSDMapRequest, OSDMapLayerResponse>("POST",
|
// new LLSDStreamhandler<OSDMapRequest, OSDMapLayerResponse>("POST",
|
||||||
// capsBase + m_mapLayerPath,
|
// capsBase + m_mapLayerPath,
|
||||||
// GetMapLayer);
|
// GetMapLayer);
|
||||||
IRequestHandler req = new RestStreamHandler("POST", capsBase + m_notecardTaskUpdatePath, ScriptTaskInventory);
|
IRequestHandler req
|
||||||
|
= new RestStreamHandler(
|
||||||
|
"POST", capsBase + m_notecardTaskUpdatePath, ScriptTaskInventory, "UpdateScript", null);
|
||||||
|
|
||||||
m_HostCapsObj.RegisterHandler("UpdateScriptTaskInventory", req);
|
m_HostCapsObj.RegisterHandler("UpdateScriptTaskInventory", req);
|
||||||
m_HostCapsObj.RegisterHandler("UpdateScriptTask", req);
|
m_HostCapsObj.RegisterHandler("UpdateScriptTask", req);
|
||||||
}
|
}
|
||||||
|
@ -174,14 +179,27 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// I don't think this one works...
|
// I don't think this one works...
|
||||||
m_HostCapsObj.RegisterHandler("NewFileAgentInventory", new LLSDStreamhandler<LLSDAssetUploadRequest, LLSDAssetUploadResponse>("POST",
|
m_HostCapsObj.RegisterHandler(
|
||||||
|
"NewFileAgentInventory",
|
||||||
|
new LLSDStreamhandler<LLSDAssetUploadRequest, LLSDAssetUploadResponse>(
|
||||||
|
"POST",
|
||||||
capsBase + m_newInventory,
|
capsBase + m_newInventory,
|
||||||
NewAgentInventoryRequest));
|
NewAgentInventoryRequest,
|
||||||
IRequestHandler req = new RestStreamHandler("POST", capsBase + m_notecardUpdatePath, NoteCardAgentInventory);
|
"NewFileAgentInventory",
|
||||||
|
null));
|
||||||
|
|
||||||
|
IRequestHandler req
|
||||||
|
= new RestStreamHandler(
|
||||||
|
"POST", capsBase + m_notecardUpdatePath, NoteCardAgentInventory, "Update*", null);
|
||||||
|
|
||||||
m_HostCapsObj.RegisterHandler("UpdateNotecardAgentInventory", req);
|
m_HostCapsObj.RegisterHandler("UpdateNotecardAgentInventory", req);
|
||||||
m_HostCapsObj.RegisterHandler("UpdateScriptAgentInventory", req);
|
m_HostCapsObj.RegisterHandler("UpdateScriptAgentInventory", req);
|
||||||
m_HostCapsObj.RegisterHandler("UpdateScriptAgent", req);
|
m_HostCapsObj.RegisterHandler("UpdateScriptAgent", req);
|
||||||
m_HostCapsObj.RegisterHandler("CopyInventoryFromNotecard", new RestStreamHandler("POST", capsBase + m_copyFromNotecardPath, CopyInventoryFromNotecard));
|
|
||||||
|
m_HostCapsObj.RegisterHandler(
|
||||||
|
"CopyInventoryFromNotecard",
|
||||||
|
new RestStreamHandler(
|
||||||
|
"POST", capsBase + m_copyFromNotecardPath, CopyInventoryFromNotecard, "CopyInventoryFromNotecard", null));
|
||||||
|
|
||||||
// As of RC 1.22.9 of the Linden client this is
|
// As of RC 1.22.9 of the Linden client this is
|
||||||
// supported
|
// supported
|
||||||
|
@ -231,7 +249,10 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
|
|
||||||
if (!m_Scene.CheckClient(m_HostCapsObj.AgentID, httpRequest.RemoteIPEndPoint))
|
if (!m_Scene.CheckClient(m_HostCapsObj.AgentID, httpRequest.RemoteIPEndPoint))
|
||||||
{
|
{
|
||||||
m_log.DebugFormat("[CAPS]: Unauthorized CAPS client");
|
m_log.DebugFormat(
|
||||||
|
"[CAPS]: Unauthorized CAPS client {0} from {1}",
|
||||||
|
m_HostCapsObj.AgentID, httpRequest.RemoteIPEndPoint);
|
||||||
|
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,7 +283,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
m_log.Debug("[CAPS]: ScriptTaskInventory Request in region: " + m_regionName);
|
// m_log.Debug("[CAPS]: ScriptTaskInventory Request in region: " + m_regionName);
|
||||||
//m_log.DebugFormat("[CAPS]: request: {0}, path: {1}, param: {2}", request, path, param);
|
//m_log.DebugFormat("[CAPS]: request: {0}, path: {1}, param: {2}", request, path, param);
|
||||||
|
|
||||||
Hashtable hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request));
|
Hashtable hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request));
|
||||||
|
@ -282,7 +303,9 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
m_dumpAssetsToFile);
|
m_dumpAssetsToFile);
|
||||||
uploader.OnUpLoad += TaskScriptUpdated;
|
uploader.OnUpLoad += TaskScriptUpdated;
|
||||||
|
|
||||||
m_HostCapsObj.HttpListener.AddStreamHandler(new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps));
|
m_HostCapsObj.HttpListener.AddStreamHandler(
|
||||||
|
new BinaryStreamHandler(
|
||||||
|
"POST", capsBase + uploaderPath, uploader.uploaderCaps, "TaskInventoryScriptUpdater", null));
|
||||||
|
|
||||||
string protocol = "http://";
|
string protocol = "http://";
|
||||||
|
|
||||||
|
@ -393,8 +416,14 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
AssetUploader uploader =
|
AssetUploader uploader =
|
||||||
new AssetUploader(assetName, assetDes, newAsset, newInvItem, parentFolder, llsdRequest.inventory_type,
|
new AssetUploader(assetName, assetDes, newAsset, newInvItem, parentFolder, llsdRequest.inventory_type,
|
||||||
llsdRequest.asset_type, capsBase + uploaderPath, m_HostCapsObj.HttpListener, m_dumpAssetsToFile);
|
llsdRequest.asset_type, capsBase + uploaderPath, m_HostCapsObj.HttpListener, m_dumpAssetsToFile);
|
||||||
|
|
||||||
m_HostCapsObj.HttpListener.AddStreamHandler(
|
m_HostCapsObj.HttpListener.AddStreamHandler(
|
||||||
new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps));
|
new BinaryStreamHandler(
|
||||||
|
"POST",
|
||||||
|
capsBase + uploaderPath,
|
||||||
|
uploader.uploaderCaps,
|
||||||
|
"NewAgentInventoryRequest",
|
||||||
|
m_HostCapsObj.AgentID.ToString()));
|
||||||
|
|
||||||
string protocol = "http://";
|
string protocol = "http://";
|
||||||
|
|
||||||
|
@ -710,7 +739,8 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
uploader.OnUpLoad += ItemUpdated;
|
uploader.OnUpLoad += ItemUpdated;
|
||||||
|
|
||||||
m_HostCapsObj.HttpListener.AddStreamHandler(
|
m_HostCapsObj.HttpListener.AddStreamHandler(
|
||||||
new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps));
|
new BinaryStreamHandler(
|
||||||
|
"POST", capsBase + uploaderPath, uploader.uploaderCaps, "NoteCardAgentInventory", null));
|
||||||
|
|
||||||
string protocol = "http://";
|
string protocol = "http://";
|
||||||
|
|
||||||
|
|
|
@ -94,7 +94,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
|
|
||||||
//scene.CommsManager.HttpServer.AddLLSDHandler("/CAPS/EQG/", EventQueueFallBack);
|
//scene.CommsManager.HttpServer.AddLLSDHandler("/CAPS/EQG/", EventQueueFallBack);
|
||||||
|
|
||||||
scene.EventManager.OnNewClient += OnNewClient;
|
// scene.EventManager.OnNewClient += OnNewClient;
|
||||||
|
|
||||||
// TODO: Leaving these open, or closing them when we
|
// TODO: Leaving these open, or closing them when we
|
||||||
// become a child is incorrect. It messes up TP in a big
|
// become a child is incorrect. It messes up TP in a big
|
||||||
|
@ -102,17 +102,19 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
// circuit is there.
|
// circuit is there.
|
||||||
|
|
||||||
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(
|
MainConsole.Instance.Commands.AddCommand(
|
||||||
"event queue",
|
"Debug",
|
||||||
false,
|
false,
|
||||||
"debug eq",
|
"debug eq",
|
||||||
"debug eq [0|1]",
|
"debug eq [0|1|2]",
|
||||||
"Turn on event queue debugging",
|
"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"
|
+ "<= 0 - turns off all event queue logging"
|
||||||
+ "debug eq 0 will turn off event queue debugging.",
|
+ ">= 1 - turns on outgoing event logging"
|
||||||
|
+ ">= 2 - turns on poll notification",
|
||||||
HandleDebugEq);
|
HandleDebugEq);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -225,29 +227,19 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
private void OnNewClient(IClientAPI client)
|
private void ClientClosed(UUID agentID, Scene scene)
|
||||||
{
|
{
|
||||||
//client.OnLogout += ClientClosed;
|
// m_log.DebugFormat("[EVENTQUEUE]: Closed client {0} in region {1}", agentID, m_scene.RegionInfo.RegionName);
|
||||||
}
|
|
||||||
|
|
||||||
// private void ClientClosed(IClientAPI client)
|
|
||||||
// {
|
|
||||||
// ClientClosed(client.AgentId);
|
|
||||||
// }
|
|
||||||
|
|
||||||
private void ClientClosed(UUID AgentID, Scene scene)
|
|
||||||
{
|
|
||||||
// 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)
|
||||||
{
|
{
|
||||||
Thread.Sleep(1000);
|
Thread.Sleep(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
lock (queues)
|
lock (queues)
|
||||||
{
|
{
|
||||||
queues.Remove(AgentID);
|
queues.Remove(agentID);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<UUID> removeitems = new List<UUID>();
|
List<UUID> removeitems = new List<UUID>();
|
||||||
|
@ -256,7 +248,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
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);
|
// 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);
|
||||||
}
|
}
|
||||||
|
@ -267,7 +259,12 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
UUID eventQueueGetUuid = m_AvatarQueueUUIDMapping[ky];
|
UUID eventQueueGetUuid = m_AvatarQueueUUIDMapping[ky];
|
||||||
m_AvatarQueueUUIDMapping.Remove(ky);
|
m_AvatarQueueUUIDMapping.Remove(ky);
|
||||||
|
|
||||||
MainServer.Instance.RemovePollServiceHTTPHandler("","/CAPS/EQG/" + eventQueueGetUuid.ToString() + "/");
|
string eqgPath = GenerateEqgCapPath(eventQueueGetUuid);
|
||||||
|
MainServer.Instance.RemovePollServiceHTTPHandler("", eqgPath);
|
||||||
|
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[EVENT QUEUE GET MODULE]: Removed EQG handler {0} for {1} in {2}",
|
||||||
|
// eqgPath, agentID, m_scene.RegionInfo.RegionName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -281,7 +278,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
{
|
{
|
||||||
searchval = m_QueueUUIDAvatarMapping[ky];
|
searchval = m_QueueUUIDAvatarMapping[ky];
|
||||||
|
|
||||||
if (searchval == AgentID)
|
if (searchval == agentID)
|
||||||
{
|
{
|
||||||
removeitems.Add(ky);
|
removeitems.Add(ky);
|
||||||
}
|
}
|
||||||
|
@ -305,6 +302,15 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Generate an Event Queue Get handler path for the given eqg uuid.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name='eqgUuid'></param>
|
||||||
|
private string GenerateEqgCapPath(UUID eqgUuid)
|
||||||
|
{
|
||||||
|
return string.Format("/CAPS/EQG/{0}/", eqgUuid);
|
||||||
|
}
|
||||||
|
|
||||||
public void OnRegisterCaps(UUID agentID, Caps caps)
|
public void OnRegisterCaps(UUID agentID, Caps caps)
|
||||||
{
|
{
|
||||||
// Register an event queue for the client
|
// Register an event queue for the client
|
||||||
|
@ -316,8 +322,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
// Let's instantiate a Queue for this agent right now
|
// Let's instantiate a Queue for this agent right now
|
||||||
TryGetQueue(agentID);
|
TryGetQueue(agentID);
|
||||||
|
|
||||||
string capsBase = "/CAPS/EQG/";
|
UUID eventQueueGetUUID;
|
||||||
UUID EventQueueGetUUID = UUID.Zero;
|
|
||||||
|
|
||||||
lock (m_AvatarQueueUUIDMapping)
|
lock (m_AvatarQueueUUIDMapping)
|
||||||
{
|
{
|
||||||
|
@ -325,44 +330,50 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
if (m_AvatarQueueUUIDMapping.ContainsKey(agentID))
|
if (m_AvatarQueueUUIDMapping.ContainsKey(agentID))
|
||||||
{
|
{
|
||||||
//m_log.DebugFormat("[EVENTQUEUE]: Found Existing UUID!");
|
//m_log.DebugFormat("[EVENTQUEUE]: Found Existing UUID!");
|
||||||
EventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID];
|
eventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
EventQueueGetUUID = UUID.Random();
|
eventQueueGetUUID = UUID.Random();
|
||||||
//m_log.DebugFormat("[EVENTQUEUE]: Using random UUID!");
|
//m_log.DebugFormat("[EVENTQUEUE]: Using random UUID!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lock (m_QueueUUIDAvatarMapping)
|
lock (m_QueueUUIDAvatarMapping)
|
||||||
{
|
{
|
||||||
if (!m_QueueUUIDAvatarMapping.ContainsKey(EventQueueGetUUID))
|
if (!m_QueueUUIDAvatarMapping.ContainsKey(eventQueueGetUUID))
|
||||||
m_QueueUUIDAvatarMapping.Add(EventQueueGetUUID, agentID);
|
m_QueueUUIDAvatarMapping.Add(eventQueueGetUUID, agentID);
|
||||||
}
|
}
|
||||||
|
|
||||||
lock (m_AvatarQueueUUIDMapping)
|
lock (m_AvatarQueueUUIDMapping)
|
||||||
{
|
{
|
||||||
if (!m_AvatarQueueUUIDMapping.ContainsKey(agentID))
|
if (!m_AvatarQueueUUIDMapping.ContainsKey(agentID))
|
||||||
m_AvatarQueueUUIDMapping.Add(agentID, EventQueueGetUUID);
|
m_AvatarQueueUUIDMapping.Add(agentID, eventQueueGetUUID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string eventQueueGetPath = GenerateEqgCapPath(eventQueueGetUUID);
|
||||||
|
|
||||||
// Register this as a caps handler
|
// Register this as a caps handler
|
||||||
// FIXME: Confusingly, we need to register separate as a capability so that the client is told about
|
// FIXME: Confusingly, we need to register separate as a capability so that the client is told about
|
||||||
// EventQueueGet when it receive capability information, but then we replace the rest handler immediately
|
// EventQueueGet when it receive capability information, but then we replace the rest handler immediately
|
||||||
// afterwards with the poll service. So for now, we'll pass a null instead to simplify code reading, but
|
// afterwards with the poll service. So for now, we'll pass a null instead to simplify code reading, but
|
||||||
// really it should be possible to directly register the poll handler as a capability.
|
// really it should be possible to directly register the poll handler as a capability.
|
||||||
caps.RegisterHandler("EventQueueGet",
|
caps.RegisterHandler("EventQueueGet", new RestHTTPHandler("POST", eventQueueGetPath, null));
|
||||||
new RestHTTPHandler("POST", capsBase + EventQueueGetUUID.ToString() + "/", null));
|
|
||||||
// delegate(Hashtable m_dhttpMethod)
|
// delegate(Hashtable m_dhttpMethod)
|
||||||
// {
|
// {
|
||||||
// return ProcessQueue(m_dhttpMethod, agentID, caps);
|
// return ProcessQueue(m_dhttpMethod, agentID, caps);
|
||||||
// }));
|
// }));
|
||||||
|
|
||||||
// This will persist this beyond the expiry of the caps handlers
|
// This will persist this beyond the expiry of the caps handlers
|
||||||
|
// TODO: Add EventQueueGet name/description for diagnostics
|
||||||
MainServer.Instance.AddPollServiceHTTPHandler(
|
MainServer.Instance.AddPollServiceHTTPHandler(
|
||||||
capsBase + EventQueueGetUUID.ToString() + "/",
|
eventQueueGetPath,
|
||||||
new PollServiceEventArgs(null, HasEvents, GetEvents, NoEvents, agentID));
|
new PollServiceEventArgs(null, HasEvents, GetEvents, NoEvents, agentID));
|
||||||
|
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[EVENT QUEUE GET MODULE]: Registered EQG handler {0} for {1} in {2}",
|
||||||
|
// eventQueueGetPath, agentID, m_scene.RegionInfo.RegionName);
|
||||||
|
|
||||||
Random rnd = new Random(Environment.TickCount);
|
Random rnd = new Random(Environment.TickCount);
|
||||||
lock (m_ids)
|
lock (m_ids)
|
||||||
{
|
{
|
||||||
|
@ -384,9 +395,25 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Logs a debug line for an outbound event queue message if appropriate.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name='element'>Element containing message</param>
|
||||||
|
private void LogOutboundDebugMessage(OSD element, UUID agentId)
|
||||||
|
{
|
||||||
|
if (element is OSDMap)
|
||||||
|
{
|
||||||
|
OSDMap ev = (OSDMap)element;
|
||||||
|
m_log.DebugFormat(
|
||||||
|
"Eq OUT {0,-30} to {1,-20} {2,-20}",
|
||||||
|
ev["message"], m_scene.GetScenePresence(agentId).Name, m_scene.RegionInfo.RegionName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Hashtable GetEvents(UUID requestID, UUID pAgentId, string request)
|
public Hashtable GetEvents(UUID requestID, UUID pAgentId, string request)
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat("[EVENT QUEUE GET MODULE]: Invoked GetEvents() for {0}", pAgentId);
|
if (DebugLevel >= 2)
|
||||||
|
m_log.DebugFormat("POLLED FOR EQ MESSAGES BY {0} in {1}", pAgentId, m_scene.RegionInfo.RegionName);
|
||||||
|
|
||||||
Queue<OSD> queue = TryGetQueue(pAgentId);
|
Queue<OSD> queue = TryGetQueue(pAgentId);
|
||||||
OSD element;
|
OSD element;
|
||||||
|
@ -410,13 +437,8 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (DebugLevel > 0 && element is OSDMap)
|
if (DebugLevel > 0)
|
||||||
{
|
LogOutboundDebugMessage(element, pAgentId);
|
||||||
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);
|
||||||
|
|
||||||
|
@ -426,13 +448,8 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
{
|
{
|
||||||
element = queue.Dequeue();
|
element = queue.Dequeue();
|
||||||
|
|
||||||
if (DebugLevel > 0 && element is OSDMap)
|
if (DebugLevel > 0)
|
||||||
{
|
LogOutboundDebugMessage(element, pAgentId);
|
||||||
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);
|
||||||
thisID++;
|
thisID++;
|
||||||
|
|
|
@ -51,7 +51,16 @@ namespace OpenSim.Region.ClientStack.Linden.Tests
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public void SetUp()
|
public void SetUp()
|
||||||
{
|
{
|
||||||
MainServer.Instance = new BaseHttpServer(9999, false, 9998, "");
|
uint port = 9999;
|
||||||
|
uint sslPort = 9998;
|
||||||
|
|
||||||
|
// This is an unfortunate bit of clean up we have to do because MainServer manages things through static
|
||||||
|
// variables and the VM is not restarted between tests.
|
||||||
|
MainServer.RemoveHttpServer(port);
|
||||||
|
|
||||||
|
BaseHttpServer server = new BaseHttpServer(port, false, sslPort, "");
|
||||||
|
MainServer.AddHttpServer(server);
|
||||||
|
MainServer.Instance = server;
|
||||||
|
|
||||||
IConfigSource config = new IniConfigSource();
|
IConfigSource config = new IniConfigSource();
|
||||||
config.AddConfig("Startup");
|
config.AddConfig("Startup");
|
||||||
|
@ -60,7 +69,7 @@ namespace OpenSim.Region.ClientStack.Linden.Tests
|
||||||
CapabilitiesModule capsModule = new CapabilitiesModule();
|
CapabilitiesModule capsModule = new CapabilitiesModule();
|
||||||
EventQueueGetModule eqgModule = new EventQueueGetModule();
|
EventQueueGetModule eqgModule = new EventQueueGetModule();
|
||||||
|
|
||||||
m_scene = SceneHelpers.SetupScene();
|
m_scene = new SceneHelpers().SetupScene();
|
||||||
SceneHelpers.SetupSceneModules(m_scene, config, capsModule, eqgModule);
|
SceneHelpers.SetupSceneModules(m_scene, config, capsModule, eqgModule);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,7 +94,7 @@ namespace OpenSim.Region.ClientStack.Linden.Tests
|
||||||
UUID spId = TestHelpers.ParseTail(0x1);
|
UUID spId = TestHelpers.ParseTail(0x1);
|
||||||
|
|
||||||
SceneHelpers.AddScenePresence(m_scene, spId);
|
SceneHelpers.AddScenePresence(m_scene, spId);
|
||||||
m_scene.IncomingCloseAgent(spId);
|
m_scene.IncomingCloseAgent(spId, false);
|
||||||
|
|
||||||
// TODO: Add more assertions for the other aspects of event queues
|
// TODO: Add more assertions for the other aspects of event queues
|
||||||
Assert.That(MainServer.Instance.GetPollServiceHandlerKeys().Count, Is.EqualTo(0));
|
Assert.That(MainServer.Instance.GetPollServiceHandlerKeys().Count, Is.EqualTo(0));
|
||||||
|
|
|
@ -132,7 +132,8 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
capUrl = "/CAPS/" + UUID.Random();
|
capUrl = "/CAPS/" + UUID.Random();
|
||||||
|
|
||||||
IRequestHandler reqHandler
|
IRequestHandler reqHandler
|
||||||
= new RestStreamHandler("POST", capUrl, m_fetchHandler.FetchInventoryRequest);
|
= new RestStreamHandler(
|
||||||
|
"POST", capUrl, m_fetchHandler.FetchInventoryRequest, capName, agentID.ToString());
|
||||||
|
|
||||||
caps.RegisterHandler(capName, reqHandler);
|
caps.RegisterHandler(capName, reqHandler);
|
||||||
}
|
}
|
||||||
|
|
|
@ -120,11 +120,13 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat("[GETMESH]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName);
|
// m_log.DebugFormat("[GETMESH]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName);
|
||||||
GetMeshHandler gmeshHandler = new GetMeshHandler(m_AssetService);
|
GetMeshHandler gmeshHandler = new GetMeshHandler(m_AssetService);
|
||||||
IRequestHandler reqHandler = new RestHTTPHandler("GET", "/CAPS/" + UUID.Random(),
|
IRequestHandler reqHandler
|
||||||
delegate(Hashtable m_dhttpMethod)
|
= new RestHTTPHandler(
|
||||||
{
|
"GET",
|
||||||
return gmeshHandler.ProcessGetMesh(m_dhttpMethod, UUID.Zero, null);
|
"/CAPS/" + UUID.Random(),
|
||||||
});
|
httpMethod => gmeshHandler.ProcessGetMesh(httpMethod, UUID.Zero, null),
|
||||||
|
"GetMesh",
|
||||||
|
agentID.ToString());
|
||||||
|
|
||||||
caps.RegisterHandler("GetMesh", reqHandler);
|
caps.RegisterHandler("GetMesh", reqHandler);
|
||||||
}
|
}
|
||||||
|
|
|
@ -130,7 +130,9 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
if (m_URL == "localhost")
|
if (m_URL == "localhost")
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat("[GETTEXTURE]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName);
|
// m_log.DebugFormat("[GETTEXTURE]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName);
|
||||||
caps.RegisterHandler("GetTexture", new GetTextureHandler("/CAPS/" + capID + "/", m_assetService));
|
caps.RegisterHandler(
|
||||||
|
"GetTexture",
|
||||||
|
new GetTextureHandler("/CAPS/" + capID + "/", m_assetService, "GetTexture", agentID.ToString()));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -117,7 +117,9 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
|
|
||||||
public void RegisterCaps(UUID agentID, Caps caps)
|
public void RegisterCaps(UUID agentID, Caps caps)
|
||||||
{
|
{
|
||||||
IRequestHandler reqHandler = new RestHTTPHandler("GET", "/CAPS/" + UUID.Random(), MeshUploadFlag);
|
IRequestHandler reqHandler
|
||||||
|
= new RestHTTPHandler("GET", "/CAPS/" + UUID.Random(), MeshUploadFlag, "MeshUploadFlag", agentID.ToString());
|
||||||
|
|
||||||
caps.RegisterHandler("MeshUploadFlag", reqHandler);
|
caps.RegisterHandler("MeshUploadFlag", reqHandler);
|
||||||
m_agentID = agentID;
|
m_agentID = agentID;
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,6 +56,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
// private IAssetService m_assetService;
|
// private IAssetService m_assetService;
|
||||||
private bool m_dumpAssetsToFile = false;
|
private bool m_dumpAssetsToFile = false;
|
||||||
private bool m_enabled = true;
|
private bool m_enabled = true;
|
||||||
|
private int m_levelUpload = 0;
|
||||||
|
|
||||||
#region IRegionModuleBase Members
|
#region IRegionModuleBase Members
|
||||||
|
|
||||||
|
@ -72,6 +73,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_enabled = meshConfig.GetBoolean("AllowMeshUpload", true);
|
m_enabled = meshConfig.GetBoolean("AllowMeshUpload", true);
|
||||||
|
m_levelUpload = meshConfig.GetInt("LevelUpload", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddRegion(Scene pScene)
|
public void AddRegion(Scene pScene)
|
||||||
|
@ -113,40 +115,55 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
UUID capID = UUID.Random();
|
UUID capID = UUID.Random();
|
||||||
|
|
||||||
// m_log.Debug("[NEW FILE AGENT INVENTORY VARIABLE PRICE]: /CAPS/" + capID);
|
// m_log.Debug("[NEW FILE AGENT INVENTORY VARIABLE PRICE]: /CAPS/" + capID);
|
||||||
caps.RegisterHandler("NewFileAgentInventoryVariablePrice",
|
caps.RegisterHandler(
|
||||||
|
"NewFileAgentInventoryVariablePrice",
|
||||||
new LLSDStreamhandler<LLSDAssetUploadRequest, LLSDNewFileAngentInventoryVariablePriceReplyResponse>("POST",
|
new LLSDStreamhandler<LLSDAssetUploadRequest, LLSDNewFileAngentInventoryVariablePriceReplyResponse>(
|
||||||
|
"POST",
|
||||||
"/CAPS/" + capID.ToString(),
|
"/CAPS/" + capID.ToString(),
|
||||||
delegate(LLSDAssetUploadRequest req)
|
req => NewAgentInventoryRequest(req, agentID),
|
||||||
{
|
"NewFileAgentInventoryVariablePrice",
|
||||||
return NewAgentInventoryRequest(req,agentID);
|
agentID.ToString()));
|
||||||
}));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
public LLSDNewFileAngentInventoryVariablePriceReplyResponse NewAgentInventoryRequest(LLSDAssetUploadRequest llsdRequest, UUID agentID)
|
public LLSDNewFileAngentInventoryVariablePriceReplyResponse NewAgentInventoryRequest(LLSDAssetUploadRequest llsdRequest, UUID agentID)
|
||||||
{
|
{
|
||||||
|
|
||||||
//TODO: The Mesh uploader uploads many types of content. If you're going to implement a Money based limit
|
//TODO: The Mesh uploader uploads many types of content. If you're going to implement a Money based limit
|
||||||
// You need to be aware of this and
|
// you need to be aware of this
|
||||||
|
|
||||||
|
|
||||||
//if (llsdRequest.asset_type == "texture" ||
|
//if (llsdRequest.asset_type == "texture" ||
|
||||||
// llsdRequest.asset_type == "animation" ||
|
// llsdRequest.asset_type == "animation" ||
|
||||||
// llsdRequest.asset_type == "sound")
|
// llsdRequest.asset_type == "sound")
|
||||||
// {
|
// {
|
||||||
|
// check user level
|
||||||
|
|
||||||
|
ScenePresence avatar = null;
|
||||||
IClientAPI client = null;
|
IClientAPI client = null;
|
||||||
|
m_scene.TryGetScenePresence(agentID, out avatar);
|
||||||
|
|
||||||
|
if (avatar != null)
|
||||||
|
{
|
||||||
|
client = avatar.ControllingClient;
|
||||||
|
|
||||||
|
if (avatar.UserLevel < m_levelUpload)
|
||||||
|
{
|
||||||
|
if (client != null)
|
||||||
|
client.SendAgentAlertMessage("Unable to upload asset. Insufficient permissions.", false);
|
||||||
|
|
||||||
|
LLSDNewFileAngentInventoryVariablePriceReplyResponse errorResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse();
|
||||||
|
errorResponse.rsvp = "";
|
||||||
|
errorResponse.state = "error";
|
||||||
|
return errorResponse;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check funds
|
||||||
IMoneyModule mm = m_scene.RequestModuleInterface<IMoneyModule>();
|
IMoneyModule mm = m_scene.RequestModuleInterface<IMoneyModule>();
|
||||||
|
|
||||||
if (mm != null)
|
if (mm != null)
|
||||||
{
|
{
|
||||||
if (m_scene.TryGetClient(agentID, out client))
|
if (!mm.UploadCovered(agentID, mm.UploadCharge))
|
||||||
{
|
|
||||||
if (!mm.UploadCovered(client.AgentId, mm.UploadCharge))
|
|
||||||
{
|
{
|
||||||
if (client != null)
|
if (client != null)
|
||||||
client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false);
|
client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false);
|
||||||
|
@ -157,7 +174,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
return errorResponse;
|
return errorResponse;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// }
|
// }
|
||||||
|
|
||||||
string assetName = llsdRequest.name;
|
string assetName = llsdRequest.name;
|
||||||
|
@ -171,8 +188,14 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
AssetUploader uploader =
|
AssetUploader uploader =
|
||||||
new AssetUploader(assetName, assetDes, newAsset, newInvItem, parentFolder, llsdRequest.inventory_type,
|
new AssetUploader(assetName, assetDes, newAsset, newInvItem, parentFolder, llsdRequest.inventory_type,
|
||||||
llsdRequest.asset_type, capsBase + uploaderPath, MainServer.Instance, m_dumpAssetsToFile);
|
llsdRequest.asset_type, capsBase + uploaderPath, MainServer.Instance, m_dumpAssetsToFile);
|
||||||
|
|
||||||
MainServer.Instance.AddStreamHandler(
|
MainServer.Instance.AddStreamHandler(
|
||||||
new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps));
|
new BinaryStreamHandler(
|
||||||
|
"POST",
|
||||||
|
capsBase + uploaderPath,
|
||||||
|
uploader.uploaderCaps,
|
||||||
|
"NewFileAgentInventoryVariablePrice",
|
||||||
|
agentID.ToString()));
|
||||||
|
|
||||||
string protocol = "http://";
|
string protocol = "http://";
|
||||||
|
|
||||||
|
@ -185,7 +208,6 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
|
|
||||||
LLSDNewFileAngentInventoryVariablePriceReplyResponse uploadResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse();
|
LLSDNewFileAngentInventoryVariablePriceReplyResponse uploadResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse();
|
||||||
|
|
||||||
|
|
||||||
uploadResponse.rsvp = uploaderURL;
|
uploadResponse.rsvp = uploaderURL;
|
||||||
uploadResponse.state = "upload";
|
uploadResponse.state = "upload";
|
||||||
uploadResponse.resource_cost = 0;
|
uploadResponse.resource_cost = 0;
|
||||||
|
@ -202,6 +224,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
pinventoryItem, pparentFolder, pdata, pinventoryType,
|
pinventoryItem, pparentFolder, pdata, pinventoryType,
|
||||||
passetType,agentID);
|
passetType,agentID);
|
||||||
};
|
};
|
||||||
|
|
||||||
return uploadResponse;
|
return uploadResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -66,12 +66,14 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
|
|
||||||
// m_log.InfoFormat("[OBJECTADD]: {0}", "/CAPS/OA/" + capuuid + "/");
|
// m_log.InfoFormat("[OBJECTADD]: {0}", "/CAPS/OA/" + capuuid + "/");
|
||||||
|
|
||||||
caps.RegisterHandler("ObjectAdd",
|
caps.RegisterHandler(
|
||||||
new RestHTTPHandler("POST", "/CAPS/OA/" + capuuid + "/",
|
"ObjectAdd",
|
||||||
delegate(Hashtable m_dhttpMethod)
|
new RestHTTPHandler(
|
||||||
{
|
"POST",
|
||||||
return ProcessAdd(m_dhttpMethod, agentID, caps);
|
"/CAPS/OA/" + capuuid + "/",
|
||||||
}));
|
httpMethod => ProcessAdd(httpMethod, agentID, caps),
|
||||||
|
"ObjectAdd",
|
||||||
|
agentID.ToString()));;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Hashtable ProcessAdd(Hashtable request, UUID AgentId, Caps cap)
|
public Hashtable ProcessAdd(Hashtable request, UUID AgentId, Caps cap)
|
||||||
|
|
|
@ -106,12 +106,15 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
UUID capID = UUID.Random();
|
UUID capID = UUID.Random();
|
||||||
|
|
||||||
// m_log.Debug("[UPLOAD OBJECT ASSET MODULE]: /CAPS/" + capID);
|
// m_log.Debug("[UPLOAD OBJECT ASSET MODULE]: /CAPS/" + capID);
|
||||||
caps.RegisterHandler("UploadObjectAsset",
|
caps.RegisterHandler(
|
||||||
new RestHTTPHandler("POST", "/CAPS/OA/" + capID + "/",
|
"UploadObjectAsset",
|
||||||
delegate(Hashtable m_dhttpMethod)
|
new RestHTTPHandler(
|
||||||
{
|
"POST",
|
||||||
return ProcessAdd(m_dhttpMethod, agentID, caps);
|
"/CAPS/OA/" + capID + "/",
|
||||||
}));
|
httpMethod => ProcessAdd(httpMethod, agentID, caps),
|
||||||
|
"UploadObjectAsset",
|
||||||
|
agentID.ToString()));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
caps.RegisterHandler("NewFileAgentInventoryVariablePrice",
|
caps.RegisterHandler("NewFileAgentInventoryVariablePrice",
|
||||||
|
|
||||||
|
@ -330,7 +333,6 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
grp.AbsolutePosition = obj.Position;
|
grp.AbsolutePosition = obj.Position;
|
||||||
prim.RotationOffset = obj.Rotation;
|
prim.RotationOffset = obj.Rotation;
|
||||||
|
|
||||||
grp.IsAttachment = false;
|
|
||||||
// Required for linking
|
// Required for linking
|
||||||
grp.RootPart.ClearUpdateSchedule();
|
grp.RootPart.ClearUpdateSchedule();
|
||||||
|
|
||||||
|
|
|
@ -154,7 +154,9 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
public void RegisterCaps(UUID agentID, Caps caps)
|
public void RegisterCaps(UUID agentID, Caps caps)
|
||||||
{
|
{
|
||||||
IRequestHandler reqHandler
|
IRequestHandler reqHandler
|
||||||
= new RestHTTPHandler("GET", "/CAPS/" + UUID.Random(), HandleSimulatorFeaturesRequest);
|
= new RestHTTPHandler(
|
||||||
|
"GET", "/CAPS/" + UUID.Random(),
|
||||||
|
HandleSimulatorFeaturesRequest, "SimulatorFeatures", agentID.ToString());
|
||||||
|
|
||||||
caps.RegisterHandler("SimulatorFeatures", reqHandler);
|
caps.RegisterHandler("SimulatorFeatures", reqHandler);
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,7 +106,9 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
"POST",
|
"POST",
|
||||||
"/CAPS/" + caps.CapsObjectPath + m_uploadBakedTexturePath,
|
"/CAPS/" + caps.CapsObjectPath + m_uploadBakedTexturePath,
|
||||||
new UploadBakedTextureHandler(
|
new UploadBakedTextureHandler(
|
||||||
caps, m_scene.AssetService, m_persistBakedTextures).UploadBakedTexture));
|
caps, m_scene.AssetService, m_persistBakedTextures).UploadBakedTexture,
|
||||||
|
"UploadBakedTexture",
|
||||||
|
agentID.ToString()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -144,7 +144,12 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
capUrl = "/CAPS/" + UUID.Random();
|
capUrl = "/CAPS/" + UUID.Random();
|
||||||
|
|
||||||
IRequestHandler reqHandler
|
IRequestHandler reqHandler
|
||||||
= new RestStreamHandler("POST", capUrl, m_webFetchHandler.FetchInventoryDescendentsRequest);
|
= new RestStreamHandler(
|
||||||
|
"POST",
|
||||||
|
capUrl,
|
||||||
|
m_webFetchHandler.FetchInventoryDescendentsRequest,
|
||||||
|
"FetchInventoryDescendents2",
|
||||||
|
agentID.ToString());
|
||||||
|
|
||||||
caps.RegisterHandler(capName, reqHandler);
|
caps.RegisterHandler(capName, reqHandler);
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
public sealed class IncomingPacket
|
public sealed class IncomingPacket
|
||||||
{
|
{
|
||||||
/// <summary>Client this packet came from</summary>
|
/// <summary>Client this packet came from</summary>
|
||||||
public LLUDPClient Client;
|
public LLClientView Client;
|
||||||
|
|
||||||
/// <summary>Packet data that has been received</summary>
|
/// <summary>Packet data that has been received</summary>
|
||||||
public Packet Packet;
|
public Packet Packet;
|
||||||
|
|
||||||
|
@ -48,7 +49,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="client">Reference to the client this packet came from</param>
|
/// <param name="client">Reference to the client this packet came from</param>
|
||||||
/// <param name="packet">Packet data</param>
|
/// <param name="packet">Packet data</param>
|
||||||
public IncomingPacket(LLUDPClient client, Packet packet)
|
public IncomingPacket(LLClientView client, Packet packet)
|
||||||
{
|
{
|
||||||
Client = client;
|
Client = client;
|
||||||
Packet = packet;
|
Packet = packet;
|
||||||
|
|
|
@ -59,7 +59,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
/// Handles new client connections
|
/// Handles new client connections
|
||||||
/// Constructor takes a single Packet and authenticates everything
|
/// Constructor takes a single Packet and authenticates everything
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class LLClientView : IClientAPI, IClientCore, IClientIM, IClientChat, IClientIPEndpoint, IStatsCollector
|
public class LLClientView : IClientAPI, IClientCore, IClientIM, IClientChat, IClientInventory, IStatsCollector
|
||||||
{
|
{
|
||||||
/// <value>
|
/// <value>
|
||||||
/// Debug packet level. See OpenSim.RegisterConsoleCommands() for more details.
|
/// Debug packet level. See OpenSim.RegisterConsoleCommands() for more details.
|
||||||
|
@ -348,8 +348,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
private int m_animationSequenceNumber = 1;
|
private int m_animationSequenceNumber = 1;
|
||||||
private bool m_SendLogoutPacketWhenClosing = true;
|
private bool m_SendLogoutPacketWhenClosing = true;
|
||||||
private AgentUpdateArgs lastarg;
|
private AgentUpdateArgs lastarg;
|
||||||
private bool m_IsActive = true;
|
|
||||||
private bool m_IsLoggingOut = false;
|
|
||||||
|
|
||||||
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
|
||||||
|
@ -358,7 +356,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
protected string m_lastName;
|
protected string m_lastName;
|
||||||
protected Thread m_clientThread;
|
protected Thread m_clientThread;
|
||||||
protected Vector3 m_startpos;
|
protected Vector3 m_startpos;
|
||||||
protected EndPoint m_userEndPoint;
|
|
||||||
protected UUID m_activeGroupID;
|
protected UUID m_activeGroupID;
|
||||||
protected string m_activeGroupName = String.Empty;
|
protected string m_activeGroupName = String.Empty;
|
||||||
protected ulong m_activeGroupPowers;
|
protected ulong m_activeGroupPowers;
|
||||||
|
@ -385,7 +382,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 ISceneAgent SceneAgent { get; 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; } }
|
||||||
|
@ -414,16 +411,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
public uint CircuitCode { get { return m_circuitCode; } }
|
public uint CircuitCode { get { return m_circuitCode; } }
|
||||||
public int MoneyBalance { get { return m_moneyBalance; } }
|
public int MoneyBalance { get { return m_moneyBalance; } }
|
||||||
public int NextAnimationSequenceNumber { get { return m_animationSequenceNumber++; } }
|
public int NextAnimationSequenceNumber { get { return m_animationSequenceNumber++; } }
|
||||||
public bool IsActive
|
|
||||||
{
|
/// <summary>
|
||||||
get { return m_IsActive; }
|
/// As well as it's function in IClientAPI, in LLClientView we are locking on this property in order to
|
||||||
set { m_IsActive = value; }
|
/// prevent race conditions by different threads calling Close().
|
||||||
}
|
/// </summary>
|
||||||
public bool IsLoggingOut
|
public bool IsActive { get; set; }
|
||||||
{
|
|
||||||
get { return m_IsLoggingOut; }
|
/// <summary>
|
||||||
set { m_IsLoggingOut = value; }
|
/// Used to synchronise threads when client is being closed.
|
||||||
}
|
/// </summary>
|
||||||
|
public Object CloseSyncLock { get; private set; }
|
||||||
|
|
||||||
|
public bool IsLoggingOut { get; set; }
|
||||||
|
|
||||||
public bool DisableFacelights
|
public bool DisableFacelights
|
||||||
{
|
{
|
||||||
|
@ -443,14 +443,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructor
|
/// Constructor
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public LLClientView(EndPoint remoteEP, Scene scene, LLUDPServer udpServer, LLUDPClient udpClient, AuthenticateResponse sessionInfo,
|
public LLClientView(Scene scene, LLUDPServer udpServer, LLUDPClient udpClient, AuthenticateResponse sessionInfo,
|
||||||
UUID agentId, UUID sessionId, uint circuitCode)
|
UUID agentId, UUID sessionId, uint circuitCode)
|
||||||
{
|
{
|
||||||
// DebugPacketLevel = 1;
|
// DebugPacketLevel = 1;
|
||||||
|
|
||||||
|
CloseSyncLock = new Object();
|
||||||
|
|
||||||
RegisterInterface<IClientIM>(this);
|
RegisterInterface<IClientIM>(this);
|
||||||
|
RegisterInterface<IClientInventory>(this);
|
||||||
RegisterInterface<IClientChat>(this);
|
RegisterInterface<IClientChat>(this);
|
||||||
RegisterInterface<IClientIPEndpoint>(this);
|
|
||||||
|
|
||||||
InitDefaultAnimations();
|
InitDefaultAnimations();
|
||||||
|
|
||||||
|
@ -470,7 +472,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
m_sessionId = sessionId;
|
m_sessionId = sessionId;
|
||||||
m_secureSessionId = sessionInfo.LoginInfo.SecureSession;
|
m_secureSessionId = sessionInfo.LoginInfo.SecureSession;
|
||||||
m_circuitCode = circuitCode;
|
m_circuitCode = circuitCode;
|
||||||
m_userEndPoint = remoteEP;
|
|
||||||
m_firstName = sessionInfo.LoginInfo.First;
|
m_firstName = sessionInfo.LoginInfo.First;
|
||||||
m_lastName = sessionInfo.LoginInfo.Last;
|
m_lastName = sessionInfo.LoginInfo.Last;
|
||||||
m_startpos = sessionInfo.LoginInfo.StartPos;
|
m_startpos = sessionInfo.LoginInfo.StartPos;
|
||||||
|
@ -484,25 +485,48 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
m_prioritizer = new Prioritizer(m_scene);
|
m_prioritizer = new Prioritizer(m_scene);
|
||||||
|
|
||||||
RegisterLocalPacketHandlers();
|
RegisterLocalPacketHandlers();
|
||||||
|
|
||||||
|
IsActive = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Client Methods
|
#region Client Methods
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Shut down the client view
|
|
||||||
/// </summary>
|
|
||||||
public void Close()
|
public void Close()
|
||||||
|
{
|
||||||
|
Close(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Close(bool force)
|
||||||
|
{
|
||||||
|
// We lock here to prevent race conditions between two threads calling close simultaneously (e.g.
|
||||||
|
// a simultaneous relog just as a client is being closed out due to no packet ack from the old connection.
|
||||||
|
lock (CloseSyncLock)
|
||||||
|
{
|
||||||
|
// We still perform a force close inside the sync lock since this is intended to attempt close where
|
||||||
|
// there is some unidentified connection problem, not where we have issues due to deadlock
|
||||||
|
if (!IsActive && !force)
|
||||||
|
return;
|
||||||
|
|
||||||
|
IsActive = false;
|
||||||
|
CloseWithoutChecks();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Closes down the client view without first checking whether it is active.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This exists because LLUDPServer has to set IsActive = false in earlier synchronous code before calling
|
||||||
|
/// CloseWithoutIsActiveCheck asynchronously.
|
||||||
|
///
|
||||||
|
/// Callers must lock ClosingSyncLock before calling.
|
||||||
|
/// </remarks>
|
||||||
|
public void CloseWithoutChecks()
|
||||||
{
|
{
|
||||||
m_log.DebugFormat(
|
m_log.DebugFormat(
|
||||||
"[CLIENT]: Close has been called for {0} attached to scene {1}",
|
"[CLIENT]: Close has been called for {0} attached to scene {1}",
|
||||||
Name, m_scene.RegionInfo.RegionName);
|
Name, m_scene.RegionInfo.RegionName);
|
||||||
|
|
||||||
// Send the STOP packet
|
|
||||||
DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator);
|
|
||||||
OutPacket(disable, ThrottleOutPacketType.Unknown);
|
|
||||||
|
|
||||||
IsActive = false;
|
|
||||||
|
|
||||||
// Shutdown the image manager
|
// Shutdown the image manager
|
||||||
ImageManager.Close();
|
ImageManager.Close();
|
||||||
|
|
||||||
|
@ -698,7 +722,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
|
||||||
public virtual void Start()
|
public virtual void Start()
|
||||||
{
|
{
|
||||||
SceneAgent = m_scene.AddNewClient(this, PresenceType.User);
|
m_scene.AddNewClient(this, PresenceType.User);
|
||||||
|
|
||||||
RefreshGroupMembership();
|
RefreshGroupMembership();
|
||||||
}
|
}
|
||||||
|
@ -2725,6 +2749,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SendAssetNotFound(AssetRequestToClient req)
|
||||||
|
{
|
||||||
|
TransferInfoPacket Transfer = new TransferInfoPacket();
|
||||||
|
Transfer.TransferInfo.ChannelType = 2;
|
||||||
|
Transfer.TransferInfo.Status = -2;
|
||||||
|
Transfer.TransferInfo.TargetType = 0;
|
||||||
|
Transfer.TransferInfo.Params = req.Params;
|
||||||
|
Transfer.TransferInfo.Size = 0;
|
||||||
|
Transfer.TransferInfo.TransferID = req.TransferRequestID;
|
||||||
|
Transfer.Header.Zerocoded = true;
|
||||||
|
OutPacket(Transfer, ThrottleOutPacketType.Asset);
|
||||||
|
}
|
||||||
|
|
||||||
public void SendTexture(AssetBase TextureAsset)
|
public void SendTexture(AssetBase TextureAsset)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -3563,7 +3600,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
|
||||||
public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations)
|
public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations)
|
||||||
{
|
{
|
||||||
if (!IsActive) return; // We don't need to update inactive clients.
|
// We don't need to update inactive clients.
|
||||||
|
if (!IsActive)
|
||||||
|
return;
|
||||||
|
|
||||||
CoarseLocationUpdatePacket loc = (CoarseLocationUpdatePacket)PacketPool.Instance.GetPacket(PacketType.CoarseLocationUpdate);
|
CoarseLocationUpdatePacket loc = (CoarseLocationUpdatePacket)PacketPool.Instance.GetPacket(PacketType.CoarseLocationUpdate);
|
||||||
loc.Header.Reliable = false;
|
loc.Header.Reliable = false;
|
||||||
|
@ -3728,8 +3767,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
++updatesThisCall;
|
|
||||||
|
|
||||||
#region UpdateFlags to packet type conversion
|
#region UpdateFlags to packet type conversion
|
||||||
|
|
||||||
PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
|
PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
|
||||||
|
@ -3786,20 +3823,53 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
|
||||||
if (!canUseImproved && !canUseCompressed)
|
if (!canUseImproved && !canUseCompressed)
|
||||||
{
|
{
|
||||||
|
ObjectUpdatePacket.ObjectDataBlock updateBlock;
|
||||||
|
|
||||||
if (update.Entity is ScenePresence)
|
if (update.Entity is ScenePresence)
|
||||||
{
|
{
|
||||||
objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
|
updateBlock = CreateAvatarUpdateBlock((ScenePresence)update.Entity);
|
||||||
objectUpdates.Value.Add(update);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
|
SceneObjectPart part = (SceneObjectPart)update.Entity;
|
||||||
objectUpdates.Value.Add(update);
|
updateBlock = CreatePrimUpdateBlock(part, AgentId);
|
||||||
|
|
||||||
|
// If the part has become a private hud since the update was scheduled then we do not
|
||||||
|
// want to send it to other avatars.
|
||||||
|
if (part.ParentGroup.IsAttachment
|
||||||
|
&& part.ParentGroup.HasPrivateAttachmentPoint
|
||||||
|
&& part.ParentGroup.AttachedAvatar != AgentId)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// If the part has since been deleted, then drop the update. In the case of attachments,
|
||||||
|
// this is to avoid spurious updates to other viewers since post-processing of attachments
|
||||||
|
// has to change the IsAttachment flag for various reasons (which will end up in a pass
|
||||||
|
// of the test above).
|
||||||
|
//
|
||||||
|
// Actual deletions (kills) happen in another method.
|
||||||
|
if (part.ParentGroup.IsDeleted)
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
objectUpdateBlocks.Value.Add(updateBlock);
|
||||||
|
objectUpdates.Value.Add(update);
|
||||||
}
|
}
|
||||||
else if (!canUseImproved)
|
else if (!canUseImproved)
|
||||||
{
|
{
|
||||||
compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags));
|
SceneObjectPart part = (SceneObjectPart)update.Entity;
|
||||||
|
ObjectUpdateCompressedPacket.ObjectDataBlock compressedBlock
|
||||||
|
= CreateCompressedUpdateBlock(part, updateFlags);
|
||||||
|
|
||||||
|
// If the part has since been deleted, then drop the update. In the case of attachments,
|
||||||
|
// this is to avoid spurious updates to other viewers since post-processing of attachments
|
||||||
|
// has to change the IsAttachment flag for various reasons (which will end up in a pass
|
||||||
|
// of the test above).
|
||||||
|
//
|
||||||
|
// Actual deletions (kills) happen in another method.
|
||||||
|
if (part.ParentGroup.IsDeleted)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
compressedUpdateBlocks.Value.Add(compressedBlock);
|
||||||
compressedUpdates.Value.Add(update);
|
compressedUpdates.Value.Add(update);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -3812,16 +3882,41 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseUpdateBlock
|
||||||
|
= CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures));
|
||||||
|
|
||||||
// Everything else goes here
|
// Everything else goes here
|
||||||
terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
|
if (update.Entity is SceneObjectPart)
|
||||||
|
{
|
||||||
|
SceneObjectPart part = (SceneObjectPart)update.Entity;
|
||||||
|
|
||||||
|
// If the part has become a private hud since the update was scheduled then we do not
|
||||||
|
// want to send it to other avatars.
|
||||||
|
if (part.ParentGroup.IsAttachment
|
||||||
|
&& part.ParentGroup.HasPrivateAttachmentPoint
|
||||||
|
&& part.ParentGroup.AttachedAvatar != AgentId)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// If the part has since been deleted, then drop the update. In the case of attachments,
|
||||||
|
// this is to avoid spurious updates to other viewers since post-processing of attachments
|
||||||
|
// has to change the IsAttachment flag for various reasons (which will end up in a pass
|
||||||
|
// of the test above).
|
||||||
|
//
|
||||||
|
// Actual deletions (kills) happen in another method.
|
||||||
|
if (part.ParentGroup.IsDeleted)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
terseUpdateBlocks.Value.Add(terseUpdateBlock);
|
||||||
terseUpdates.Value.Add(update);
|
terseUpdates.Value.Add(update);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
++updatesThisCall;
|
||||||
|
|
||||||
#endregion Block Construction
|
#endregion Block Construction
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#region Packet Sending
|
#region Packet Sending
|
||||||
ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
|
ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
|
||||||
|
|
||||||
|
@ -4273,7 +4368,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
block.OwnerID = sop.OwnerID;
|
block.OwnerID = sop.OwnerID;
|
||||||
|
|
||||||
block.ItemID = sop.FromUserInventoryItemID;
|
block.ItemID = sop.FromUserInventoryItemID;
|
||||||
block.FolderID = UUID.Zero; // sop.FromFolderID ??
|
block.FolderID = UUID.Zero; // sog.FromFolderID ??
|
||||||
block.FromTaskID = UUID.Zero; // ???
|
block.FromTaskID = UUID.Zero; // ???
|
||||||
block.InventorySerial = (short)sop.InventorySerial;
|
block.InventorySerial = (short)sop.InventorySerial;
|
||||||
|
|
||||||
|
@ -4959,7 +5054,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
update.MediaURL = Utils.EmptyBytes; // FIXME: Support this in OpenSim
|
update.MediaURL = Utils.EmptyBytes; // FIXME: Support this in OpenSim
|
||||||
if (data.ParentGroup.IsAttachment)
|
if (data.ParentGroup.IsAttachment)
|
||||||
{
|
{
|
||||||
update.NameValue = Util.StringToBytes256("AttachItemID STRING RW SV " + data.FromItemID);
|
update.NameValue = Util.StringToBytes256("AttachItemID STRING RW SV " + data.ParentGroup.FromItemID);
|
||||||
update.State = (byte)((data.ParentGroup.AttachmentPoint % 16) * 16 + (data.ParentGroup.AttachmentPoint / 16));
|
update.State = (byte)((data.ParentGroup.AttachmentPoint % 16) * 16 + (data.ParentGroup.AttachmentPoint / 16));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -5104,7 +5199,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
AddLocalPacketHandler(PacketType.ChatFromViewer, HandleChatFromViewer);
|
AddLocalPacketHandler(PacketType.ChatFromViewer, HandleChatFromViewer);
|
||||||
AddLocalPacketHandler(PacketType.AvatarPropertiesUpdate, HandlerAvatarPropertiesUpdate);
|
AddLocalPacketHandler(PacketType.AvatarPropertiesUpdate, HandlerAvatarPropertiesUpdate);
|
||||||
AddLocalPacketHandler(PacketType.ScriptDialogReply, HandlerScriptDialogReply);
|
AddLocalPacketHandler(PacketType.ScriptDialogReply, HandlerScriptDialogReply);
|
||||||
AddLocalPacketHandler(PacketType.ImprovedInstantMessage, HandlerImprovedInstantMessage, false);
|
AddLocalPacketHandler(PacketType.ImprovedInstantMessage, HandlerImprovedInstantMessage);
|
||||||
AddLocalPacketHandler(PacketType.AcceptFriendship, HandlerAcceptFriendship);
|
AddLocalPacketHandler(PacketType.AcceptFriendship, HandlerAcceptFriendship);
|
||||||
AddLocalPacketHandler(PacketType.DeclineFriendship, HandlerDeclineFriendship);
|
AddLocalPacketHandler(PacketType.DeclineFriendship, HandlerDeclineFriendship);
|
||||||
AddLocalPacketHandler(PacketType.TerminateFriendship, HandlerTerminateFriendship);
|
AddLocalPacketHandler(PacketType.TerminateFriendship, HandlerTerminateFriendship);
|
||||||
|
@ -5787,7 +5882,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
// My guess is this is the folder to stick the calling card into
|
// My guess is this is the folder to stick the calling card into
|
||||||
List<UUID> callingCardFolders = new List<UUID>();
|
List<UUID> callingCardFolders = new List<UUID>();
|
||||||
|
|
||||||
UUID agentID = afriendpack.AgentData.AgentID;
|
|
||||||
UUID transactionID = afriendpack.TransactionBlock.TransactionID;
|
UUID transactionID = afriendpack.TransactionBlock.TransactionID;
|
||||||
|
|
||||||
for (int fi = 0; fi < afriendpack.FolderData.Length; fi++)
|
for (int fi = 0; fi < afriendpack.FolderData.Length; fi++)
|
||||||
|
@ -5798,10 +5892,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
FriendActionDelegate handlerApproveFriendRequest = OnApproveFriendRequest;
|
FriendActionDelegate handlerApproveFriendRequest = OnApproveFriendRequest;
|
||||||
if (handlerApproveFriendRequest != null)
|
if (handlerApproveFriendRequest != null)
|
||||||
{
|
{
|
||||||
handlerApproveFriendRequest(this, agentID, transactionID, callingCardFolders);
|
handlerApproveFriendRequest(this, transactionID, callingCardFolders);
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool HandlerDeclineFriendship(IClientAPI sender, Packet Pack)
|
private bool HandlerDeclineFriendship(IClientAPI sender, Packet Pack)
|
||||||
|
@ -5820,7 +5914,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
if (OnDenyFriendRequest != null)
|
if (OnDenyFriendRequest != null)
|
||||||
{
|
{
|
||||||
OnDenyFriendRequest(this,
|
OnDenyFriendRequest(this,
|
||||||
dfriendpack.AgentData.AgentID,
|
|
||||||
dfriendpack.TransactionBlock.TransactionID,
|
dfriendpack.TransactionBlock.TransactionID,
|
||||||
null);
|
null);
|
||||||
}
|
}
|
||||||
|
@ -5840,14 +5933,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
UUID listOwnerAgentID = tfriendpack.AgentData.AgentID;
|
|
||||||
UUID exFriendID = tfriendpack.ExBlock.OtherID;
|
UUID exFriendID = tfriendpack.ExBlock.OtherID;
|
||||||
FriendshipTermination TerminateFriendshipHandler = OnTerminateFriendship;
|
FriendshipTermination TerminateFriendshipHandler = OnTerminateFriendship;
|
||||||
if (TerminateFriendshipHandler != null)
|
if (TerminateFriendshipHandler != null)
|
||||||
{
|
{
|
||||||
TerminateFriendshipHandler(this, listOwnerAgentID, exFriendID);
|
TerminateFriendshipHandler(this, exFriendID);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11165,12 +11258,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
GrantUserFriendRights GrantUserRightsHandler = OnGrantUserRights;
|
GrantUserFriendRights GrantUserRightsHandler = OnGrantUserRights;
|
||||||
if (GrantUserRightsHandler != null)
|
if (GrantUserRightsHandler != null)
|
||||||
GrantUserRightsHandler(this,
|
GrantUserRightsHandler(this,
|
||||||
GrantUserRights.AgentData.AgentID,
|
|
||||||
GrantUserRights.Rights[0].AgentRelated,
|
GrantUserRights.Rights[0].AgentRelated,
|
||||||
GrantUserRights.Rights[0].RelatedRights);
|
GrantUserRights.Rights[0].RelatedRights);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11683,7 +11777,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
if (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 (DebugPacketLevel <= 50 && packet.Type == PacketType.ImprovedTerseObjectUpdate)
|
if (DebugPacketLevel <= 50
|
||||||
|
& (packet.Type == PacketType.ImprovedTerseObjectUpdate || packet.Type == PacketType.ObjectUpdate))
|
||||||
logPacket = false;
|
logPacket = false;
|
||||||
|
|
||||||
if (DebugPacketLevel <= 25 && packet.Type == PacketType.ObjectPropertiesFamily)
|
if (DebugPacketLevel <= 25 && packet.Type == PacketType.ObjectPropertiesFamily)
|
||||||
|
@ -11796,7 +11891,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
{
|
{
|
||||||
ClientInfo info = m_udpClient.GetClientInfo();
|
ClientInfo info = m_udpClient.GetClientInfo();
|
||||||
|
|
||||||
info.userEP = m_userEndPoint;
|
|
||||||
info.proxyEP = null;
|
info.proxyEP = null;
|
||||||
info.agentcircuit = RequestClientInfo();
|
info.agentcircuit = RequestClientInfo();
|
||||||
|
|
||||||
|
@ -11808,11 +11902,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
m_udpClient.SetClientInfo(info);
|
m_udpClient.SetClientInfo(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
public EndPoint GetClientEP()
|
|
||||||
{
|
|
||||||
return m_userEndPoint;
|
|
||||||
}
|
|
||||||
|
|
||||||
#region Media Parcel Members
|
#region Media Parcel Members
|
||||||
|
|
||||||
public void SendParcelMediaCommand(uint flags, ParcelMediaCommandEnum command, float time)
|
public void SendParcelMediaCommand(uint flags, ParcelMediaCommandEnum command, float time)
|
||||||
|
@ -11893,10 +11982,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void KillEndDone()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
#region IClientCore
|
#region IClientCore
|
||||||
|
|
||||||
private readonly Dictionary<Type, object> m_clientInterfaces = new Dictionary<Type, object>();
|
private readonly Dictionary<Type, object> m_clientInterfaces = new Dictionary<Type, object>();
|
||||||
|
@ -11937,7 +12022,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
{
|
{
|
||||||
Kick(reason);
|
Kick(reason);
|
||||||
Thread.Sleep(1000);
|
Thread.Sleep(1000);
|
||||||
Close();
|
Disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Disconnect()
|
public void Disconnect()
|
||||||
|
@ -11984,21 +12069,24 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
protected void MakeAssetRequest(TransferRequestPacket transferRequest, UUID taskID)
|
protected void MakeAssetRequest(TransferRequestPacket transferRequest, UUID taskID)
|
||||||
{
|
{
|
||||||
UUID requestID = UUID.Zero;
|
UUID requestID = UUID.Zero;
|
||||||
if (transferRequest.TransferInfo.SourceType == (int)SourceType.Asset)
|
int sourceType = transferRequest.TransferInfo.SourceType;
|
||||||
|
|
||||||
|
if (sourceType == (int)SourceType.Asset)
|
||||||
{
|
{
|
||||||
requestID = new UUID(transferRequest.TransferInfo.Params, 0);
|
requestID = new UUID(transferRequest.TransferInfo.Params, 0);
|
||||||
}
|
}
|
||||||
else if (transferRequest.TransferInfo.SourceType == (int)SourceType.SimInventoryItem)
|
else if (sourceType == (int)SourceType.SimInventoryItem)
|
||||||
{
|
{
|
||||||
requestID = new UUID(transferRequest.TransferInfo.Params, 80);
|
requestID = new UUID(transferRequest.TransferInfo.Params, 80);
|
||||||
}
|
}
|
||||||
else if (transferRequest.TransferInfo.SourceType == (int)SourceType.SimEstate)
|
else if (sourceType == (int)SourceType.SimEstate)
|
||||||
{
|
{
|
||||||
requestID = taskID;
|
requestID = taskID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// m_log.DebugFormat(
|
||||||
// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID);
|
// "[LLCLIENTVIEW]: Received transfer request for {0} in {1} type {2} by {3}",
|
||||||
|
// requestID, taskID, (SourceType)sourceType, Name);
|
||||||
|
|
||||||
m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived);
|
m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived);
|
||||||
}
|
}
|
||||||
|
@ -12011,14 +12099,27 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
/// <param name="asset"></param>
|
/// <param name="asset"></param>
|
||||||
protected void AssetReceived(string id, Object sender, AssetBase asset)
|
protected void AssetReceived(string id, Object sender, AssetBase asset)
|
||||||
{
|
{
|
||||||
if (asset == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
TransferRequestPacket transferRequest = (TransferRequestPacket)sender;
|
TransferRequestPacket transferRequest = (TransferRequestPacket)sender;
|
||||||
|
|
||||||
UUID requestID = UUID.Zero;
|
UUID requestID = UUID.Zero;
|
||||||
byte source = (byte)SourceType.Asset;
|
byte source = (byte)SourceType.Asset;
|
||||||
|
|
||||||
|
AssetRequestToClient req = new AssetRequestToClient();
|
||||||
|
|
||||||
|
if (asset == null)
|
||||||
|
{
|
||||||
|
req.AssetInf = null;
|
||||||
|
req.AssetRequestSource = source;
|
||||||
|
req.IsTextureRequest = false;
|
||||||
|
req.NumPackets = 0;
|
||||||
|
req.Params = transferRequest.TransferInfo.Params;
|
||||||
|
req.RequestAssetID = requestID;
|
||||||
|
req.TransferRequestID = transferRequest.TransferInfo.TransferID;
|
||||||
|
|
||||||
|
SendAssetNotFound(req);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (transferRequest.TransferInfo.SourceType == (int)SourceType.Asset)
|
if (transferRequest.TransferInfo.SourceType == (int)SourceType.Asset)
|
||||||
{
|
{
|
||||||
requestID = new UUID(transferRequest.TransferInfo.Params, 0);
|
requestID = new UUID(transferRequest.TransferInfo.Params, 0);
|
||||||
|
@ -12035,7 +12136,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// The asset is known to exist and is in our cache, so add it to the AssetRequests list
|
// The asset is known to exist and is in our cache, so add it to the AssetRequests list
|
||||||
AssetRequestToClient req = new AssetRequestToClient();
|
|
||||||
req.AssetInf = asset;
|
req.AssetInf = asset;
|
||||||
req.AssetRequestSource = source;
|
req.AssetRequestSource = source;
|
||||||
req.IsTextureRequest = false;
|
req.IsTextureRequest = false;
|
||||||
|
@ -12071,24 +12171,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
return numPackets;
|
return numPackets;
|
||||||
}
|
}
|
||||||
|
|
||||||
#region IClientIPEndpoint Members
|
|
||||||
|
|
||||||
public IPAddress EndPoint
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (m_userEndPoint is IPEndPoint)
|
|
||||||
{
|
|
||||||
IPEndPoint ep = (IPEndPoint)m_userEndPoint;
|
|
||||||
|
|
||||||
return ep.Address;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
public void SendRebakeAvatarTextures(UUID textureID)
|
public void SendRebakeAvatarTextures(UUID textureID)
|
||||||
{
|
{
|
||||||
RebakeAvatarTexturesPacket pack =
|
RebakeAvatarTexturesPacket pack =
|
||||||
|
@ -12292,5 +12374,175 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
if (reply != null)
|
if (reply != null)
|
||||||
OutPacket(reply, ThrottleOutPacketType.Task);
|
OutPacket(reply, ThrottleOutPacketType.Task);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SendRemoveInventoryItems(UUID[] items)
|
||||||
|
{
|
||||||
|
IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>();
|
||||||
|
|
||||||
|
if (eq == null)
|
||||||
|
{
|
||||||
|
m_log.DebugFormat("[LLCLIENT]: Null event queue");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
OSDMap llsd = new OSDMap(3);
|
||||||
|
|
||||||
|
OSDMap AgentDataMap = new OSDMap(1);
|
||||||
|
AgentDataMap.Add("AgentID", OSD.FromUUID(AgentId));
|
||||||
|
AgentDataMap.Add("SessionID", OSD.FromUUID(SessionId));
|
||||||
|
|
||||||
|
OSDArray AgentData = new OSDArray(1);
|
||||||
|
AgentData.Add(AgentDataMap);
|
||||||
|
|
||||||
|
llsd.Add("AgentData", AgentData);
|
||||||
|
|
||||||
|
OSDArray ItemData = new OSDArray();
|
||||||
|
|
||||||
|
foreach (UUID item in items)
|
||||||
|
{
|
||||||
|
OSDMap ItemDataMap = new OSDMap(2);
|
||||||
|
ItemDataMap.Add("ItemID", OSD.FromUUID(item));
|
||||||
|
ItemDataMap.Add("AgentID", OSD.FromUUID(AgentId));
|
||||||
|
|
||||||
|
ItemData.Add(ItemDataMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
llsd.Add("InventoryData", ItemData);
|
||||||
|
|
||||||
|
eq.Enqueue(BuildEvent("RemoveInventoryItem",
|
||||||
|
llsd), AgentId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SendRemoveInventoryFolders(UUID[] folders)
|
||||||
|
{
|
||||||
|
IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>();
|
||||||
|
|
||||||
|
if (eq == null)
|
||||||
|
{
|
||||||
|
m_log.DebugFormat("[LLCLIENT]: Null event queue");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
OSDMap llsd = new OSDMap(3);
|
||||||
|
|
||||||
|
OSDMap AgentDataMap = new OSDMap(1);
|
||||||
|
AgentDataMap.Add("AgentID", OSD.FromUUID(AgentId));
|
||||||
|
AgentDataMap.Add("SessionID", OSD.FromUUID(SessionId));
|
||||||
|
|
||||||
|
OSDArray AgentData = new OSDArray(1);
|
||||||
|
AgentData.Add(AgentDataMap);
|
||||||
|
|
||||||
|
llsd.Add("AgentData", AgentData);
|
||||||
|
|
||||||
|
OSDArray FolderData = new OSDArray();
|
||||||
|
|
||||||
|
foreach (UUID folder in folders)
|
||||||
|
{
|
||||||
|
OSDMap FolderDataMap = new OSDMap(2);
|
||||||
|
FolderDataMap.Add("FolderID", OSD.FromUUID(folder));
|
||||||
|
FolderDataMap.Add("AgentID", OSD.FromUUID(AgentId));
|
||||||
|
|
||||||
|
FolderData.Add(FolderDataMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
llsd.Add("FolderData", FolderData);
|
||||||
|
|
||||||
|
eq.Enqueue(BuildEvent("RemoveInventoryFolder",
|
||||||
|
llsd), AgentId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] EncodeU32(uint val)
|
||||||
|
{
|
||||||
|
byte[] ret = BitConverter.GetBytes(val);
|
||||||
|
if (BitConverter.IsLittleEndian)
|
||||||
|
Array.Reverse(ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SendBulkUpdateInventory(InventoryFolderBase[] folders, InventoryItemBase[] items)
|
||||||
|
{
|
||||||
|
IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>();
|
||||||
|
|
||||||
|
if (eq == null)
|
||||||
|
{
|
||||||
|
m_log.DebugFormat("[LLCLIENT]: Null event queue");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
OSDMap llsd = new OSDMap(3);
|
||||||
|
|
||||||
|
OSDMap AgentDataMap = new OSDMap(1);
|
||||||
|
AgentDataMap.Add("AgentID", OSD.FromUUID(AgentId));
|
||||||
|
AgentDataMap.Add("SessionID", OSD.FromUUID(SessionId));
|
||||||
|
AgentDataMap.Add("TransactionID", OSD.FromUUID(UUID.Random()));
|
||||||
|
|
||||||
|
OSDArray AgentData = new OSDArray(1);
|
||||||
|
AgentData.Add(AgentDataMap);
|
||||||
|
|
||||||
|
llsd.Add("AgentData", AgentData);
|
||||||
|
|
||||||
|
OSDArray FolderData = new OSDArray();
|
||||||
|
|
||||||
|
foreach (InventoryFolderBase folder in folders)
|
||||||
|
{
|
||||||
|
OSDMap FolderDataMap = new OSDMap(5);
|
||||||
|
FolderDataMap.Add("FolderID", OSD.FromUUID(folder.ID));
|
||||||
|
FolderDataMap.Add("AgentID", OSD.FromUUID(AgentId));
|
||||||
|
FolderDataMap.Add("ParentID", OSD.FromUUID(folder.ParentID));
|
||||||
|
FolderDataMap.Add("Type", OSD.FromInteger(folder.Type));
|
||||||
|
FolderDataMap.Add("Name", OSD.FromString(folder.Name));
|
||||||
|
|
||||||
|
FolderData.Add(FolderDataMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
llsd.Add("FolderData", FolderData);
|
||||||
|
|
||||||
|
OSDArray ItemData = new OSDArray();
|
||||||
|
|
||||||
|
foreach (InventoryItemBase item in items)
|
||||||
|
{
|
||||||
|
OSDMap ItemDataMap = new OSDMap();
|
||||||
|
|
||||||
|
ItemDataMap.Add("ItemID", OSD.FromUUID(item.ID));
|
||||||
|
ItemDataMap.Add("FolderID", OSD.FromUUID(item.Folder));
|
||||||
|
|
||||||
|
ItemDataMap.Add("CreatorID", OSD.FromUUID(item.CreatorIdAsUuid));
|
||||||
|
ItemDataMap.Add("OwnerID", OSD.FromUUID(item.Owner));
|
||||||
|
ItemDataMap.Add("GroupID", OSD.FromUUID(item.GroupID));
|
||||||
|
ItemDataMap.Add("BaseMask", OSD.FromBinary(EncodeU32((uint)item.BasePermissions)));
|
||||||
|
ItemDataMap.Add("OwnerMask", OSD.FromBinary(EncodeU32((uint)item.CurrentPermissions)));
|
||||||
|
ItemDataMap.Add("GroupMask", OSD.FromBinary(EncodeU32((uint)item.GroupPermissions)));
|
||||||
|
ItemDataMap.Add("EveryoneMask", OSD.FromBinary(EncodeU32((uint)item.EveryOnePermissions)));
|
||||||
|
ItemDataMap.Add("NextOwnerMask", OSD.FromBinary(EncodeU32((uint)item.NextPermissions)));
|
||||||
|
ItemDataMap.Add("GroupOwned", OSD.FromBoolean(item.GroupOwned));
|
||||||
|
ItemDataMap.Add("AssetID", OSD.FromUUID(item.AssetID));
|
||||||
|
ItemDataMap.Add("Type", OSD.FromInteger(item.AssetType));
|
||||||
|
ItemDataMap.Add("InvType", OSD.FromInteger(item.InvType));
|
||||||
|
ItemDataMap.Add("Flags", OSD.FromBinary(EncodeU32((uint)item.Flags)));
|
||||||
|
ItemDataMap.Add("SaleType", OSD.FromInteger((byte)item.SaleType));
|
||||||
|
ItemDataMap.Add("SalePrice", OSD.FromInteger(item.SalePrice));
|
||||||
|
ItemDataMap.Add("Name", OSD.FromString(item.Name));
|
||||||
|
ItemDataMap.Add("Description", OSD.FromString(item.Description));
|
||||||
|
ItemDataMap.Add("CreationDate", OSD.FromInteger(item.CreationDate));
|
||||||
|
|
||||||
|
ItemDataMap.Add("CRC", OSD.FromBinary(EncodeU32(
|
||||||
|
Helpers.InventoryCRC(1000, 0, (sbyte)item.InvType,
|
||||||
|
(sbyte)item.AssetType, item.AssetID,
|
||||||
|
item.GroupID, 100,
|
||||||
|
item.Owner, item.CreatorIdAsUuid,
|
||||||
|
item.ID, item.Folder,
|
||||||
|
(uint)PermissionMask.All, 1, (uint)PermissionMask.All, (uint)PermissionMask.All,
|
||||||
|
(uint)PermissionMask.All)
|
||||||
|
)));
|
||||||
|
ItemDataMap.Add("CallbackID", 0);
|
||||||
|
|
||||||
|
ItemData.Add(ItemDataMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
llsd.Add("ItemData", ItemData);
|
||||||
|
|
||||||
|
eq.Enqueue(BuildEvent("BulkUpdateInventory",
|
||||||
|
llsd), AgentId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -278,7 +278,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
public string GetStats()
|
public string GetStats()
|
||||||
{
|
{
|
||||||
return string.Format(
|
return string.Format(
|
||||||
"{0,7} {1,7} {2,7} {3,9} {4,7} {5,7} {6,7} {7,7} {8,7} {9,8} {10,7} {11,7}",
|
"{0,7} {1,7} {2,7} {3,9} {4,7} {5,7} {6,7} {7,7} {8,7} {9,8} {10,7} {11,7} {12,7}",
|
||||||
|
Util.EnvironmentTickCountSubtract(TickLastPacketReceived),
|
||||||
PacketsReceived,
|
PacketsReceived,
|
||||||
PacketsSent,
|
PacketsSent,
|
||||||
PacketsResent,
|
PacketsResent,
|
||||||
|
|
|
@ -147,21 +147,34 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
private int m_elapsed500MSOutgoingPacketHandler;
|
private int m_elapsed500MSOutgoingPacketHandler;
|
||||||
|
|
||||||
/// <summary>Flag to signal when clients should check for resends</summary>
|
/// <summary>Flag to signal when clients should check for resends</summary>
|
||||||
private bool m_resendUnacked;
|
protected bool m_resendUnacked;
|
||||||
|
|
||||||
/// <summary>Flag to signal when clients should send ACKs</summary>
|
/// <summary>Flag to signal when clients should send ACKs</summary>
|
||||||
private bool m_sendAcks;
|
protected bool m_sendAcks;
|
||||||
|
|
||||||
/// <summary>Flag to signal when clients should send pings</summary>
|
/// <summary>Flag to signal when clients should send pings</summary>
|
||||||
private bool m_sendPing;
|
protected bool m_sendPing;
|
||||||
|
|
||||||
private int m_defaultRTO = 0;
|
private int m_defaultRTO = 0;
|
||||||
private int m_maxRTO = 0;
|
private int m_maxRTO = 0;
|
||||||
|
private int m_ackTimeout = 0;
|
||||||
|
private int m_pausedAckTimeout = 0;
|
||||||
private bool m_disableFacelights = false;
|
private bool m_disableFacelights = false;
|
||||||
|
|
||||||
public Socket Server { get { return null; } }
|
public Socket Server { get { return null; } }
|
||||||
|
|
||||||
private int m_malformedCount = 0; // Guard against a spamming attack
|
private int m_malformedCount = 0; // Guard against a spamming attack
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Record current outgoing client for monitoring purposes.
|
||||||
|
/// </summary>
|
||||||
|
private IClientAPI m_currentOutgoingClient;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Recording current incoming client for monitoring purposes.
|
||||||
|
/// </summary>
|
||||||
|
private IClientAPI m_currentIncomingClient;
|
||||||
|
|
||||||
public LLUDPServer(IPAddress listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port, IConfigSource configSource, AgentCircuitManager circuitManager)
|
public LLUDPServer(IPAddress listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port, IConfigSource configSource, AgentCircuitManager circuitManager)
|
||||||
: base(listenIP, (int)port)
|
: base(listenIP, (int)port)
|
||||||
{
|
{
|
||||||
|
@ -198,11 +211,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
m_defaultRTO = config.GetInt("DefaultRTO", 0);
|
m_defaultRTO = config.GetInt("DefaultRTO", 0);
|
||||||
m_maxRTO = config.GetInt("MaxRTO", 0);
|
m_maxRTO = config.GetInt("MaxRTO", 0);
|
||||||
m_disableFacelights = config.GetBoolean("DisableFacelights", false);
|
m_disableFacelights = config.GetBoolean("DisableFacelights", false);
|
||||||
|
m_ackTimeout = 1000 * config.GetInt("AckTimeout", 60);
|
||||||
|
m_pausedAckTimeout = 1000 * config.GetInt("PausedAckTimeout", 300);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PrimUpdatesPerCallback = 100;
|
PrimUpdatesPerCallback = 100;
|
||||||
TextureSendLimit = 20;
|
TextureSendLimit = 20;
|
||||||
|
m_ackTimeout = 1000 * 60; // 1 minute
|
||||||
|
m_pausedAckTimeout = 1000 * 300; // 5 minutes
|
||||||
}
|
}
|
||||||
|
|
||||||
#region BinaryStats
|
#region BinaryStats
|
||||||
|
@ -239,19 +256,56 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
if (m_scene == null)
|
if (m_scene == null)
|
||||||
throw new InvalidOperationException("[LLUDPSERVER]: Cannot LLUDPServer.Start() without an IScene reference");
|
throw new InvalidOperationException("[LLUDPSERVER]: Cannot LLUDPServer.Start() without an IScene reference");
|
||||||
|
|
||||||
m_log.Info("[LLUDPSERVER]: Starting the LLUDP server in " + (m_asyncPacketHandling ? "asynchronous" : "synchronous") + " mode");
|
m_log.InfoFormat(
|
||||||
|
"[LLUDPSERVER]: Starting the LLUDP server in {0} mode",
|
||||||
|
m_asyncPacketHandling ? "asynchronous" : "synchronous");
|
||||||
|
|
||||||
base.Start(m_recvBufferSize, m_asyncPacketHandling);
|
base.Start(m_recvBufferSize, m_asyncPacketHandling);
|
||||||
|
|
||||||
// Start the packet processing threads
|
// Start the packet processing threads
|
||||||
Watchdog.StartThread(
|
Watchdog.StartThread(
|
||||||
IncomingPacketHandler, "Incoming Packets (" + m_scene.RegionInfo.RegionName + ")", ThreadPriority.Normal, false, true);
|
IncomingPacketHandler,
|
||||||
|
string.Format("Incoming Packets ({0})", m_scene.RegionInfo.RegionName),
|
||||||
|
ThreadPriority.Normal,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
GetWatchdogIncomingAlarmData,
|
||||||
|
Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS);
|
||||||
|
|
||||||
Watchdog.StartThread(
|
Watchdog.StartThread(
|
||||||
OutgoingPacketHandler, "Outgoing Packets (" + m_scene.RegionInfo.RegionName + ")", ThreadPriority.Normal, false, true);
|
OutgoingPacketHandler,
|
||||||
|
string.Format("Outgoing Packets ({0})", m_scene.RegionInfo.RegionName),
|
||||||
|
ThreadPriority.Normal,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
GetWatchdogOutgoingAlarmData,
|
||||||
|
Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS);
|
||||||
|
|
||||||
m_elapsedMSSinceLastStatReport = Environment.TickCount;
|
m_elapsedMSSinceLastStatReport = Environment.TickCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If the outgoing UDP thread times out, then return client that was being processed to help with debugging.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
private string GetWatchdogIncomingAlarmData()
|
||||||
|
{
|
||||||
|
return string.Format(
|
||||||
|
"Client is {0}",
|
||||||
|
m_currentIncomingClient != null ? m_currentIncomingClient.Name : "none");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If the outgoing UDP thread times out, then return client that was being processed to help with debugging.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
private string GetWatchdogOutgoingAlarmData()
|
||||||
|
{
|
||||||
|
return string.Format(
|
||||||
|
"Client is {0}",
|
||||||
|
m_currentOutgoingClient != null ? m_currentOutgoingClient.Name : "none");
|
||||||
|
}
|
||||||
|
|
||||||
public new void Stop()
|
public new void Stop()
|
||||||
{
|
{
|
||||||
m_log.Info("[LLUDPSERVER]: Shutting down the LLUDP server for " + m_scene.RegionInfo.RegionName);
|
m_log.Info("[LLUDPSERVER]: Shutting down the LLUDP server for " + m_scene.RegionInfo.RegionName);
|
||||||
|
@ -485,19 +539,34 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
SendPacket(udpClient, completePing, ThrottleOutPacketType.Unknown, false, null);
|
SendPacket(udpClient, completePing, ThrottleOutPacketType.Unknown, false, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void HandleUnacked(LLUDPClient udpClient)
|
public void HandleUnacked(LLClientView client)
|
||||||
{
|
{
|
||||||
|
LLUDPClient udpClient = client.UDPClient;
|
||||||
|
|
||||||
if (!udpClient.IsConnected)
|
if (!udpClient.IsConnected)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Disconnect an agent if no packets are received for some time
|
// Disconnect an agent if no packets are received for some time
|
||||||
//FIXME: Make 60 an .ini setting
|
int timeoutTicks = m_ackTimeout;
|
||||||
if ((Environment.TickCount & Int32.MaxValue) - udpClient.TickLastPacketReceived > 1000 * 60)
|
|
||||||
{
|
// Allow more slack if the client is "paused" eg file upload dialogue is open
|
||||||
m_log.Warn("[LLUDPSERVER]: Ack timeout, disconnecting " + udpClient.AgentID);
|
// Some sort of limit is needed in case the client crashes, loses its network connection
|
||||||
StatsManager.SimExtraStats.AddAbnormalClientThreadTermination();
|
// or some other disaster prevents it from sendung the AgentResume
|
||||||
|
if (udpClient.IsPaused)
|
||||||
|
timeoutTicks = m_pausedAckTimeout;
|
||||||
|
|
||||||
|
if (client.IsActive &&
|
||||||
|
(Environment.TickCount & Int32.MaxValue) - udpClient.TickLastPacketReceived > timeoutTicks)
|
||||||
|
{
|
||||||
|
// We must set IsActive synchronously so that we can stop the packet loop reinvoking this method, even
|
||||||
|
// though it's set later on by LLClientView.Close()
|
||||||
|
client.IsActive = false;
|
||||||
|
|
||||||
|
// Fire this out on a different thread so that we don't hold up outgoing packet processing for
|
||||||
|
// everybody else if this is being called due to an ack timeout.
|
||||||
|
// This is the same as processing as the async process of a logout request.
|
||||||
|
Util.FireAndForget(o => DeactivateClientDueToTimeout(client));
|
||||||
|
|
||||||
RemoveClient(udpClient);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -820,7 +889,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
#endregion Ping Check Handling
|
#endregion Ping Check Handling
|
||||||
|
|
||||||
// Inbox insertion
|
// Inbox insertion
|
||||||
packetInbox.Enqueue(new IncomingPacket(udpClient, packet));
|
packetInbox.Enqueue(new IncomingPacket((LLClientView)client, packet));
|
||||||
}
|
}
|
||||||
|
|
||||||
#region BinaryStats
|
#region BinaryStats
|
||||||
|
@ -916,7 +985,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
UDPPacketBuffer buffer = (UDPPacketBuffer)array[0];
|
UDPPacketBuffer buffer = (UDPPacketBuffer)array[0];
|
||||||
UseCircuitCodePacket uccp = (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 for circuit {0} to {1} from IP {2}",
|
||||||
|
uccp.CircuitCode.Code, m_scene.RegionInfo.RegionName, buffer.RemoteEndPoint);
|
||||||
|
|
||||||
remoteEndPoint = (IPEndPoint)buffer.RemoteEndPoint;
|
remoteEndPoint = (IPEndPoint)buffer.RemoteEndPoint;
|
||||||
|
|
||||||
|
@ -945,8 +1016,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
{
|
{
|
||||||
// Don't create clients for unauthorized requesters.
|
// Don't create clients for unauthorized requesters.
|
||||||
m_log.WarnFormat(
|
m_log.WarnFormat(
|
||||||
"[LLUDPSERVER]: Connection request for client {0} connecting with unnotified circuit code {1} from {2}",
|
"[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}",
|
||||||
uccp.CircuitCode.ID, uccp.CircuitCode.Code, remoteEndPoint);
|
uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, remoteEndPoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
// m_log.DebugFormat(
|
// m_log.DebugFormat(
|
||||||
|
@ -1023,16 +1094,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
{
|
{
|
||||||
IClientAPI client = null;
|
IClientAPI client = null;
|
||||||
|
|
||||||
// In priciple there shouldn't be more than one thread here, ever.
|
// We currently synchronize this code across the whole scene to avoid issues such as
|
||||||
// But in case that happens, we need to synchronize this piece of code
|
// http://opensimulator.org/mantis/view.php?id=5365 However, once locking per agent circuit can be done
|
||||||
// because it's too important
|
// consistently, this lock could probably be removed.
|
||||||
lock (this)
|
lock (this)
|
||||||
{
|
{
|
||||||
if (!m_scene.TryGetClient(agentID, out client))
|
if (!m_scene.TryGetClient(agentID, out client))
|
||||||
{
|
{
|
||||||
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);
|
||||||
|
|
||||||
client = new LLClientView(remoteEndPoint, m_scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode);
|
client = new LLClientView(m_scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode);
|
||||||
client.OnLogout += LogoutHandler;
|
client.OnLogout += LogoutHandler;
|
||||||
|
|
||||||
((LLClientView)client).DisableFacelights = m_disableFacelights;
|
((LLClientView)client).DisableFacelights = m_disableFacelights;
|
||||||
|
@ -1044,14 +1115,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RemoveClient(LLUDPClient udpClient)
|
/// <summary>
|
||||||
|
/// Deactivates the client if we don't receive any packets within a certain amount of time (default 60 seconds).
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// If a connection is active then we will always receive packets even if nothing else is happening, due to
|
||||||
|
/// regular client pings.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name='client'></param>
|
||||||
|
private void DeactivateClientDueToTimeout(LLClientView client)
|
||||||
{
|
{
|
||||||
// Remove this client from the scene
|
lock (client.CloseSyncLock)
|
||||||
IClientAPI client;
|
|
||||||
if (m_scene.TryGetClient(udpClient.AgentID, out client))
|
|
||||||
{
|
{
|
||||||
client.IsLoggingOut = true;
|
m_log.WarnFormat(
|
||||||
client.Close();
|
"[LLUDPSERVER]: Ack timeout, disconnecting {0} agent for {1} in {2}",
|
||||||
|
client.SceneAgent.IsChildAgent ? "child" : "root", client.Name, m_scene.RegionInfo.RegionName);
|
||||||
|
|
||||||
|
StatsManager.SimExtraStats.AddAbnormalClientThreadTermination();
|
||||||
|
|
||||||
|
if (!client.SceneAgent.IsChildAgent)
|
||||||
|
client.Kick("Simulator logged you out due to connection timeout");
|
||||||
|
|
||||||
|
client.CloseWithoutChecks();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1159,6 +1244,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
// client. m_packetSent will be set to true if a packet is sent
|
// client. m_packetSent will be set to true if a packet is sent
|
||||||
m_scene.ForEachClient(clientPacketHandler);
|
m_scene.ForEachClient(clientPacketHandler);
|
||||||
|
|
||||||
|
m_currentOutgoingClient = null;
|
||||||
|
|
||||||
// If nothing was sent, sleep for the minimum amount of time before a
|
// If nothing was sent, sleep for the minimum amount of time before a
|
||||||
// token bucket could get more tokens
|
// token bucket could get more tokens
|
||||||
if (!m_packetSent)
|
if (!m_packetSent)
|
||||||
|
@ -1175,18 +1262,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
Watchdog.RemoveThread();
|
Watchdog.RemoveThread();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ClientOutgoingPacketHandler(IClientAPI client)
|
protected void ClientOutgoingPacketHandler(IClientAPI client)
|
||||||
{
|
{
|
||||||
|
m_currentOutgoingClient = client;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (client is LLClientView)
|
if (client is LLClientView)
|
||||||
{
|
{
|
||||||
LLUDPClient udpClient = ((LLClientView)client).UDPClient;
|
LLClientView llClient = (LLClientView)client;
|
||||||
|
LLUDPClient udpClient = llClient.UDPClient;
|
||||||
|
|
||||||
if (udpClient.IsConnected)
|
if (udpClient.IsConnected)
|
||||||
{
|
{
|
||||||
if (m_resendUnacked)
|
if (m_resendUnacked)
|
||||||
HandleUnacked(udpClient);
|
HandleUnacked(llClient);
|
||||||
|
|
||||||
if (m_sendAcks)
|
if (m_sendAcks)
|
||||||
SendAcks(udpClient);
|
SendAcks(udpClient);
|
||||||
|
@ -1202,8 +1292,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
m_log.Error("[LLUDPSERVER]: OutgoingPacketHandler iteration for " + client.Name +
|
m_log.Error(
|
||||||
" threw an exception: " + ex.Message, ex);
|
string.Format("[LLUDPSERVER]: OutgoingPacketHandler iteration for {0} threw ", client.Name), ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1229,11 +1319,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
{
|
{
|
||||||
nticks++;
|
nticks++;
|
||||||
watch1.Start();
|
watch1.Start();
|
||||||
|
m_currentOutgoingClient = client;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (client is LLClientView)
|
if (client is LLClientView)
|
||||||
{
|
{
|
||||||
LLUDPClient udpClient = ((LLClientView)client).UDPClient;
|
LLClientView llClient = (LLClientView)client;
|
||||||
|
LLUDPClient udpClient = llClient.UDPClient;
|
||||||
|
|
||||||
if (udpClient.IsConnected)
|
if (udpClient.IsConnected)
|
||||||
{
|
{
|
||||||
|
@ -1242,7 +1335,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
nticksUnack++;
|
nticksUnack++;
|
||||||
watch2.Start();
|
watch2.Start();
|
||||||
|
|
||||||
HandleUnacked(udpClient);
|
HandleUnacked(llClient);
|
||||||
|
|
||||||
watch2.Stop();
|
watch2.Stop();
|
||||||
avgResendUnackedTicks = (nticksUnack - 1)/(float)nticksUnack * avgResendUnackedTicks + (watch2.ElapsedTicks / (float)nticksUnack);
|
avgResendUnackedTicks = (nticksUnack - 1)/(float)nticksUnack * avgResendUnackedTicks + (watch2.ElapsedTicks / (float)nticksUnack);
|
||||||
|
@ -1313,23 +1406,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
private void ProcessInPacket(object state)
|
private void ProcessInPacket(IncomingPacket incomingPacket)
|
||||||
{
|
{
|
||||||
IncomingPacket incomingPacket = (IncomingPacket)state;
|
|
||||||
Packet packet = incomingPacket.Packet;
|
Packet packet = incomingPacket.Packet;
|
||||||
LLUDPClient udpClient = incomingPacket.Client;
|
LLClientView client = incomingPacket.Client;
|
||||||
IClientAPI client;
|
|
||||||
|
|
||||||
// Sanity check
|
if (client.IsActive)
|
||||||
if (packet == null || udpClient == null)
|
|
||||||
{
|
{
|
||||||
m_log.WarnFormat("[LLUDPSERVER]: Processing a packet with incomplete state. Packet=\"{0}\", UDPClient=\"{1}\"",
|
m_currentIncomingClient = client;
|
||||||
packet, udpClient);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure this client is still alive
|
|
||||||
if (m_scene.TryGetClient(udpClient.AgentID, out client))
|
|
||||||
{
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Process this packet
|
// Process this packet
|
||||||
|
@ -1344,21 +1429,34 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
// Don't let a failure in an individual client thread crash the whole sim.
|
// Don't let a failure in an individual client thread crash the whole sim.
|
||||||
m_log.ErrorFormat("[LLUDPSERVER]: Client packet handler for {0} for packet {1} threw an exception", udpClient.AgentID, packet.Type);
|
m_log.Error(
|
||||||
m_log.Error(e.Message, e);
|
string.Format(
|
||||||
|
"[LLUDPSERVER]: Client packet handler for {0} for packet {1} threw ",
|
||||||
|
client.Name, packet.Type),
|
||||||
|
e);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
m_currentIncomingClient = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_log.DebugFormat("[LLUDPSERVER]: Dropping incoming {0} packet for dead client {1}", packet.Type, udpClient.AgentID);
|
m_log.DebugFormat(
|
||||||
|
"[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}",
|
||||||
|
packet.Type, client.Name, m_scene.RegionInfo.RegionName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void LogoutHandler(IClientAPI client)
|
protected void LogoutHandler(IClientAPI client)
|
||||||
{
|
{
|
||||||
client.SendLogoutPacket();
|
client.SendLogoutPacket();
|
||||||
if (client.IsActive)
|
|
||||||
RemoveClient(((LLClientView)client).UDPClient);
|
if (!client.IsLoggingOut)
|
||||||
|
{
|
||||||
|
client.IsLoggingOut = true;
|
||||||
|
client.Close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -45,6 +45,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class BasicCircuitTests
|
public class BasicCircuitTests
|
||||||
{
|
{
|
||||||
|
private Scene m_scene;
|
||||||
|
private TestLLUDPServer m_udpServer;
|
||||||
|
|
||||||
[TestFixtureSetUp]
|
[TestFixtureSetUp]
|
||||||
public void FixtureInit()
|
public void FixtureInit()
|
||||||
{
|
{
|
||||||
|
@ -61,83 +64,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
|
||||||
Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod;
|
Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod;
|
||||||
}
|
}
|
||||||
|
|
||||||
// /// <summary>
|
[SetUp]
|
||||||
// /// Add a client for testing
|
public void SetUp()
|
||||||
// /// </summary>
|
{
|
||||||
// /// <param name="scene"></param>
|
m_scene = new SceneHelpers().SetupScene();
|
||||||
// /// <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();
|
|
||||||
// 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;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /// <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>
|
|
||||||
// /// Set up a client for tests which aren't concerned with this process itself
|
|
||||||
// /// </summary>
|
|
||||||
// /// <param name="circuitCode"></param>
|
|
||||||
// /// <param name="epSender"></param>
|
|
||||||
// /// <param name="agentId"></param>
|
|
||||||
// /// <param name="sessionId"></param>
|
|
||||||
// /// <param name="testLLUDPServer"></param>
|
|
||||||
// /// <param name="acm"></param>
|
|
||||||
// protected void AddClient(
|
|
||||||
// uint circuitCode, EndPoint epSender, UUID agentId, UUID sessionId,
|
|
||||||
// TestLLUDPServer testLLUDPServer, AgentCircuitManager acm)
|
|
||||||
// {
|
|
||||||
// AgentCircuitData acd = new AgentCircuitData();
|
|
||||||
// acd.AgentID = agentId;
|
|
||||||
// acd.SessionID = sessionId;
|
|
||||||
//
|
|
||||||
// UseCircuitCodePacket uccp = new UseCircuitCodePacket();
|
|
||||||
//
|
|
||||||
// UseCircuitCodePacket.CircuitCodeBlock uccpCcBlock
|
|
||||||
// = new UseCircuitCodePacket.CircuitCodeBlock();
|
|
||||||
// uccpCcBlock.Code = circuitCode;
|
|
||||||
// uccpCcBlock.ID = agentId;
|
|
||||||
// uccpCcBlock.SessionID = sessionId;
|
|
||||||
// uccp.CircuitCode = uccpCcBlock;
|
|
||||||
//
|
|
||||||
// acm.AddNewCircuit(circuitCode, acd);
|
|
||||||
//
|
|
||||||
// testLLUDPServer.LoadReceive(uccp, epSender);
|
|
||||||
// testLLUDPServer.ReceiveData(null);
|
|
||||||
// }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Build an object name packet for test purposes
|
/// Build an object name packet for test purposes
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="objectLocalId"></param>
|
/// <param name="objectLocalId"></param>
|
||||||
/// <param name="objectName"></param>
|
/// <param name="objectName"></param>
|
||||||
protected ObjectNamePacket BuildTestObjectNamePacket(uint objectLocalId, string objectName)
|
private ObjectNamePacket BuildTestObjectNamePacket(uint objectLocalId, string objectName)
|
||||||
{
|
{
|
||||||
ObjectNamePacket onp = new ObjectNamePacket();
|
ObjectNamePacket onp = new ObjectNamePacket();
|
||||||
ObjectNamePacket.ObjectDataBlock odb = new ObjectNamePacket.ObjectDataBlock();
|
ObjectNamePacket.ObjectDataBlock odb = new ObjectNamePacket.ObjectDataBlock();
|
||||||
|
@ -149,28 +87,30 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
|
||||||
return onp;
|
return onp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
private void AddUdpServer()
|
||||||
/// Test adding a client to the stack
|
|
||||||
/// </summary>
|
|
||||||
[Test]
|
|
||||||
public void TestAddClient()
|
|
||||||
{
|
{
|
||||||
TestHelpers.InMethod();
|
AddUdpServer(new IniConfigSource());
|
||||||
// XmlConfigurator.Configure();
|
}
|
||||||
|
|
||||||
TestScene scene = SceneHelpers.SetupScene();
|
private void AddUdpServer(IniConfigSource configSource)
|
||||||
uint myCircuitCode = 123456;
|
{
|
||||||
|
uint port = 0;
|
||||||
|
AgentCircuitManager acm = m_scene.AuthenticateHandler;
|
||||||
|
|
||||||
|
m_udpServer = new TestLLUDPServer(IPAddress.Any, ref port, 0, false, configSource, acm);
|
||||||
|
m_udpServer.AddScene(m_scene);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Used by tests that aren't testing this stage.
|
||||||
|
/// </summary>
|
||||||
|
private ScenePresence AddClient()
|
||||||
|
{
|
||||||
UUID myAgentUuid = TestHelpers.ParseTail(0x1);
|
UUID myAgentUuid = TestHelpers.ParseTail(0x1);
|
||||||
UUID mySessionUuid = TestHelpers.ParseTail(0x2);
|
UUID mySessionUuid = TestHelpers.ParseTail(0x2);
|
||||||
|
uint myCircuitCode = 123456;
|
||||||
IPEndPoint testEp = new IPEndPoint(IPAddress.Loopback, 999);
|
IPEndPoint testEp = new IPEndPoint(IPAddress.Loopback, 999);
|
||||||
|
|
||||||
uint port = 0;
|
|
||||||
AgentCircuitManager acm = scene.AuthenticateHandler;
|
|
||||||
|
|
||||||
TestLLUDPServer llUdpServer
|
|
||||||
= new TestLLUDPServer(IPAddress.Any, ref port, 0, false, new IniConfigSource(), acm);
|
|
||||||
llUdpServer.AddScene(scene);
|
|
||||||
|
|
||||||
UseCircuitCodePacket uccp = new UseCircuitCodePacket();
|
UseCircuitCodePacket uccp = new UseCircuitCodePacket();
|
||||||
|
|
||||||
UseCircuitCodePacket.CircuitCodeBlock uccpCcBlock
|
UseCircuitCodePacket.CircuitCodeBlock uccpCcBlock
|
||||||
|
@ -185,26 +125,67 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
|
||||||
upb.DataLength = uccpBytes.Length; // God knows why this isn't set by the constructor.
|
upb.DataLength = uccpBytes.Length; // God knows why this isn't set by the constructor.
|
||||||
Buffer.BlockCopy(uccpBytes, 0, upb.Data, 0, uccpBytes.Length);
|
Buffer.BlockCopy(uccpBytes, 0, upb.Data, 0, uccpBytes.Length);
|
||||||
|
|
||||||
llUdpServer.PacketReceived(upb);
|
AgentCircuitData acd = new AgentCircuitData();
|
||||||
|
acd.AgentID = myAgentUuid;
|
||||||
|
acd.SessionID = mySessionUuid;
|
||||||
|
|
||||||
|
m_scene.AuthenticateHandler.AddNewCircuit(myCircuitCode, acd);
|
||||||
|
|
||||||
|
m_udpServer.PacketReceived(upb);
|
||||||
|
|
||||||
|
return m_scene.GetScenePresence(myAgentUuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Test adding a client to the stack
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestAddClient()
|
||||||
|
{
|
||||||
|
TestHelpers.InMethod();
|
||||||
|
// XmlConfigurator.Configure();
|
||||||
|
|
||||||
|
AddUdpServer();
|
||||||
|
|
||||||
|
UUID myAgentUuid = TestHelpers.ParseTail(0x1);
|
||||||
|
UUID mySessionUuid = TestHelpers.ParseTail(0x2);
|
||||||
|
uint myCircuitCode = 123456;
|
||||||
|
IPEndPoint testEp = new IPEndPoint(IPAddress.Loopback, 999);
|
||||||
|
|
||||||
|
UseCircuitCodePacket uccp = new UseCircuitCodePacket();
|
||||||
|
|
||||||
|
UseCircuitCodePacket.CircuitCodeBlock uccpCcBlock
|
||||||
|
= new UseCircuitCodePacket.CircuitCodeBlock();
|
||||||
|
uccpCcBlock.Code = myCircuitCode;
|
||||||
|
uccpCcBlock.ID = myAgentUuid;
|
||||||
|
uccpCcBlock.SessionID = mySessionUuid;
|
||||||
|
uccp.CircuitCode = uccpCcBlock;
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
m_udpServer.PacketReceived(upb);
|
||||||
|
|
||||||
// Presence shouldn'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.That(scene.GetScenePresence(myAgentUuid), Is.Null);
|
Assert.That(m_scene.GetScenePresence(myAgentUuid), Is.Null);
|
||||||
|
|
||||||
AgentCircuitData acd = new AgentCircuitData();
|
AgentCircuitData acd = new AgentCircuitData();
|
||||||
acd.AgentID = myAgentUuid;
|
acd.AgentID = myAgentUuid;
|
||||||
acd.SessionID = mySessionUuid;
|
acd.SessionID = mySessionUuid;
|
||||||
|
|
||||||
acm.AddNewCircuit(myCircuitCode, acd);
|
m_scene.AuthenticateHandler.AddNewCircuit(myCircuitCode, acd);
|
||||||
|
|
||||||
llUdpServer.PacketReceived(upb);
|
m_udpServer.PacketReceived(upb);
|
||||||
|
|
||||||
// Should succeed now
|
// Should succeed now
|
||||||
ScenePresence sp = scene.GetScenePresence(myAgentUuid);
|
ScenePresence sp = m_scene.GetScenePresence(myAgentUuid);
|
||||||
Assert.That(sp.UUID, Is.EqualTo(myAgentUuid));
|
Assert.That(sp.UUID, Is.EqualTo(myAgentUuid));
|
||||||
|
|
||||||
Assert.That(llUdpServer.PacketsSent.Count, Is.EqualTo(1));
|
Assert.That(m_udpServer.PacketsSent.Count, Is.EqualTo(1));
|
||||||
|
|
||||||
Packet packet = llUdpServer.PacketsSent[0];
|
Packet packet = m_udpServer.PacketsSent[0];
|
||||||
Assert.That(packet, Is.InstanceOf(typeof(PacketAckPacket)));
|
Assert.That(packet, Is.InstanceOf(typeof(PacketAckPacket)));
|
||||||
|
|
||||||
PacketAckPacket ackPacket = packet as PacketAckPacket;
|
PacketAckPacket ackPacket = packet as PacketAckPacket;
|
||||||
|
@ -212,6 +193,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
|
||||||
Assert.That(ackPacket.Packets[0].ID, Is.EqualTo(0));
|
Assert.That(ackPacket.Packets[0].ID, Is.EqualTo(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestLogoutClientDueToAck()
|
||||||
|
{
|
||||||
|
TestHelpers.InMethod();
|
||||||
|
// TestHelpers.EnableLogging();
|
||||||
|
|
||||||
|
IniConfigSource ics = new IniConfigSource();
|
||||||
|
IConfig config = ics.AddConfig("ClientStack.LindenUDP");
|
||||||
|
config.Set("AckTimeout", -1);
|
||||||
|
AddUdpServer(ics);
|
||||||
|
|
||||||
|
ScenePresence sp = AddClient();
|
||||||
|
m_udpServer.ClientOutgoingPacketHandler(sp.ControllingClient, true, false, false);
|
||||||
|
|
||||||
|
ScenePresence spAfterAckTimeout = m_scene.GetScenePresence(sp.UUID);
|
||||||
|
Assert.That(spAfterAckTimeout, Is.Null);
|
||||||
|
|
||||||
|
// TestHelpers.DisableLogging();
|
||||||
|
}
|
||||||
|
|
||||||
// /// <summary>
|
// /// <summary>
|
||||||
// /// Test removing a client from the stack
|
// /// Test removing a client from the stack
|
||||||
// /// </summary>
|
// /// </summary>
|
||||||
|
|
|
@ -79,7 +79,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
|
||||||
|
|
||||||
J2KDecoderModule j2kdm = new J2KDecoderModule();
|
J2KDecoderModule j2kdm = new J2KDecoderModule();
|
||||||
|
|
||||||
scene = SceneHelpers.SetupScene();
|
SceneHelpers sceneHelpers = new SceneHelpers();
|
||||||
|
scene = sceneHelpers.SetupScene();
|
||||||
SceneHelpers.SetupSceneModules(scene, j2kdm);
|
SceneHelpers.SetupSceneModules(scene, j2kdm);
|
||||||
|
|
||||||
tc = new TestClient(SceneHelpers.GenerateAgentData(userId), scene);
|
tc = new TestClient(SceneHelpers.GenerateAgentData(userId), scene);
|
||||||
|
|
|
@ -44,13 +44,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
|
||||||
}
|
}
|
||||||
protected int m_objectNameCallsReceived;
|
protected int m_objectNameCallsReceived;
|
||||||
|
|
||||||
public MockScene()
|
public MockScene() : base(new RegionInfo(1000, 1000, null, null))
|
||||||
{
|
{
|
||||||
m_regInfo = new RegionInfo(1000, 1000, null, null);
|
|
||||||
m_regStatus = RegionStatus.Up;
|
m_regStatus = RegionStatus.Up;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Update() {}
|
public override void Update(int frames) {}
|
||||||
public override void LoadWorldMap() {}
|
public override void LoadWorldMap() {}
|
||||||
|
|
||||||
public override ISceneAgent AddNewClient(IClientAPI client, PresenceType type)
|
public override ISceneAgent AddNewClient(IClientAPI client, PresenceType type)
|
||||||
|
|
|
@ -59,6 +59,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
|
||||||
PacketsSent.Add(packet);
|
PacketsSent.Add(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ClientOutgoingPacketHandler(IClientAPI client, bool resendUnacked, bool sendAcks, bool sendPing)
|
||||||
|
{
|
||||||
|
m_resendUnacked = resendUnacked;
|
||||||
|
m_sendAcks = sendAcks;
|
||||||
|
m_sendPing = sendPing;
|
||||||
|
|
||||||
|
ClientOutgoingPacketHandler(client);
|
||||||
|
}
|
||||||
|
|
||||||
//// /// <summary>
|
//// /// <summary>
|
||||||
//// /// The chunks of data to pass to the LLUDPServer when it calls EndReceive
|
//// /// The chunks of data to pass to the LLUDPServer when it calls EndReceive
|
||||||
//// /// </summary>
|
//// /// </summary>
|
||||||
|
|
|
@ -53,9 +53,8 @@ namespace OpenSim.Region.ClientStack
|
||||||
protected ISimulationDataService m_simulationDataService;
|
protected ISimulationDataService m_simulationDataService;
|
||||||
protected IEstateDataService m_estateDataService;
|
protected IEstateDataService m_estateDataService;
|
||||||
protected ClientStackManager m_clientStackManager;
|
protected ClientStackManager m_clientStackManager;
|
||||||
protected SceneManager m_sceneManager = new SceneManager();
|
|
||||||
|
|
||||||
public SceneManager SceneManager { get { return m_sceneManager; } }
|
public SceneManager SceneManager { get; protected set; }
|
||||||
public NetworkServersInfo NetServersInfo { get { return m_networkServersInfo; } }
|
public NetworkServersInfo NetServersInfo { get { return m_networkServersInfo; } }
|
||||||
public ISimulationDataService SimulationDataService { get { return m_simulationDataService; } }
|
public ISimulationDataService SimulationDataService { get { return m_simulationDataService; } }
|
||||||
public IEstateDataService EstateDataService { get { return m_estateDataService; } }
|
public IEstateDataService EstateDataService { get { return m_estateDataService; } }
|
||||||
|
@ -77,6 +76,7 @@ namespace OpenSim.Region.ClientStack
|
||||||
|
|
||||||
protected override void StartupSpecific()
|
protected override void StartupSpecific()
|
||||||
{
|
{
|
||||||
|
SceneManager = new SceneManager();
|
||||||
m_clientStackManager = CreateClientStackManager();
|
m_clientStackManager = CreateClientStackManager();
|
||||||
|
|
||||||
Initialize();
|
Initialize();
|
||||||
|
@ -94,23 +94,20 @@ namespace OpenSim.Region.ClientStack
|
||||||
m_log.InfoFormat("[REGION SERVER]: Starting HTTP server on port {0}", m_httpServerPort);
|
m_log.InfoFormat("[REGION SERVER]: Starting HTTP server on port {0}", m_httpServerPort);
|
||||||
m_httpServer.Start();
|
m_httpServer.Start();
|
||||||
|
|
||||||
|
MainServer.AddHttpServer(m_httpServer);
|
||||||
MainServer.Instance = m_httpServer;
|
MainServer.Instance = m_httpServer;
|
||||||
|
|
||||||
// "OOB" Server
|
// "OOB" Server
|
||||||
if (m_networkServersInfo.ssl_listener)
|
if (m_networkServersInfo.ssl_listener)
|
||||||
{
|
{
|
||||||
BaseHttpServer server = null;
|
BaseHttpServer server = new BaseHttpServer(
|
||||||
server = new BaseHttpServer(
|
|
||||||
m_networkServersInfo.https_port, m_networkServersInfo.ssl_listener, m_networkServersInfo.cert_path,
|
m_networkServersInfo.https_port, m_networkServersInfo.ssl_listener, m_networkServersInfo.cert_path,
|
||||||
m_networkServersInfo.cert_pass);
|
m_networkServersInfo.cert_pass);
|
||||||
// Add the server to m_Servers
|
|
||||||
if(server != null)
|
|
||||||
{
|
|
||||||
m_log.InfoFormat("[REGION SERVER]: Starting HTTPS server on port {0}", server.Port);
|
m_log.InfoFormat("[REGION SERVER]: Starting HTTPS server on port {0}", server.Port);
|
||||||
MainServer.AddHttpServer(server);
|
MainServer.AddHttpServer(server);
|
||||||
server.Start();
|
server.Start();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
base.StartupSpecific();
|
base.StartupSpecific();
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,8 +42,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
||||||
public class AssetTransactionModule : INonSharedRegionModule,
|
public class AssetTransactionModule : INonSharedRegionModule,
|
||||||
IAgentAssetTransactions
|
IAgentAssetTransactions
|
||||||
{
|
{
|
||||||
// private static readonly ILog m_log = LogManager.GetLogger(
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
// MethodBase.GetCurrentMethod().DeclaringType);
|
|
||||||
|
|
||||||
protected Scene m_Scene;
|
protected Scene m_Scene;
|
||||||
private bool m_dumpAssetsToFile = false;
|
private bool m_dumpAssetsToFile = false;
|
||||||
|
@ -203,15 +202,15 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
||||||
/// and comes through this method.
|
/// and comes through this method.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="remoteClient"></param>
|
/// <param name="remoteClient"></param>
|
||||||
|
/// <param name="part"></param>
|
||||||
/// <param name="transactionID"></param>
|
/// <param name="transactionID"></param>
|
||||||
/// <param name="item"></param>
|
/// <param name="item"></param>
|
||||||
public void HandleTaskItemUpdateFromTransaction(IClientAPI remoteClient,
|
public void HandleTaskItemUpdateFromTransaction(
|
||||||
SceneObjectPart part, UUID transactionID,
|
IClientAPI remoteClient, SceneObjectPart part, UUID transactionID, TaskInventoryItem item)
|
||||||
TaskInventoryItem item)
|
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat(
|
m_log.DebugFormat(
|
||||||
// "[TRANSACTIONS MANAGER] Called HandleTaskItemUpdateFromTransaction with item {0}",
|
"[TRANSACTIONS MANAGER] Called HandleTaskItemUpdateFromTransaction with item {0} in {1} for {2} in {3}",
|
||||||
// item.Name);
|
item.Name, part.Name, remoteClient.Name, m_Scene.RegionInfo.RegionName);
|
||||||
|
|
||||||
AgentAssetTransactions transactions =
|
AgentAssetTransactions transactions =
|
||||||
GetUserTransactions(remoteClient.AgentId);
|
GetUserTransactions(remoteClient.AgentId);
|
||||||
|
|
|
@ -143,7 +143,7 @@ namespace Flotsam.RegionModules.AssetCache
|
||||||
IConfig assetConfig = source.Configs["AssetCache"];
|
IConfig assetConfig = source.Configs["AssetCache"];
|
||||||
if (assetConfig == null)
|
if (assetConfig == null)
|
||||||
{
|
{
|
||||||
m_log.Warn(
|
m_log.Debug(
|
||||||
"[FLOTSAM ASSET CACHE]: AssetCache section missing from config (not copied config-include/FlotsamCache.ini.example? Using defaults.");
|
"[FLOTSAM ASSET CACHE]: AssetCache section missing from config (not copied config-include/FlotsamCache.ini.example? Using defaults.");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -203,10 +203,10 @@ namespace Flotsam.RegionModules.AssetCache
|
||||||
m_CacheDirectoryTierLen = 4;
|
m_CacheDirectoryTierLen = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
MainConsole.Instance.Commands.AddCommand(Name, true, "fcache status", "fcache status", "Display cache status", HandleConsoleCommand);
|
MainConsole.Instance.Commands.AddCommand("Assets", true, "fcache status", "fcache status", "Display cache status", HandleConsoleCommand);
|
||||||
MainConsole.Instance.Commands.AddCommand(Name, true, "fcache clear", "fcache clear [file] [memory]", "Remove all assets in the cache. If file or memory is specified then only this cache is cleared.", HandleConsoleCommand);
|
MainConsole.Instance.Commands.AddCommand("Assets", true, "fcache clear", "fcache clear [file] [memory]", "Remove all assets in the cache. If file or memory is specified then only this cache is cleared.", HandleConsoleCommand);
|
||||||
MainConsole.Instance.Commands.AddCommand(Name, true, "fcache assets", "fcache assets", "Attempt a deep scan and cache of all assets in all scenes", HandleConsoleCommand);
|
MainConsole.Instance.Commands.AddCommand("Assets", true, "fcache assets", "fcache assets", "Attempt a deep scan and cache of all assets in all scenes", HandleConsoleCommand);
|
||||||
MainConsole.Instance.Commands.AddCommand(Name, true, "fcache expire", "fcache expire <datetime>", "Purge cached assets older then the specified date/time", HandleConsoleCommand);
|
MainConsole.Instance.Commands.AddCommand("Assets", true, "fcache expire", "fcache expire <datetime>", "Purge cached assets older then the specified date/time", HandleConsoleCommand);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue