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/Regions/* | ||||
| bin/UserAssets | ||||
| bin/assetcache | ||||
| bin/maptiles | ||||
| bin/estate_settings.xml | ||||
| bin/config-include/CenomeCache.ini | ||||
| bin/config-include/FlotsamCache.ini | ||||
|  |  | |||
|  | @ -8,6 +8,24 @@ | |||
|   <copy file="bin/OpenSim.ini.example" tofile="bin/OpenSim.ini"/> | ||||
|   <copy file="bin/config-include/StandaloneCommon.ini.example" tofile="bin/config-include/StandaloneCommon.ini"/> | ||||
|   <copy file="bin/config-include/FlotsamCache.ini.example" tofile="bin/config-include/FlotsamCache.ini"/> | ||||
|   <!-- delete files generated by runprebuild.sh which had to be run in order to generate the build file for this target--> | ||||
|   <delete> | ||||
|     <fileset basedir="OpenSim"> | ||||
|       <include name="**/*.build"/> | ||||
|       <include name="**/*.csproj*"/> | ||||
|       <include name="**/*.dll.build"/> | ||||
|       <include name="**/*.pidb"/> | ||||
|       <exclude name="Tools/OpenSim.32BitLaunch/**"/> | ||||
|       <exclude name="Tools/Robust.32BitLaunch/**"/> | ||||
|       <exclude name="Tools/LaunchSLClient/**"/> | ||||
|     </fileset> | ||||
|   </delete> | ||||
|   <delete> | ||||
|     <fileset> | ||||
|       <include name="OpenSim.build"/> | ||||
|       <include name="OpenSim.sln"/> | ||||
|     </fileset> | ||||
|   </delete> | ||||
| </target> | ||||
| 
 | ||||
| <property name="distbindir" value="distbin" /> | ||||
|  | @ -117,14 +135,25 @@ | |||
|   <delete dir="%temp%"/> | ||||
| </target> | ||||
| 
 | ||||
| <target name="torture" depends="build, find-nunit"> | ||||
| <target name="test-stress" depends="build, find-nunit"> | ||||
|   <setenv name="MONO_THREADS_PER_CPU" value="100" /> | ||||
| 
 | ||||
|   <exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.tests.torture"> | ||||
|     <arg value="./bin/OpenSim.Tests.Torture.dll" /> | ||||
|   <exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.tests.stress"> | ||||
|     <arg value="./bin/OpenSim.Tests.Stress.dll" /> | ||||
|   </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%"/> | ||||
| </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!) | ||||
| 
 | ||||
| = Current OpenSim Developers (in very rough order of appearance) = | ||||
|  | @ -139,6 +139,9 @@ what it is today. | |||
| * SignpostMarv | ||||
| * SpotOn3D | ||||
| * Strawberry Fride | ||||
| * Talun | ||||
| * TechplexEngineer (Blake Bourque) | ||||
| * TBG Renfold | ||||
| * tglion | ||||
| * tlaukkan/Tommil (Tommi S. E. Laukkanen, Bubble Cloud) | ||||
| * tyre | ||||
|  |  | |||
|  | @ -539,7 +539,6 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory | |||
|         /// path has not already been registered, the method is added to the active | ||||
|         /// handler table. | ||||
|         /// </summary> | ||||
| 
 | ||||
|         public void AddStreamHandler(string httpMethod, string path, RestMethod method) | ||||
|         { | ||||
|             if (!IsEnabled) | ||||
|  |  | |||
|  | @ -101,18 +101,8 @@ namespace OpenSim.Capabilities.Handlers | |||
|             llsdItem.item_id = invItem.ID; | ||||
|             llsdItem.name = invItem.Name; | ||||
|             llsdItem.parent_id = invItem.Folder; | ||||
| 
 | ||||
|             try | ||||
|             { | ||||
|                 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.type = invItem.AssetType; | ||||
|             llsdItem.inv_type = invItem.InvType; | ||||
| 
 | ||||
|             llsdItem.permissions = new LLSDPermissions(); | ||||
|             llsdItem.permissions.creator_id = invItem.CreatorIdAsUuid; | ||||
|  | @ -126,21 +116,7 @@ namespace OpenSim.Capabilities.Handlers | |||
|             llsdItem.permissions.owner_mask = (int)invItem.CurrentPermissions; | ||||
|             llsdItem.sale_info = new LLSDSaleInfo(); | ||||
|             llsdItem.sale_info.sale_price = invItem.SalePrice; | ||||
|             switch (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; | ||||
|             } | ||||
|             llsdItem.sale_info.sale_type = invItem.SaleType; | ||||
| 
 | ||||
|             return llsdItem; | ||||
|         } | ||||
|  |  | |||
|  | @ -63,7 +63,8 @@ namespace OpenSim.Capabilities.Handlers | |||
| 
 | ||||
|             FetchInventory2Handler fiHandler = new FetchInventory2Handler(m_InventoryService); | ||||
|             IRequestHandler reqHandler | ||||
|                 = new RestStreamHandler("POST", "/CAPS/FetchInventory/", fiHandler.FetchInventoryRequest); | ||||
|                 = new RestStreamHandler( | ||||
|                     "POST", "/CAPS/FetchInventory/", fiHandler.FetchInventoryRequest, "FetchInventory", null); | ||||
|             server.AddStreamHandler(reqHandler); | ||||
|         } | ||||
|     } | ||||
|  |  | |||
|  | @ -66,13 +66,14 @@ namespace OpenSim.Capabilities.Handlers | |||
|                 throw new Exception(String.Format("Failed to load AssetService from {0}; config is {1}", assetService, m_ConfigName)); | ||||
| 
 | ||||
|             GetMeshHandler gmeshHandler = new GetMeshHandler(m_AssetService); | ||||
|             IRequestHandler reqHandler = new RestHTTPHandler("GET", "/CAPS/" + UUID.Random(), | ||||
|                                                        delegate(Hashtable m_dhttpMethod) | ||||
|                                                        { | ||||
|                                                            return gmeshHandler.ProcessGetMesh(m_dhttpMethod, UUID.Zero, null); | ||||
|                                                        }); | ||||
|             IRequestHandler reqHandler | ||||
|                 = new RestHTTPHandler( | ||||
|                     "GET", | ||||
|                     "/CAPS/" + UUID.Random(), | ||||
|                     httpMethod => gmeshHandler.ProcessGetMesh(httpMethod, UUID.Zero, null), | ||||
|                     "GetMesh", | ||||
|                     null); | ||||
|             server.AddStreamHandler(reqHandler); | ||||
|         } | ||||
| 
 | ||||
|     } | ||||
| } | ||||
| } | ||||
|  | @ -58,8 +58,8 @@ namespace OpenSim.Capabilities.Handlers | |||
|         // TODO: Change this to a config option | ||||
|         const string REDIRECT_URL = null; | ||||
| 
 | ||||
|         public GetTextureHandler(string path, IAssetService assService) : | ||||
|                 base("GET", path) | ||||
|         public GetTextureHandler(string path, IAssetService assService, string name, string description) | ||||
|             : base("GET", path, name, description) | ||||
|         { | ||||
|             m_assetService = assService; | ||||
|         } | ||||
|  | @ -77,7 +77,6 @@ namespace OpenSim.Capabilities.Handlers | |||
|             { | ||||
|                 m_log.Error("[GETTEXTURE]: Cannot fetch texture " + textureStr + " without an asset service"); | ||||
|                 httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound; | ||||
|                 return null; | ||||
|             } | ||||
| 
 | ||||
|             UUID textureID; | ||||
|  | @ -115,7 +114,6 @@ namespace OpenSim.Capabilities.Handlers | |||
| //                "[GETTEXTURE]: For texture {0} sending back response {1}, data length {2}", | ||||
| //                textureID, httpResponse.StatusCode, httpResponse.ContentLength); | ||||
| 
 | ||||
|             httpResponse.Send(); | ||||
|             return null; | ||||
|         } | ||||
| 
 | ||||
|  | @ -165,7 +163,7 @@ namespace OpenSim.Capabilities.Handlers | |||
| 
 | ||||
|                 if (texture == null) | ||||
|                 { | ||||
|                     //m_log.DebugFormat("[GETTEXTURE]: texture was not in the cache"); | ||||
| //                    m_log.DebugFormat("[GETTEXTURE]: texture was not in the cache"); | ||||
| 
 | ||||
|                     // Fetch locally or remotely. Misses return a 404 | ||||
|                     texture = m_assetService.Get(textureID.ToString()); | ||||
|  | @ -199,7 +197,7 @@ namespace OpenSim.Capabilities.Handlers | |||
|                } | ||||
|                else // it was on the cache | ||||
|                { | ||||
|                    //m_log.DebugFormat("[GETTEXTURE]: texture was in the cache"); | ||||
| //                   m_log.DebugFormat("[GETTEXTURE]: texture was in the cache"); | ||||
|                    WriteTextureData(httpRequest, httpResponse, texture, format); | ||||
|                    return true; | ||||
|                } | ||||
|  | @ -221,12 +219,30 @@ namespace OpenSim.Capabilities.Handlers | |||
|                 int start, end; | ||||
|                 if (TryParseRange(range, out start, out end)) | ||||
|                 { | ||||
| 
 | ||||
|                     // Before clamping start make sure we can satisfy it in order to avoid | ||||
|                     // sending back the last byte instead of an error status | ||||
|                     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 | ||||
|                     { | ||||
|  | @ -234,12 +250,18 @@ namespace OpenSim.Capabilities.Handlers | |||
|                         start = Utils.Clamp(start, 0, end); | ||||
|                         int len = end - start + 1; | ||||
| 
 | ||||
|                         //m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID); | ||||
| //                        m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID); | ||||
| 
 | ||||
|                         // Always return PartialContent, even if the range covered the entire data length | ||||
|                         // We were accidentally sending back 404 before in this situation | ||||
|                         // https://issues.apache.org/bugzilla/show_bug.cgi?id=51878 supports sending 206 even if the | ||||
|                         // entire range is requested, and viewer 3.2.2 (and very probably earlier) seems fine with this. | ||||
|                         // | ||||
|                         // 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.ContentLength = len; | ||||
|  |  | |||
|  | @ -62,8 +62,8 @@ namespace OpenSim.Capabilities.Handlers | |||
|             if (m_AssetService == null) | ||||
|                 throw new Exception(String.Format("Failed to load AssetService from {0}; config is {1}", assetService, m_ConfigName)); | ||||
| 
 | ||||
|             server.AddStreamHandler(new GetTextureHandler("/CAPS/GetTexture/" /*+ UUID.Random() */, m_AssetService)); | ||||
|             server.AddStreamHandler( | ||||
|                 new GetTextureHandler("/CAPS/GetTexture/" /*+ UUID.Random() */, m_AssetService, "GetTexture", null)); | ||||
|         } | ||||
| 
 | ||||
|     } | ||||
| } | ||||
| } | ||||
|  | @ -50,9 +50,9 @@ namespace OpenSim.Capabilities.Handlers.GetTexture.Tests | |||
|             TestHelpers.InMethod(); | ||||
| 
 | ||||
|             // Overkill - we only really need the asset service, not a whole scene. | ||||
|             Scene scene = SceneHelpers.SetupScene(); | ||||
|             Scene scene = new SceneHelpers().SetupScene(); | ||||
| 
 | ||||
|             GetTextureHandler handler = new GetTextureHandler(null, scene.AssetService); | ||||
|             GetTextureHandler handler = new GetTextureHandler(null, scene.AssetService, "TestGetTexture", null); | ||||
|             TestOSHttpRequest req = new TestOSHttpRequest(); | ||||
|             TestOSHttpResponse resp = new TestOSHttpResponse(); | ||||
|             req.Url = new Uri("http://localhost/?texture_id=00000000-0000-1111-9999-000000000012"); | ||||
|  |  | |||
|  | @ -85,8 +85,8 @@ namespace OpenSim.Capabilities.Handlers | |||
|                 uploader.OnUpLoad += BakedTextureUploaded; | ||||
| 
 | ||||
|                 m_HostCapsObj.HttpListener.AddStreamHandler( | ||||
|                         new BinaryStreamHandler("POST", capsBase + uploaderPath, | ||||
|                         uploader.uploaderCaps)); | ||||
|                     new BinaryStreamHandler( | ||||
|                         "POST", capsBase + uploaderPath, uploader.uploaderCaps, "UploadBakedTexture", null)); | ||||
| 
 | ||||
|                 string protocol = "http://"; | ||||
| 
 | ||||
|  |  | |||
|  | @ -156,11 +156,12 @@ namespace OpenSim.Capabilities.Handlers | |||
|             inv.Folders = new List<InventoryFolderBase>(); | ||||
|             inv.Items = new List<InventoryItemBase>(); | ||||
|             int version = 0; | ||||
|             int descendents = 0; | ||||
| 
 | ||||
|             inv | ||||
|                 = Fetch( | ||||
|                     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) | ||||
|             { | ||||
|  | @ -168,6 +169,8 @@ namespace OpenSim.Capabilities.Handlers | |||
|                 { | ||||
|                     contents.categories.Array.Add(ConvertInventoryFolder(invFolder)); | ||||
|                 } | ||||
| 
 | ||||
|                 descendents += inv.Folders.Count; | ||||
|             } | ||||
| 
 | ||||
|             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; | ||||
| 
 | ||||
| //            m_log.DebugFormat( | ||||
|  | @ -206,7 +209,7 @@ namespace OpenSim.Capabilities.Handlers | |||
|         /// <returns>An empty InventoryCollection if the inventory look up failed</returns> | ||||
|         private InventoryCollection Fetch( | ||||
|             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( | ||||
| //                "[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! | ||||
| 
 | ||||
|             version = 0; | ||||
|             descendents = 0; | ||||
| 
 | ||||
|             InventoryFolderImpl fold; | ||||
|             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(); | ||||
|                     ret.Folders = new List<InventoryFolderBase>(); | ||||
|                     ret.Items = fold.RequestListOfItems(); | ||||
|                     descendents = ret.Folders.Count + ret.Items.Count; | ||||
| 
 | ||||
|                     return ret; | ||||
|                 } | ||||
|  | @ -246,24 +252,72 @@ namespace OpenSim.Capabilities.Handlers | |||
| 
 | ||||
|                     version = containingFolder.Version; | ||||
| 
 | ||||
| //                    if (fetchItems) | ||||
|                     if (fetchItems) | ||||
|                     { | ||||
|                         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) | ||||
| //                    { | ||||
| //                        List<InventoryItemBase> linkedItemsToAdd = new List<InventoryItemBase>(); | ||||
| // | ||||
| //                        foreach (InventoryItemBase item in contents.Items) | ||||
| //                        { | ||||
| //                            if (item.AssetType == (int)AssetType.Link) | ||||
| //                            { | ||||
| //                                InventoryItemBase linkedItem = m_InventoryService.GetItem(new InventoryItemBase(item.AssetID)); | ||||
| // | ||||
| //                                // Take care of genuinely broken links where the target doesn't exist | ||||
| //                                // HACK: Also, don't follow up links that just point to other links.  In theory this is legitimate, | ||||
| //                                // but no viewer has been observed to set these up and this is the lazy way of avoiding cycles | ||||
| //                                // rather than having to keep track of every folder requested in the recursion. | ||||
| //                                if (linkedItem != null && linkedItem.AssetType != (int)AssetType.Link) | ||||
| //                                    linkedItemsToAdd.Insert(0, linkedItem); | ||||
| //                            } | ||||
| //                        } | ||||
| //                        m_log.DebugFormat( | ||||
| //                            "[WEB FETCH INV DESC HANDLER]: Returning item {0}, type {1}, parent {2} in {3} {4}", | ||||
| //                            item.Name, (AssetType)item.AssetType, item.Folder, containingFolder.Name, containingFolder.ID); | ||||
| //                    } | ||||
| 
 | ||||
|                     // ===== | ||||
| 
 | ||||
| // | ||||
| //                        foreach (InventoryItemBase linkedItem in linkedItemsToAdd) | ||||
| //                        { | ||||
|  | @ -340,12 +394,8 @@ namespace OpenSim.Capabilities.Handlers | |||
|             llsdFolder.folder_id = invFolder.ID; | ||||
|             llsdFolder.parent_id = invFolder.ParentID; | ||||
|             llsdFolder.name = invFolder.Name; | ||||
| 
 | ||||
|             if (invFolder.Type == (short)AssetType.Unknown || !Enum.IsDefined(typeof(AssetType), (sbyte)invFolder.Type)) | ||||
|                 llsdFolder.type = "-1"; | ||||
|             else | ||||
|                 llsdFolder.type = Utils.AssetTypeToString((AssetType)invFolder.Type); | ||||
|             llsdFolder.preferred_type = "-1"; | ||||
|             llsdFolder.type = invFolder.Type; | ||||
|             llsdFolder.preferred_type = -1; | ||||
| 
 | ||||
|             return llsdFolder; | ||||
|         } | ||||
|  | @ -365,18 +415,8 @@ namespace OpenSim.Capabilities.Handlers | |||
|             llsdItem.item_id = invItem.ID; | ||||
|             llsdItem.name = invItem.Name; | ||||
|             llsdItem.parent_id = invItem.Folder; | ||||
| 
 | ||||
|             try | ||||
|             { | ||||
|                 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.type = invItem.AssetType; | ||||
|             llsdItem.inv_type = invItem.InvType; | ||||
| 
 | ||||
|             llsdItem.permissions = new LLSDPermissions(); | ||||
|             llsdItem.permissions.creator_id = invItem.CreatorIdAsUuid; | ||||
|  | @ -390,21 +430,7 @@ namespace OpenSim.Capabilities.Handlers | |||
|             llsdItem.permissions.owner_mask = (int)invItem.CurrentPermissions; | ||||
|             llsdItem.sale_info = new LLSDSaleInfo(); | ||||
|             llsdItem.sale_info.sale_price = invItem.SalePrice; | ||||
|             switch (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; | ||||
|             } | ||||
|             llsdItem.sale_info.sale_type = invItem.SaleType; | ||||
| 
 | ||||
|             return llsdItem; | ||||
|         } | ||||
|  |  | |||
|  | @ -68,7 +68,13 @@ namespace OpenSim.Capabilities.Handlers | |||
|                     ServerUtils.LoadPlugin<ILibraryService>(libService, args); | ||||
| 
 | ||||
|             WebFetchInvDescHandler webFetchHandler = new WebFetchInvDescHandler(m_InventoryService, m_LibraryService); | ||||
|             IRequestHandler reqHandler = new RestStreamHandler("POST", "/CAPS/WebFetchInvDesc/" /*+ UUID.Random()*/, webFetchHandler.FetchInventoryDescendentsRequest); | ||||
|             IRequestHandler reqHandler | ||||
|                 = new RestStreamHandler( | ||||
|                     "POST", | ||||
|                     "/CAPS/WebFetchInvDesc/" /*+ UUID.Random()*/, | ||||
|                     webFetchHandler.FetchInventoryDescendentsRequest, | ||||
|                     "WebFetchInvDesc", | ||||
|                     null); | ||||
|             server.AddStreamHandler(reqHandler); | ||||
|         } | ||||
| 
 | ||||
|  |  | |||
|  | @ -35,7 +35,7 @@ namespace OpenSim.Framework.Capabilities | |||
|         public UUID folder_id; | ||||
|         public UUID parent_id; | ||||
|         public string name; | ||||
|         public string type; | ||||
|         public string preferred_type; | ||||
|         public int type; | ||||
|         public int preferred_type; | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -37,8 +37,8 @@ namespace OpenSim.Framework.Capabilities | |||
|         public UUID asset_id; | ||||
|         public UUID item_id; | ||||
|         public LLSDPermissions permissions; | ||||
|         public string type; | ||||
|         public string inv_type; | ||||
|         public int type; | ||||
|         public int inv_type; | ||||
|         public int flags; | ||||
| 
 | ||||
|         public LLSDSaleInfo sale_info; | ||||
|  | @ -65,7 +65,7 @@ namespace OpenSim.Framework.Capabilities | |||
|     public class LLSDSaleInfo | ||||
|     { | ||||
|         public int sale_price; | ||||
|         public string sale_type; | ||||
|         public int sale_type; | ||||
|     } | ||||
| 
 | ||||
|     [OSDMap] | ||||
|  |  | |||
|  | @ -39,7 +39,11 @@ namespace OpenSim.Framework.Capabilities | |||
|         private LLSDMethod<TRequest, TResponse> m_method; | ||||
| 
 | ||||
|         public LLSDStreamhandler(string httpMethod, string path, LLSDMethod<TRequest, TResponse> method) | ||||
|             : base(httpMethod, path) | ||||
|             : this(httpMethod, path, method, null, null) {} | ||||
| 
 | ||||
|         public LLSDStreamhandler( | ||||
|             string httpMethod, string path, LLSDMethod<TRequest, TResponse> method, string name, string description) | ||||
|             : base(httpMethod, path, name, description) | ||||
|         { | ||||
|             m_method = method; | ||||
|         } | ||||
|  | @ -62,9 +66,7 @@ namespace OpenSim.Framework.Capabilities | |||
| 
 | ||||
|             TResponse response = m_method(llsdRequest); | ||||
| 
 | ||||
|             Encoding encoding = new UTF8Encoding(false); | ||||
| 
 | ||||
|             return encoding.GetBytes(LLSDHelpers.SerialiseLLSDReply(response)); | ||||
|             return Util.UTF8NoBomEncoding.GetBytes(LLSDHelpers.SerialiseLLSDReply(response)); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -50,7 +50,7 @@ namespace OpenSim.ConsoleClient | |||
| 
 | ||||
|             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; | ||||
|             request.ContentLength = length; | ||||
| 
 | ||||
|  |  | |||
|  | @ -106,7 +106,22 @@ namespace OpenSim.Data | |||
|         /// <returns>true if the delete was successful, false if it was not</returns> | ||||
|         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); | ||||
|         int GetAssetPermissions(UUID principalID, UUID assetID); | ||||
|     } | ||||
|  |  | |||
|  | @ -89,5 +89,11 @@ namespace OpenSim.Data.MSSQL | |||
|                 return DoQuery(cmd); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public FriendsData[] GetFriends(Guid principalID) | ||||
|         { | ||||
|             return GetFriends(principalID.ToString()); | ||||
|         } | ||||
|   | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -813,7 +813,7 @@ namespace OpenSim.Data.MSSQL | |||
|         { | ||||
|             try | ||||
|             { | ||||
|                 using (SqlCommand command = new SqlCommand("DELETE FROM inventoryfolders WHERE folderID=@folderID", connection)) | ||||
|                 using (SqlCommand command = new SqlCommand("DELETE FROM inventoryfolders WHERE folderID=@folderID and type=-1", connection)) | ||||
|                 { | ||||
|                     command.Parameters.Add(database.CreateParameter("folderID", folderID)); | ||||
| 
 | ||||
|  |  | |||
|  | @ -675,7 +675,7 @@ VALUES | |||
|                 cmd.ExecuteNonQuery(); | ||||
|             } | ||||
| 
 | ||||
|             sql = "INSERT INTO [landaccesslist] ([LandUUID],[AccessUUID],[Flags]) VALUES (@LandUUID,@AccessUUID,@Flags)"; | ||||
|             sql = "INSERT INTO [landaccesslist] ([LandUUID],[AccessUUID],[Flags],[Expires]) VALUES (@LandUUID,@AccessUUID,@Flags,@Expires)"; | ||||
| 
 | ||||
|             using (SqlConnection conn = new SqlConnection(m_connectionString)) | ||||
|             using (SqlCommand cmd = new SqlCommand(sql, conn)) | ||||
|  | @ -1215,6 +1215,8 @@ VALUES | |||
|             //Store new values | ||||
|             StoreNewRegionSettings(regionSettings); | ||||
| 
 | ||||
|             LoadSpawnPoints(regionSettings); | ||||
| 
 | ||||
|             return regionSettings; | ||||
|         } | ||||
| 
 | ||||
|  | @ -1252,7 +1254,7 @@ VALUES | |||
| ,[elevation_1_ne] = @elevation_1_ne ,[elevation_2_ne] = @elevation_2_ne ,[elevation_1_se] = @elevation_1_se ,[elevation_2_se] = @elevation_2_se  | ||||
| ,[elevation_1_sw] = @elevation_1_sw ,[elevation_2_sw] = @elevation_2_sw ,[water_height] = @water_height ,[terrain_raise_limit] = @terrain_raise_limit  | ||||
| ,[terrain_lower_limit] = @terrain_lower_limit ,[use_estate_sun] = @use_estate_sun ,[fixed_sun] = @fixed_sun ,[sun_position] = @sun_position  | ||||
| ,[covenant] = @covenant ,[covenant_datetime] = @covenant_datetime, [sunvectorx] = @sunvectorx, [sunvectory] = @sunvectory, [sunvectorz] = @sunvectorz,  [Sandbox] = @Sandbox, [loaded_creation_datetime] = @loaded_creation_datetime, [loaded_creation_id] = @loaded_creation_id | ||||
| ,[covenant] = @covenant ,[covenant_datetime] = @covenant_datetime, [sunvectorx] = @sunvectorx, [sunvectory] = @sunvectory, [sunvectorz] = @sunvectorz,  [Sandbox] = @Sandbox, [loaded_creation_datetime] = @loaded_creation_datetime, [loaded_creation_id] = @loaded_creation_id, [map_tile_id] = @TerrainImageID, [telehubobject] = @telehubobject, [parcel_tile_id] = @ParcelImageID | ||||
|  WHERE [regionUUID] = @regionUUID";
 | ||||
| 
 | ||||
|                 using (SqlConnection conn = new SqlConnection(m_connectionString)) | ||||
|  | @ -1263,6 +1265,7 @@ VALUES | |||
|                     cmd.ExecuteNonQuery(); | ||||
|                 } | ||||
|             } | ||||
|             SaveSpawnPoints(regionSettings); | ||||
|         } | ||||
| 
 | ||||
|         public void Shutdown() | ||||
|  | @ -1383,6 +1386,11 @@ VALUES | |||
|                 newSettings.LoadedCreationID = ""; | ||||
|             else | ||||
|                 newSettings.LoadedCreationID = (String)row["loaded_creation_id"]; | ||||
| 
 | ||||
|             newSettings.TerrainImageID = new UUID((string)row["map_tile_ID"]); | ||||
|             newSettings.ParcelImageID = new UUID((Guid)row["parcel_tile_ID"]); | ||||
|             newSettings.TelehubObject = new UUID((Guid)row["TelehubObject"]); | ||||
| 
 | ||||
|             return newSettings; | ||||
|         } | ||||
| 
 | ||||
|  | @ -1454,6 +1462,13 @@ VALUES | |||
|             } | ||||
| 
 | ||||
|             newData.ParcelAccessList = new List<LandAccessEntry>(); | ||||
|             newData.MediaDescription = (string)row["MediaDescription"]; | ||||
|             newData.MediaType = (string)row["MediaType"]; | ||||
|             newData.MediaWidth = Convert.ToInt32((((string)row["MediaSize"]).Split(','))[0]); | ||||
|             newData.MediaHeight = Convert.ToInt32((((string)row["MediaSize"]).Split(','))[1]); | ||||
|             newData.MediaLoop = Convert.ToBoolean(row["MediaLoop"]); | ||||
|             newData.ObscureMusic = Convert.ToBoolean(row["ObscureMusic"]); | ||||
|             newData.ObscureMedia = Convert.ToBoolean(row["ObscureMedia"]); | ||||
| 
 | ||||
|             return newData; | ||||
|         } | ||||
|  | @ -1468,7 +1483,7 @@ VALUES | |||
|             LandAccessEntry entry = new LandAccessEntry(); | ||||
|             entry.AgentID = new UUID((Guid)row["AccessUUID"]); | ||||
|             entry.Flags = (AccessList)Convert.ToInt32(row["Flags"]); | ||||
|             entry.Expires = 0; | ||||
|             entry.Expires = Convert.ToInt32(row["Expires"]); | ||||
|             return entry; | ||||
|         } | ||||
| 
 | ||||
|  | @ -1497,7 +1512,8 @@ VALUES | |||
|             prim.TouchName = (string)primRow["TouchName"]; | ||||
|             // permissions | ||||
|             prim.Flags = (PrimFlags)Convert.ToUInt32(primRow["ObjectFlags"]); | ||||
|             prim.CreatorID = new UUID((Guid)primRow["CreatorID"]); | ||||
|             //prim.CreatorID = new UUID((Guid)primRow["CreatorID"]); | ||||
|             prim.CreatorIdentification = (string)primRow["CreatorID"]; | ||||
|             prim.OwnerID = new UUID((Guid)primRow["OwnerID"]); | ||||
|             prim.GroupID = new UUID((Guid)primRow["GroupID"]); | ||||
|             prim.LastOwnerID = new UUID((Guid)primRow["LastOwnerID"]); | ||||
|  | @ -1691,7 +1707,8 @@ VALUES | |||
|             taskItem.Name = (string)inventoryRow["name"]; | ||||
|             taskItem.Description = (string)inventoryRow["description"]; | ||||
|             taskItem.CreationDate = Convert.ToUInt32(inventoryRow["creationDate"]); | ||||
|             taskItem.CreatorID = new UUID((Guid)inventoryRow["creatorID"]); | ||||
|             //taskItem.CreatorID = new UUID((Guid)inventoryRow["creatorID"]); | ||||
|             taskItem.CreatorIdentification = (string)inventoryRow["creatorID"]; | ||||
|             taskItem.OwnerID = new UUID((Guid)inventoryRow["ownerID"]); | ||||
|             taskItem.LastOwnerID = new UUID((Guid)inventoryRow["lastOwnerID"]); | ||||
|             taskItem.GroupID = new UUID((Guid)inventoryRow["groupID"]); | ||||
|  | @ -1792,6 +1809,9 @@ VALUES | |||
|             parameters.Add(_Database.CreateParameter("covenant_datetime", settings.CovenantChangedDateTime)); | ||||
|             parameters.Add(_Database.CreateParameter("Loaded_Creation_DateTime", settings.LoadedCreationDateTime)); | ||||
|             parameters.Add(_Database.CreateParameter("Loaded_Creation_ID", settings.LoadedCreationID)); | ||||
|             parameters.Add(_Database.CreateParameter("TerrainImageID", settings.TerrainImageID)); | ||||
|             parameters.Add(_Database.CreateParameter("ParcelImageID", settings.ParcelImageID)); | ||||
|             parameters.Add(_Database.CreateParameter("TelehubObject", settings.TelehubObject)); | ||||
| 
 | ||||
|             return parameters.ToArray(); | ||||
|         } | ||||
|  | @ -1859,6 +1879,7 @@ VALUES | |||
|             parameters.Add(_Database.CreateParameter("LandUUID", parcelID)); | ||||
|             parameters.Add(_Database.CreateParameter("AccessUUID", parcelAccessEntry.AgentID)); | ||||
|             parameters.Add(_Database.CreateParameter("Flags", parcelAccessEntry.Flags)); | ||||
|             parameters.Add(_Database.CreateParameter("Expires", parcelAccessEntry.Expires)); | ||||
| 
 | ||||
|             return parameters.ToArray(); | ||||
|         } | ||||
|  | @ -2063,5 +2084,57 @@ VALUES | |||
|         #endregion | ||||
| 
 | ||||
|         #endregion | ||||
| 
 | ||||
|         private void LoadSpawnPoints(RegionSettings rs) | ||||
|         { | ||||
|             rs.ClearSpawnPoints(); | ||||
| 
 | ||||
|             string sql = "SELECT Yaw, Pitch, Distance FROM spawn_points WHERE RegionUUID = @RegionUUID"; | ||||
|             using (SqlConnection conn = new SqlConnection(m_connectionString)) | ||||
|             using (SqlCommand cmd = new SqlCommand(sql, conn)) | ||||
|             { | ||||
|                 cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", rs.RegionUUID.ToString())); | ||||
|                 conn.Open(); | ||||
|                 using (SqlDataReader reader = cmd.ExecuteReader()) | ||||
|                 { | ||||
|                     if (reader.Read()) | ||||
|                     { | ||||
|                         SpawnPoint sp = new SpawnPoint(); | ||||
| 
 | ||||
|                         sp.Yaw = (float)reader["Yaw"]; | ||||
|                         sp.Pitch = (float)reader["Pitch"]; | ||||
|                         sp.Distance = (float)reader["Distance"]; | ||||
| 
 | ||||
|                         rs.AddSpawnPoint(sp); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         private void SaveSpawnPoints(RegionSettings rs) | ||||
|         { | ||||
|             string sql = "DELETE FROM spawn_points WHERE RegionUUID = @RegionUUID"; | ||||
|             using (SqlConnection conn = new SqlConnection(m_connectionString)) | ||||
|             using (SqlCommand cmd = new SqlCommand(sql, conn)) | ||||
|             { | ||||
|                 cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", rs.RegionUUID)); | ||||
|                 conn.Open(); | ||||
|                 cmd.ExecuteNonQuery(); | ||||
|             } | ||||
|             foreach (SpawnPoint p in rs.SpawnPoints()) | ||||
|             { | ||||
|                 sql = "INSERT INTO spawn_points (RegionUUID, Yaw, Pitch, Distance) VALUES (@RegionUUID, @Yaw, @Pitch, @Distance)"; | ||||
|                 using (SqlConnection conn = new SqlConnection(m_connectionString)) | ||||
|                 using (SqlCommand cmd = new SqlCommand(sql, conn)) | ||||
|                 { | ||||
|                     cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", rs.RegionUUID)); | ||||
|                     cmd.Parameters.Add(_Database.CreateParameter("@Yaw", p.Yaw)); | ||||
|                     cmd.Parameters.Add(_Database.CreateParameter("@Pitch", p.Pitch)); | ||||
|                     cmd.Parameters.Add(_Database.CreateParameter("@Distance", p.Distance)); | ||||
|                     conn.Open(); | ||||
|                     cmd.ExecuteNonQuery(); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -43,12 +43,12 @@ namespace OpenSim.Data.MSSQL | |||
| //        private static readonly ILog m_log = LogManager.GetLogger( | ||||
| //                MethodBase.GetCurrentMethod().DeclaringType); | ||||
| 
 | ||||
|         private MSSQLGenericTableHandler<XInventoryFolder> m_Folders; | ||||
|         private MSSQLFolderHandler m_Folders; | ||||
|         private MSSQLItemHandler m_Items; | ||||
| 
 | ||||
|         public MSSQLXInventoryData(string conn, string realm) | ||||
|         { | ||||
|             m_Folders = new MSSQLGenericTableHandler<XInventoryFolder>( | ||||
|             m_Folders = new MSSQLFolderHandler( | ||||
|                     conn, "inventoryfolders", "InventoryStore"); | ||||
|             m_Items = new MSSQLItemHandler( | ||||
|                     conn, "inventoryitems", String.Empty); | ||||
|  | @ -85,6 +85,7 @@ namespace OpenSim.Data.MSSQL | |||
|         { | ||||
|             return m_Folders.Delete(field, val); | ||||
|         } | ||||
| 
 | ||||
|         public bool DeleteFolders(string[] fields, string[] vals) | ||||
|         { | ||||
|             return m_Folders.Delete(fields, vals); | ||||
|  | @ -94,15 +95,22 @@ namespace OpenSim.Data.MSSQL | |||
|         { | ||||
|             return m_Items.Delete(field, val); | ||||
|         } | ||||
| 
 | ||||
|         public bool DeleteItems(string[] fields, string[] vals) | ||||
|         { | ||||
|             return m_Items.Delete(fields, vals); | ||||
|         } | ||||
| 
 | ||||
|         public bool MoveItem(string id, string 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) | ||||
|         { | ||||
|             return m_Items.GetActiveGestures(principalID); | ||||
|  | @ -124,79 +132,115 @@ namespace OpenSim.Data.MSSQL | |||
|         public bool MoveItem(string id, string newParent) | ||||
|         { | ||||
|             using (SqlConnection conn = new SqlConnection(m_ConnectionString)) | ||||
|             using (SqlCommand cmd = new SqlCommand()) | ||||
|             { | ||||
|                 using (SqlCommand cmd = new SqlCommand()) | ||||
|                 { | ||||
| 
 | ||||
|                 cmd.CommandText = String.Format("update {0} set parentFolderID = @ParentFolderID where inventoryID = @InventoryID", m_Realm); | ||||
|                 cmd.Parameters.Add(m_database.CreateParameter("@ParentFolderID", newParent)); | ||||
|                 cmd.Parameters.Add(m_database.CreateParameter("@InventoryID", id)); | ||||
|                 cmd.Connection = conn; | ||||
|                 conn.Open(); | ||||
|                 return cmd.ExecuteNonQuery() == 0 ? false : true; | ||||
|                     cmd.CommandText = String.Format("update {0} set parentFolderID = @ParentFolderID where inventoryID = @InventoryID", m_Realm); | ||||
|                     cmd.Parameters.Add(m_database.CreateParameter("@ParentFolderID", newParent)); | ||||
|                     cmd.Parameters.Add(m_database.CreateParameter("@InventoryID", id)); | ||||
|                     cmd.Connection = conn; | ||||
|                     conn.Open(); | ||||
|                     return cmd.ExecuteNonQuery() == 0 ? false : true; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public XInventoryItem[] GetActiveGestures(UUID principalID) | ||||
|         { | ||||
|             using (SqlConnection conn = new SqlConnection(m_ConnectionString)) | ||||
|             using (SqlCommand cmd = new SqlCommand()) | ||||
|             { | ||||
|                 cmd.CommandText = String.Format("select * from inventoryitems where avatarId = @uuid and assetType = @type and flags = 1", m_Realm); | ||||
|                 using (SqlCommand cmd = new SqlCommand()) | ||||
|                 { | ||||
|                     cmd.CommandText = String.Format("select * from inventoryitems where avatarId = @uuid and assetType = @type and flags = 1", m_Realm); | ||||
| 
 | ||||
|                 cmd.Parameters.Add(m_database.CreateParameter("@uuid", principalID.ToString())); | ||||
|                 cmd.Parameters.Add(m_database.CreateParameter("@type", (int)AssetType.Gesture)); | ||||
|                 cmd.Connection = conn; | ||||
|                 conn.Open(); | ||||
|                 return DoQuery(cmd); | ||||
|                     cmd.Parameters.Add(m_database.CreateParameter("@uuid", principalID.ToString())); | ||||
|                     cmd.Parameters.Add(m_database.CreateParameter("@type", (int)AssetType.Gesture)); | ||||
|                     cmd.Connection = conn; | ||||
|                     conn.Open(); | ||||
|                     return DoQuery(cmd); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public int GetAssetPermissions(UUID principalID, UUID assetID) | ||||
|         { | ||||
|             using (SqlConnection conn = new SqlConnection(m_ConnectionString)) | ||||
|             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.Parameters.Add(m_database.CreateParameter("@PrincipalID", principalID.ToString())); | ||||
|                 cmd.Parameters.Add(m_database.CreateParameter("@AssetID", assetID.ToString())); | ||||
|                 cmd.Connection = conn; | ||||
|                 conn.Open(); | ||||
|                 using (SqlDataReader reader = cmd.ExecuteReader()) | ||||
|                 using (SqlCommand cmd = new SqlCommand()) | ||||
|                 { | ||||
| 
 | ||||
|                     int perms = 0; | ||||
| 
 | ||||
|                     if (reader.Read()) | ||||
|                     cmd.CommandText = String.Format("select bit_or(inventoryCurrentPermissions) as inventoryCurrentPermissions from inventoryitems where avatarID = @PrincipalID and assetID = @AssetID group by assetID", m_Realm); | ||||
|                     cmd.Parameters.Add(m_database.CreateParameter("@PrincipalID", principalID.ToString())); | ||||
|                     cmd.Parameters.Add(m_database.CreateParameter("@AssetID", assetID.ToString())); | ||||
|                     cmd.Connection = conn; | ||||
|                     conn.Open(); | ||||
|                     using (SqlDataReader reader = cmd.ExecuteReader()) | ||||
|                     { | ||||
|                         perms = Convert.ToInt32(reader["inventoryCurrentPermissions"]); | ||||
| 
 | ||||
|                         int perms = 0; | ||||
| 
 | ||||
|                         if (reader.Read()) | ||||
|                         { | ||||
|                             perms = Convert.ToInt32(reader["inventoryCurrentPermissions"]); | ||||
|                         } | ||||
| 
 | ||||
|                         return perms; | ||||
|                     } | ||||
| 
 | ||||
|                     return perms; | ||||
|                 } | ||||
| 
 | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public override bool Store(XInventoryItem item) | ||||
|         { | ||||
|             if (!base.Store(item)) | ||||
|                 return false; | ||||
| 
 | ||||
|             string sql = "update inventoryfolders set version=version+1 where folderID = @folderID"; | ||||
|             using (SqlConnection conn = new SqlConnection(m_ConnectionString)) | ||||
|             using (SqlCommand cmd = new SqlCommand(sql, conn)) | ||||
|             { | ||||
|                 conn.Open(); | ||||
|                 using (SqlCommand cmd = new SqlCommand(sql, conn)) | ||||
|                 { | ||||
|                     conn.Open(); | ||||
| 
 | ||||
|                     cmd.Parameters.AddWithValue("@folderID", item.parentFolderID.ToString()); | ||||
|                     try | ||||
|                     { | ||||
|                         cmd.ExecuteNonQuery(); | ||||
|                     } | ||||
|                     catch (Exception) | ||||
|                     { | ||||
|                         return false; | ||||
|                     }                 | ||||
|                         cmd.Parameters.AddWithValue("@folderID", item.parentFolderID.ToString()); | ||||
|                         try | ||||
|                         { | ||||
|                             cmd.ExecuteNonQuery(); | ||||
|                         } | ||||
|                         catch (Exception) | ||||
|                         { | ||||
|                             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 | ||||
| 
 | ||||
| :VERSION 29         #--------------------- | ||||
| :VERSION 29         #----------------- Region Covenant changed time | ||||
| 
 | ||||
| BEGIN TRANSACTION | ||||
| 
 | ||||
| ALTER TABLE regionsettings ADD covenant_datetime int NOT NULL default 0 | ||||
| 
 | ||||
| COMMIT | ||||
| 
 | ||||
| :VERSION 30         #------------------Migrate creatorID storage to varchars instead of UUIDs for HG support | ||||
| 
 | ||||
| BEGIN TRANSACTION | ||||
| 
 | ||||
| EXECUTE sp_rename N'dbo.prims.creatorid', N'creatoridold', 'COLUMN' | ||||
| EXECUTE sp_rename N'dbo.primitems.creatorid', N'creatoridold', 'COLUMN' | ||||
| 
 | ||||
| COMMIT | ||||
| 
 | ||||
| :VERSION 31        #--------------------- | ||||
| 
 | ||||
| BEGIN TRANSACTION | ||||
| 
 | ||||
| ALTER TABLE prims ADD CreatorID varchar(255) | ||||
| ALTER TABLE primitems ADD CreatorID varchar(255) | ||||
| 
 | ||||
| COMMIT | ||||
| 
 | ||||
| :VERSION 32        #--------------------- | ||||
| 
 | ||||
| BEGIN TRANSACTION | ||||
| 
 | ||||
| UPDATE prims SET prims.CreatorID = CONVERT(varchar(255), creatoridold) | ||||
| UPDATE primitems SET primitems.CreatorID = CONVERT(varchar(255), creatoridold) | ||||
| 
 | ||||
| COMMIT | ||||
| 
 | ||||
| :VERSION 33       #--------------------- | ||||
| 
 | ||||
| BEGIN TRANSACTION | ||||
| 
 | ||||
| ALTER TABLE prims  | ||||
| ADD CONSTRAINT DF_prims_CreatorIDNew  | ||||
| DEFAULT '00000000-0000-0000-0000-000000000000'  | ||||
| FOR CreatorID | ||||
| 
 | ||||
| ALTER TABLE prims ALTER COLUMN CreatorID varchar(255) NOT NULL | ||||
| 
 | ||||
| ALTER TABLE primitems | ||||
| ADD CONSTRAINT DF_primitems_CreatorIDNew | ||||
| DEFAULT '00000000-0000-0000-0000-000000000000'  | ||||
| FOR CreatorID | ||||
| 
 | ||||
| ALTER TABLE primitems ALTER COLUMN CreatorID varchar(255) NOT NULL | ||||
| 
 | ||||
| COMMIT | ||||
| 
 | ||||
| :VERSION 34		  #--------------- Telehub support | ||||
| 
 | ||||
| BEGIN TRANSACTION | ||||
| 
 | ||||
| CREATE TABLE [dbo].[Spawn_Points]( | ||||
| 	[RegionUUID] [uniqueidentifier] NOT NULL, | ||||
| 	[Yaw] [float] NOT NULL, | ||||
| 	[Pitch] [float] NOT NULL, | ||||
| 	[Distance] [float] NOT NULL, | ||||
| 	PRIMARY KEY CLUSTERED  | ||||
| 	( | ||||
| 		[RegionUUID] ASC | ||||
| 	)WITH (PAD_INDEX  = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY] | ||||
| ) ON [PRIMARY] | ||||
| 
 | ||||
| ALTER TABLE regionsettings ADD TelehubObject uniqueidentifier NOT NULL  DEFAULT '00000000-0000-0000-0000-000000000000'; | ||||
| 
 | ||||
| COMMIT | ||||
| 
 | ||||
| :VERSION 35       #---------------- Parcels for sale | ||||
| 
 | ||||
| BEGIN TRANSACTION | ||||
| 
 | ||||
| ALTER TABLE regionsettings ADD parcel_tile_ID uniqueidentifier NOT NULL  DEFAULT '00000000-0000-0000-0000-000000000000'; | ||||
| 
 | ||||
| COMMIT | ||||
| 
 | ||||
| :VERSION 36       #---------------- Timed bans/access | ||||
| 
 | ||||
| BEGIN TRANSACTION | ||||
| 
 | ||||
| ALTER TABLE landaccesslist ADD Expires integer NOT NULL  DEFAULT 0; | ||||
| 
 | ||||
| COMMIT | ||||
| 
 | ||||
|  |  | |||
|  | @ -217,6 +217,8 @@ namespace OpenSim.Data.MySQL | |||
| 
 | ||||
|         public virtual bool Store(T row) | ||||
|         { | ||||
| //            m_log.DebugFormat("[MYSQL GENERIC TABLE HANDLER]: Store(T row) invoked"); | ||||
| 
 | ||||
|             using (MySqlCommand cmd = new MySqlCommand()) | ||||
|             { | ||||
|                 string query = ""; | ||||
|  | @ -271,6 +273,10 @@ namespace OpenSim.Data.MySQL | |||
| 
 | ||||
|         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) | ||||
|                 return false; | ||||
| 
 | ||||
|  |  | |||
|  | @ -26,9 +26,10 @@ | |||
|  */ | ||||
| 
 | ||||
| using System; | ||||
| using System.Data; | ||||
| using System.Reflection; | ||||
| using System.Collections.Generic; | ||||
| using System.Data; | ||||
| using System.Linq; | ||||
| using System.Reflection; | ||||
| using log4net; | ||||
| using MySql.Data.MySqlClient; | ||||
| using OpenMetaverse; | ||||
|  | @ -41,12 +42,12 @@ namespace OpenSim.Data.MySQL | |||
|     /// </summary> | ||||
|     public class MySQLXInventoryData : IXInventoryData | ||||
|     { | ||||
|         private MySQLGenericTableHandler<XInventoryFolder> m_Folders; | ||||
|         private MySqlFolderHandler m_Folders; | ||||
|         private MySqlItemHandler m_Items; | ||||
| 
 | ||||
|         public MySQLXInventoryData(string conn, string realm) | ||||
|         { | ||||
|             m_Folders = new MySQLGenericTableHandler<XInventoryFolder>( | ||||
|             m_Folders = new MySqlFolderHandler( | ||||
|                     conn, "inventoryfolders", "InventoryStore"); | ||||
|             m_Items = new MySqlItemHandler( | ||||
|                     conn, "inventoryitems", String.Empty); | ||||
|  | @ -105,6 +106,11 @@ namespace OpenSim.Data.MySQL | |||
|             return m_Items.MoveItem(id, newParent); | ||||
|         } | ||||
| 
 | ||||
|         public bool MoveFolder(string id, string newParent) | ||||
|         { | ||||
|             return m_Folders.MoveFolder(id, newParent); | ||||
|         } | ||||
| 
 | ||||
|         public XInventoryItem[] GetActiveGestures(UUID principalID) | ||||
|         { | ||||
|             return m_Items.GetActiveGestures(principalID); | ||||
|  | @ -118,22 +124,69 @@ namespace OpenSim.Data.MySQL | |||
| 
 | ||||
|     public class MySqlItemHandler : MySQLGenericTableHandler<XInventoryItem> | ||||
|     { | ||||
| //        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||||
| 
 | ||||
|         public MySqlItemHandler(string c, string t, string 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) | ||||
|         { | ||||
|             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()) | ||||
|             { | ||||
| 
 | ||||
|                 cmd.CommandText = String.Format("update {0} set parentFolderID = ?ParentFolderID where inventoryID = ?InventoryID", m_Realm); | ||||
|                 cmd.Parameters.AddWithValue("?ParentFolderID", newParent); | ||||
|                 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) | ||||
|  | @ -184,6 +237,21 @@ namespace OpenSim.Data.MySQL | |||
|             if (!base.Store(item)) | ||||
|                 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)) | ||||
|             { | ||||
|                 dbcon.Open(); | ||||
|  | @ -193,7 +261,7 @@ namespace OpenSim.Data.MySQL | |||
|                     cmd.Connection = dbcon; | ||||
| 
 | ||||
|                     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 | ||||
|                     { | ||||
|  | @ -205,9 +273,96 @@ namespace OpenSim.Data.MySQL | |||
|                     } | ||||
|                     cmd.Dispose(); | ||||
|                 } | ||||
| 
 | ||||
|                 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; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -28,6 +28,9 @@ | |||
| using System; | ||||
| using System.Collections; | ||||
| using System.Collections.Generic; | ||||
| using System.Reflection; | ||||
| using System.Threading; | ||||
| using log4net; | ||||
| using OpenMetaverse; | ||||
| using OpenSim.Framework; | ||||
| using OpenSim.Data; | ||||
|  | @ -36,12 +39,26 @@ namespace OpenSim.Data.Null | |||
| { | ||||
|     public class NullFriendsData : IFriendsData | ||||
|     { | ||||
| //        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||||
| 
 | ||||
|         private static List<FriendsData> m_Data = new List<FriendsData>(); | ||||
| 
 | ||||
|         public NullFriendsData(string connectionString, string realm) | ||||
|         { | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Clear all friends data | ||||
|         /// </summary> | ||||
|         /// <remarks> | ||||
|         /// This is required by unit tests to clear the static data between test runs. | ||||
|         /// </remarks> | ||||
|         public static void Clear() | ||||
|         { | ||||
|             lock (m_Data) | ||||
|                 m_Data.Clear(); | ||||
|         } | ||||
| 
 | ||||
|         public FriendsData[] GetFriends(UUID principalID) | ||||
|         { | ||||
|             return GetFriends(principalID.ToString()); | ||||
|  | @ -56,20 +73,30 @@ namespace OpenSim.Data.Null | |||
|         /// <returns></returns> | ||||
|         public FriendsData[] GetFriends(string userID) | ||||
|         { | ||||
|             List<FriendsData> lst = m_Data.FindAll(fdata => | ||||
|             lock (m_Data) | ||||
|             { | ||||
|                 return fdata.PrincipalID == userID.ToString(); | ||||
|             }); | ||||
| 
 | ||||
|             if (lst != null) | ||||
|             { | ||||
|                 lst.ForEach(f => | ||||
|                 List<FriendsData> lst = m_Data.FindAll(fdata => | ||||
|                 { | ||||
|                     FriendsData f2 = m_Data.Find(candidateF2 => f.Friend == candidateF2.PrincipalID); | ||||
|                     if (f2 != null) { f.Data["TheirFlags"] = f2.Data["Flags"]; } | ||||
|                     return fdata.PrincipalID == userID.ToString(); | ||||
|                 }); | ||||
| 
 | ||||
|                 return lst.ToArray(); | ||||
|      | ||||
|                 if (lst != null) | ||||
|                 { | ||||
|                     lst.ForEach(f => | ||||
|                     { | ||||
|                         FriendsData f2 = m_Data.Find(candidateF2 => f.Friend == candidateF2.PrincipalID); | ||||
|                         if (f2 != null) | ||||
|                             f.Data["TheirFlags"] = f2.Data["Flags"]; | ||||
|      | ||||
|     //                    m_log.DebugFormat( | ||||
|     //                        "[NULL FRIENDS DATA]: Got {0} {1} {2} for {3}", | ||||
|     //                        f.Friend, f.Data["Flags"], f2 != null ? f.Data["TheirFlags"] : "not found!", f.PrincipalID); | ||||
|                     }); | ||||
|      | ||||
|     //                m_log.DebugFormat("[NULL FRIENDS DATA]: Got {0} friends for {1}", lst.Count, userID); | ||||
|      | ||||
|                     return lst.ToArray(); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             return new FriendsData[0]; | ||||
|  | @ -80,7 +107,11 @@ namespace OpenSim.Data.Null | |||
|             if (data == null) | ||||
|                 return false; | ||||
| 
 | ||||
|             m_Data.Add(data); | ||||
| //            m_log.DebugFormat( | ||||
| //                "[NULL FRIENDS DATA]: Storing {0} {1} {2}", data.PrincipalID, data.Friend, data.Data["Flags"]); | ||||
| 
 | ||||
|             lock (m_Data) | ||||
|                 m_Data.Add(data); | ||||
| 
 | ||||
|             return true; | ||||
|         } | ||||
|  | @ -92,14 +123,21 @@ namespace OpenSim.Data.Null | |||
| 
 | ||||
|         public bool Delete(string userID, string friendID) | ||||
|         { | ||||
|             List<FriendsData> lst = m_Data.FindAll(delegate(FriendsData fdata) { return fdata.PrincipalID == userID.ToString(); }); | ||||
|             if (lst != null) | ||||
|             lock (m_Data) | ||||
|             { | ||||
|                 FriendsData friend = lst.Find(delegate(FriendsData fdata) { return fdata.Friend == friendID; }); | ||||
|                 if (friendID != null) | ||||
|                 List<FriendsData> lst = m_Data.FindAll(delegate(FriendsData fdata) { return fdata.PrincipalID == userID.ToString(); }); | ||||
|                 if (lst != null) | ||||
|                 { | ||||
|                     m_Data.Remove(friend); | ||||
|                     return true; | ||||
|                     FriendsData friend = lst.Find(delegate(FriendsData fdata) { return fdata.Friend == friendID; }); | ||||
|                     if (friendID != null) | ||||
|                     { | ||||
|     //                    m_log.DebugFormat( | ||||
|     //                        "[NULL FRIENDS DATA]: Deleting friend {0} {1} for {2}", | ||||
|     //                        friend.Friend, friend.Data["Flags"], friend.PrincipalID); | ||||
|      | ||||
|                         m_Data.Remove(friend); | ||||
|                         return true; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|  |  | |||
|  | @ -110,7 +110,6 @@ namespace OpenSim.Data.Null | |||
|             return false; | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         public PresenceData[] Get(string field, string data) | ||||
|         { | ||||
|             if (Instance != this) | ||||
|  |  | |||
|  | @ -47,7 +47,7 @@ namespace OpenSim.Data.SQLite | |||
|     { | ||||
| //        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||||
| 
 | ||||
|         private SQLiteGenericTableHandler<XInventoryFolder> m_Folders; | ||||
|         private SqliteFolderHandler m_Folders; | ||||
|         private SqliteItemHandler m_Items; | ||||
| 
 | ||||
|         public SQLiteXInventoryData(string conn, string realm) | ||||
|  | @ -55,7 +55,7 @@ namespace OpenSim.Data.SQLite | |||
|             if (Util.IsWindows()) | ||||
|                 Util.LoadArchSpecificWindowsDll("sqlite3.dll"); | ||||
| 
 | ||||
|             m_Folders = new SQLiteGenericTableHandler<XInventoryFolder>( | ||||
|             m_Folders = new SqliteFolderHandler( | ||||
|                     conn, "inventoryfolders", "XInventoryStore"); | ||||
|             m_Items = new SqliteItemHandler( | ||||
|                     conn, "inventoryitems", String.Empty); | ||||
|  | @ -114,6 +114,11 @@ namespace OpenSim.Data.SQLite | |||
|             return m_Items.MoveItem(id, newParent); | ||||
|         } | ||||
| 
 | ||||
|         public bool MoveFolder(string id, string newParent) | ||||
|         { | ||||
|             return m_Folders.MoveFolder(id, newParent); | ||||
|         } | ||||
| 
 | ||||
|         public XInventoryItem[] GetActiveGestures(UUID principalID) | ||||
|         { | ||||
|             return m_Items.GetActiveGestures(principalID); | ||||
|  | @ -177,4 +182,23 @@ namespace OpenSim.Data.SQLite | |||
|             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.RegionLocY = 0; | ||||
| 
 | ||||
|             Scene scene = new Scene(regionInfo); | ||||
| 
 | ||||
|             SceneObjectPart sop = new SceneObjectPart(); | ||||
|             sop.Name = name; | ||||
|             sop.Description = name; | ||||
|  | @ -1082,7 +1080,7 @@ namespace OpenSim.Data.Tests | |||
|             sop.Shape = PrimitiveBaseShape.Default; | ||||
| 
 | ||||
|             SceneObjectGroup sog = new SceneObjectGroup(sop); | ||||
|             sog.SetScene(scene); | ||||
| //            sog.SetScene(scene); | ||||
| 
 | ||||
|             return sog; | ||||
|         } | ||||
|  |  | |||
|  | @ -98,6 +98,11 @@ namespace OpenSim.Framework | |||
|         /// </summary> | ||||
|         public string lastname; | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Agent's full name. | ||||
|         /// </summary> | ||||
|         public string Name { get { return string.Format("{0} {1}", firstname, lastname); } } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Random Unique GUID for this session.  Client gets this at login and it's | ||||
|         /// only supposed to be disclosed over secure channels | ||||
|  |  | |||
|  | @ -199,7 +199,14 @@ namespace OpenSim.Framework | |||
|     // | ||||
|     public class Cache | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// Must only be accessed under lock. | ||||
|         /// </summary> | ||||
|         private List<CacheItemBase> m_Index = new List<CacheItemBase>(); | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Must only be accessed under m_Index lock. | ||||
|         /// </summary> | ||||
|         private Dictionary<string, CacheItemBase> m_Lookup = | ||||
|             new Dictionary<string, CacheItemBase>(); | ||||
| 
 | ||||
|  | @ -320,19 +327,19 @@ namespace OpenSim.Framework | |||
|             { | ||||
|                 if (m_Lookup.ContainsKey(index)) | ||||
|                     item = m_Lookup[index]; | ||||
|             } | ||||
| 
 | ||||
|             if (item == null) | ||||
|             { | ||||
|                 if (item == null) | ||||
|                 { | ||||
|                     Expire(true); | ||||
|                     return null; | ||||
|                 } | ||||
|      | ||||
|                 item.hits++; | ||||
|                 item.lastUsed = DateTime.Now; | ||||
|      | ||||
|                 Expire(true); | ||||
|                 return null; | ||||
|             } | ||||
| 
 | ||||
|             item.hits++; | ||||
|             item.lastUsed = DateTime.Now; | ||||
| 
 | ||||
|             Expire(true); | ||||
| 
 | ||||
|             return item; | ||||
|         } | ||||
| 
 | ||||
|  | @ -385,7 +392,10 @@ namespace OpenSim.Framework | |||
|         // | ||||
|         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) | ||||
|                 return null; | ||||
|  | @ -419,12 +429,12 @@ namespace OpenSim.Framework | |||
|         public virtual void Store(string index, Object data, Type container, | ||||
|                 Object[] parameters) | ||||
|         { | ||||
|             Expire(false); | ||||
| 
 | ||||
|             CacheItemBase item; | ||||
| 
 | ||||
|             lock (m_Index) | ||||
|             { | ||||
|                 Expire(false); | ||||
| 
 | ||||
|                 if (m_Index.Contains(new CacheItemBase(index))) | ||||
|                 { | ||||
|                     if ((m_Flags & CacheFlags.AllowUpdate) != 0) | ||||
|  | @ -450,9 +460,17 @@ namespace OpenSim.Framework | |||
|                 m_Index.Add(item); | ||||
|                 m_Lookup[index] = item; | ||||
|             } | ||||
| 
 | ||||
|             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) | ||||
|         { | ||||
|             if (getting && (m_Strategy == CacheStrategy.Aggressive)) | ||||
|  | @ -475,12 +493,10 @@ namespace OpenSim.Framework | |||
| 
 | ||||
|             switch (m_Strategy) | ||||
|             { | ||||
|             case CacheStrategy.Aggressive: | ||||
|                 if (Count < Size) | ||||
|                     return; | ||||
|                 case CacheStrategy.Aggressive: | ||||
|                     if (Count < Size) | ||||
|                         return; | ||||
| 
 | ||||
|                 lock (m_Index) | ||||
|                 { | ||||
|                     m_Index.Sort(new SortLRU()); | ||||
|                     m_Index.Reverse(); | ||||
| 
 | ||||
|  | @ -490,7 +506,7 @@ namespace OpenSim.Framework | |||
| 
 | ||||
|                     ExpireDelegate doExpire = OnExpire; | ||||
| 
 | ||||
|                 if (doExpire != null) | ||||
|                     if (doExpire != null) | ||||
|                     { | ||||
|                         List<CacheItemBase> candidates = | ||||
|                                 m_Index.GetRange(target, Count - target); | ||||
|  | @ -513,27 +529,34 @@ namespace OpenSim.Framework | |||
|                         foreach (CacheItemBase item in m_Index) | ||||
|                             m_Lookup[item.uuid] = item; | ||||
|                     } | ||||
|                 } | ||||
|                 break; | ||||
|             default: | ||||
|                 break; | ||||
| 
 | ||||
|                     break; | ||||
| 
 | ||||
|                     default: | ||||
|                         break; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public void Invalidate(string uuid) | ||||
|         { | ||||
|             if (!m_Lookup.ContainsKey(uuid)) | ||||
|                 return; | ||||
|             lock (m_Index) | ||||
|             { | ||||
|                 if (!m_Lookup.ContainsKey(uuid)) | ||||
|                     return; | ||||
| 
 | ||||
|             CacheItemBase item = m_Lookup[uuid]; | ||||
|             m_Lookup.Remove(uuid); | ||||
|             m_Index.Remove(item); | ||||
|                 CacheItemBase item = m_Lookup[uuid]; | ||||
|                 m_Lookup.Remove(uuid); | ||||
|                 m_Index.Remove(item); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public void Clear() | ||||
|         { | ||||
|             m_Index.Clear(); | ||||
|             m_Lookup.Clear(); | ||||
|             lock (m_Index) | ||||
|             { | ||||
|                 m_Index.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.Collections.Generic; | ||||
| using System.Diagnostics; | ||||
| using System.Linq; | ||||
| using System.Reflection; | ||||
| using System.Text; | ||||
| using System.Text.RegularExpressions; | ||||
|  | @ -40,6 +41,8 @@ namespace OpenSim.Framework.Console | |||
| { | ||||
|     public class Commands : ICommands | ||||
|     { | ||||
| //        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Encapsulates a command that can be invoked from the console | ||||
|         /// </summary> | ||||
|  | @ -76,12 +79,23 @@ namespace OpenSim.Framework.Console | |||
|             public List<CommandDelegate> fn; | ||||
|         } | ||||
| 
 | ||||
|         public const string GeneralHelpText | ||||
|             = "To enter an argument that contains spaces, surround the argument with double quotes.\nFor example, show object name \"My long object name\"\n"; | ||||
| 
 | ||||
|         public const string ItemHelpText | ||||
|                 = "For more information, type 'help <item>' where <item> is one of the following:"; | ||||
| 
 | ||||
|         /// <value> | ||||
|         /// Commands organized by keyword in a tree | ||||
|         /// </value> | ||||
|         private Dictionary<string, object> tree = | ||||
|                 new Dictionary<string, object>(); | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Commands organized by module | ||||
|         /// </summary> | ||||
|         private Dictionary<string, List<CommandInfo>> m_modulesCommands = new Dictionary<string, List<CommandInfo>>(); | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Get help for the given help string | ||||
|         /// </summary> | ||||
|  | @ -98,8 +112,10 @@ namespace OpenSim.Framework.Console | |||
|             // General help | ||||
|             if (helpParts.Count == 0) | ||||
|             { | ||||
|                 help.AddRange(CollectHelp(tree)); | ||||
|                 help.Sort(); | ||||
|                 help.Add(""); // Will become a newline. | ||||
|                 help.Add(GeneralHelpText); | ||||
|                 help.Add(ItemHelpText); | ||||
|                 help.AddRange(CollectModulesHelp(tree)); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|  | @ -118,6 +134,13 @@ namespace OpenSim.Framework.Console | |||
|         { | ||||
|             string originalHelpRequest = string.Join(" ", helpParts.ToArray()); | ||||
|             List<string> help = new List<string>(); | ||||
| 
 | ||||
|             // Check modules first to see if we just need to display a list of those commands | ||||
|             if (TryCollectModuleHelp(originalHelpRequest, help)) | ||||
|             { | ||||
|                 help.Insert(0, ItemHelpText); | ||||
|                 return help; | ||||
|             } | ||||
|              | ||||
|             Dictionary<string, object> dict = tree; | ||||
|             while (helpParts.Count > 0) | ||||
|  | @ -161,25 +184,63 @@ namespace OpenSim.Framework.Console | |||
|             return help; | ||||
|         } | ||||
| 
 | ||||
|         private List<string> CollectHelp(Dictionary<string, object> dict) | ||||
|         /// <summary> | ||||
|         /// Try to collect help for the given module if that module exists. | ||||
|         /// </summary> | ||||
|         /// <param name="moduleName"></param> | ||||
|         /// <param name="helpText">/param> | ||||
|         /// <returns>true if there was the module existed, false otherwise.</returns> | ||||
|         private bool TryCollectModuleHelp(string moduleName, List<string> helpText) | ||||
|         { | ||||
|             List<string> result = new List<string>(); | ||||
| 
 | ||||
|             foreach (KeyValuePair<string, object> kvp in dict) | ||||
|             lock (m_modulesCommands) | ||||
|             { | ||||
|                 if (kvp.Value is Dictionary<string, Object>) | ||||
|                 foreach (string key in m_modulesCommands.Keys) | ||||
|                 { | ||||
|                     result.AddRange(CollectHelp((Dictionary<string, Object>)kvp.Value)); | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     if (((CommandInfo)kvp.Value).long_help != String.Empty) | ||||
|                         result.Add(((CommandInfo)kvp.Value).help_text+" - "+ | ||||
|                                 ((CommandInfo)kvp.Value).long_help); | ||||
|                     // Allow topic help requests to succeed whether they are upper or lowercase. | ||||
|                     if (moduleName.ToLower() == key.ToLower()) | ||||
|                     { | ||||
|                         List<CommandInfo> commands = m_modulesCommands[key]; | ||||
|                         var ourHelpText = commands.ConvertAll(c => string.Format("{0} - {1}", c.help_text, c.long_help)); | ||||
|                         ourHelpText.Sort(); | ||||
|                         helpText.AddRange(ourHelpText); | ||||
| 
 | ||||
|                         return true; | ||||
|                     } | ||||
|                 } | ||||
| 
 | ||||
|                 return false; | ||||
|             } | ||||
|             return result; | ||||
|         } | ||||
| 
 | ||||
|         private List<string> CollectModulesHelp(Dictionary<string, object> dict) | ||||
|         { | ||||
|             lock (m_modulesCommands) | ||||
|             { | ||||
|                 List<string> helpText = new List<string>(m_modulesCommands.Keys); | ||||
|                 helpText.Sort(); | ||||
|                 return helpText; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
| //        private List<string> CollectHelp(Dictionary<string, object> dict) | ||||
| //        { | ||||
| //            List<string> result = new List<string>(); | ||||
| // | ||||
| //            foreach (KeyValuePair<string, object> kvp in dict) | ||||
| //            { | ||||
| //                if (kvp.Value is Dictionary<string, Object>) | ||||
| //                { | ||||
| //                    result.AddRange(CollectHelp((Dictionary<string, Object>)kvp.Value)); | ||||
| //                } | ||||
| //                else | ||||
| //                { | ||||
| //                    if (((CommandInfo)kvp.Value).long_help != String.Empty) | ||||
| //                        result.Add(((CommandInfo)kvp.Value).help_text+" - "+ | ||||
| //                                ((CommandInfo)kvp.Value).long_help); | ||||
| //                } | ||||
| //            } | ||||
| //            return result; | ||||
| //        } | ||||
|          | ||||
|         /// <summary> | ||||
|         /// Add a command to those which can be invoked from the console. | ||||
|  | @ -212,21 +273,19 @@ namespace OpenSim.Framework.Console | |||
| 
 | ||||
|             Dictionary<string, Object> current = tree; | ||||
|              | ||||
|             foreach (string s in parts) | ||||
|             foreach (string part in parts) | ||||
|             { | ||||
|                 if (current.ContainsKey(s)) | ||||
|                 if (current.ContainsKey(part)) | ||||
|                 { | ||||
|                     if (current[s] is Dictionary<string, Object>) | ||||
|                     { | ||||
|                         current = (Dictionary<string, Object>)current[s]; | ||||
|                     } | ||||
|                     if (current[part] is Dictionary<string, Object>) | ||||
|                         current = (Dictionary<string, Object>)current[part]; | ||||
|                     else | ||||
|                         return; | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     current[s] = new Dictionary<string, Object>(); | ||||
|                     current = (Dictionary<string, Object>)current[s]; | ||||
|                     current[part] = new Dictionary<string, Object>(); | ||||
|                     current = (Dictionary<string, Object>)current[part]; | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|  | @ -250,6 +309,24 @@ namespace OpenSim.Framework.Console | |||
|             info.fn = new List<CommandDelegate>(); | ||||
|             info.fn.Add(fn); | ||||
|             current[String.Empty] = info; | ||||
| 
 | ||||
|             // Now add command to modules dictionary | ||||
|             lock (m_modulesCommands) | ||||
|             { | ||||
|                 List<CommandInfo> commands; | ||||
|                 if (m_modulesCommands.ContainsKey(module)) | ||||
|                 { | ||||
|                     commands = m_modulesCommands[module]; | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     commands = new List<CommandInfo>(); | ||||
|                     m_modulesCommands[module] = commands; | ||||
|                 } | ||||
| 
 | ||||
| //                m_log.DebugFormat("[COMMAND CONSOLE]: Adding to category {0} command {1}", module, command); | ||||
|                 commands.Add(info); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public string[] FindNextOption(string[] cmd, bool term) | ||||
|  | @ -607,8 +684,9 @@ namespace OpenSim.Framework.Console | |||
|         { | ||||
|             Commands = new Commands(); | ||||
| 
 | ||||
|             Commands.AddCommand("console", false, "help", "help [<command>]",  | ||||
|                     "Get general command list or more detailed help on a specific command", Help); | ||||
|             Commands.AddCommand( | ||||
|                 "Help", false, "help", "help [<item>]", | ||||
|                 "Display help on a particular command or on a list of commands in a category", Help); | ||||
|         } | ||||
| 
 | ||||
|         private void Help(string module, string[] cmd) | ||||
|  |  | |||
|  | @ -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.Collections.Generic; | ||||
| using System.Text; | ||||
| using System.Xml; | ||||
| 
 | ||||
| namespace OpenSim.Framework.Console | ||||
| { | ||||
|  | @ -37,28 +38,42 @@ namespace OpenSim.Framework.Console | |||
|     /// Don't use this except for Unit Testing or you're in for a world of hurt when the  | ||||
|     /// sim gets to ReadLine | ||||
|     /// </summary> | ||||
|     public class MockConsole : CommandConsole | ||||
|     public class MockConsole : ICommandConsole | ||||
|     { | ||||
|         public MockConsole(string defaultPrompt) : base(defaultPrompt) | ||||
|         { | ||||
|         } | ||||
|         public override void Output(string text) | ||||
|         { | ||||
|         } | ||||
|         public override void Output(string text, string level) | ||||
|         { | ||||
|         } | ||||
|         private MockCommands m_commands = new MockCommands(); | ||||
| 
 | ||||
|         public override string ReadLine(string p, bool isCommand, bool e) | ||||
|         { | ||||
|             //Thread.CurrentThread.Join(1000); | ||||
|             return string.Empty; | ||||
|         } | ||||
|         public override void UnlockOutput() | ||||
|         { | ||||
|         } | ||||
|         public override void LockOutput() | ||||
|         { | ||||
|         } | ||||
|         public ICommands Commands { get { return m_commands; } } | ||||
| 
 | ||||
|         public void Prompt() {} | ||||
| 
 | ||||
|         public void RunCommand(string cmd) {} | ||||
| 
 | ||||
|         public string ReadLine(string p, bool isCommand, bool e) { return ""; } | ||||
| 
 | ||||
|         public object ConsoleScene { get { return null; } } | ||||
| 
 | ||||
|         public void Output(string text, string level) {} | ||||
|         public void Output(string text) {} | ||||
|         public void OutputFormat(string format, params object[] components) {} | ||||
| 
 | ||||
|         public string CmdPrompt(string p) { return ""; } | ||||
|         public string CmdPrompt(string p, string def) { return ""; } | ||||
|         public string CmdPrompt(string p, List<char> excludedCharacters) { return ""; } | ||||
|         public string CmdPrompt(string p, string def, List<char> excludedCharacters) { return ""; } | ||||
| 
 | ||||
|         public string CmdPrompt(string prompt, string defaultresponse, List<string> options) { return ""; } | ||||
| 
 | ||||
|         public string PasswdPrompt(string p) { return ""; } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|     public class MockCommands : ICommands | ||||
|     { | ||||
|         public void FromXml(XmlElement root, CommandDelegate fn) {} | ||||
|         public List<string> GetHelp(string[] cmd) { return null; } | ||||
|         public void AddCommand(string module, bool shared, string command, string help, string longhelp, CommandDelegate fn) {} | ||||
|         public void AddCommand(string module, bool shared, string command, string help, string longhelp, string descriptivehelp, CommandDelegate fn) {} | ||||
|         public string[] FindNextOption(string[] cmd, bool term) { return null; } | ||||
|         public string[] Resolve(string[] cmd) { return null; } | ||||
|         public XmlElement GetXml(XmlDocument doc) { return null; } | ||||
|     } | ||||
| } | ||||
|  | @ -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 FriendActionDelegate( | ||||
|         IClientAPI remoteClient, UUID agentID, UUID transactionID, List<UUID> callingCardFolders); | ||||
|         IClientAPI remoteClient, UUID transactionID, List<UUID> callingCardFolders); | ||||
| 
 | ||||
|     public delegate void FriendshipTermination(IClientAPI remoteClient, UUID agentID, UUID ExID); | ||||
|     public delegate void FriendshipTermination(IClientAPI remoteClient, UUID ExID); | ||||
| 
 | ||||
|     public delegate void MoneyTransferRequest( | ||||
|         UUID sourceID, UUID destID, int amount, int transactionType, string description); | ||||
|  | @ -458,7 +458,7 @@ namespace OpenSim.Framework | |||
|     public delegate void AvatarNotesUpdate(IClientAPI client, UUID targetID, string notes); | ||||
|     public delegate void MuteListRequest(IClientAPI client, uint muteCRC); | ||||
|     public delegate void AvatarInterestUpdate(IClientAPI client, uint wantmask, string wanttext, uint skillsmask, string skillstext, string languages); | ||||
|     public delegate void GrantUserFriendRights(IClientAPI client, UUID requester, UUID target, int rights); | ||||
|     public delegate void GrantUserFriendRights(IClientAPI client, UUID target, int rights); | ||||
|     public delegate void PlacesQuery(UUID QueryID, UUID TransactionID, string QueryText, uint QueryFlags, byte Category, string SimName, IClientAPI client); | ||||
| 
 | ||||
|     public delegate void AgentFOV(IClientAPI client, float verticalAngle); | ||||
|  | @ -710,7 +710,7 @@ namespace OpenSim.Framework | |||
|         /// The scene agent for this client.  This will only be set if the client has an agent in a scene (i.e. if it | ||||
|         /// is connected). | ||||
|         /// </summary> | ||||
|         ISceneAgent SceneAgent { get; } | ||||
|         ISceneAgent SceneAgent { get; set; } | ||||
| 
 | ||||
|         UUID SessionId { get; } | ||||
| 
 | ||||
|  | @ -740,14 +740,21 @@ namespace OpenSim.Framework | |||
|         /// </summary> | ||||
|         string Name { get; } | ||||
| 
 | ||||
|         /// <value> | ||||
|         /// Determines whether the client thread is doing anything or not. | ||||
|         /// </value> | ||||
|         /// <summary> | ||||
|         /// True if the client is active (sending and receiving new UDP messages).  False if the client is being closed. | ||||
|         /// </summary> | ||||
|         bool IsActive { get; set; } | ||||
| 
 | ||||
|         /// <value> | ||||
|         /// Determines whether the client is or has been removed from a given scene | ||||
|         /// </value> | ||||
|         /// <summary> | ||||
|         /// Set if the client is closing due to a logout request | ||||
|         /// </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 SendLogoutPacketWhenClosing { set; } | ||||
|  | @ -1026,7 +1033,21 @@ namespace OpenSim.Framework | |||
| 
 | ||||
|         void InPacket(object NewPack); | ||||
|         void ProcessInPacket(Packet NewPack); | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Close this client | ||||
|         /// </summary> | ||||
|         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); | ||||
|          | ||||
|         /// <summary> | ||||
|  | @ -1347,7 +1368,6 @@ namespace OpenSim.Framework | |||
|         void SendBlueBoxMessage(UUID FromAvatarID, String FromAvatarName, String Message); | ||||
| 
 | ||||
|         void SendLogoutPacket(); | ||||
|         EndPoint GetClientEP(); | ||||
| 
 | ||||
|         // WARNING WARNING WARNING | ||||
|         // | ||||
|  | @ -1408,8 +1428,6 @@ namespace OpenSim.Framework | |||
| 
 | ||||
|         void SendGroupVoteHistory(UUID groupID, UUID transactionID, GroupVoteHistory[] Votes); | ||||
| 
 | ||||
|         void KillEndDone(); | ||||
| 
 | ||||
|         bool AddGenericPacketHandler(string MethodName, GenericMessage handler); | ||||
| 
 | ||||
|         void SendRebakeAvatarTextures(UUID textureID); | ||||
|  |  | |||
|  | @ -40,7 +40,7 @@ namespace OpenSim.Framework | |||
|         /// <summary> | ||||
|         /// Get help for the given help string | ||||
|         /// </summary> | ||||
|         /// <param name="helpParts">Parsed parts of the help string.  If empty then general help is returned.</param> | ||||
|         /// <param name="cmd">Parsed parts of the help string.  If empty then general help is returned.</param> | ||||
|         /// <returns></returns> | ||||
|         List<string> GetHelp(string[] cmd); | ||||
| 
 | ||||
|  |  | |||
|  | @ -71,6 +71,7 @@ namespace OpenSim.Framework | |||
|         bool IsEitherBannedOrRestricted(UUID avatar); | ||||
|         bool IsBannedFromLand(UUID avatar); | ||||
|         bool IsRestrictedFromLand(UUID avatar); | ||||
|         bool IsInLandAccessList(UUID avatar); | ||||
|         void SendLandUpdateToClient(IClientAPI remote_client); | ||||
|         void SendLandUpdateToClient(bool snap_selection, IClientAPI remote_client); | ||||
|         List<LandAccessEntry> CreateAccessListArrayByFlag(AccessList flag); | ||||
|  |  | |||
|  | @ -56,11 +56,29 @@ namespace OpenSim.Framework | |||
| 
 | ||||
|     public interface IScene | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// The name of this scene. | ||||
|         /// </summary> | ||||
|         string Name { get; } | ||||
| 
 | ||||
|         RegionInfo RegionInfo { get; } | ||||
|         RegionStatus RegionStatus { get; set; } | ||||
| 
 | ||||
|         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; } | ||||
| 
 | ||||
|         bool AllowScriptCrossings { get; } | ||||
|  |  | |||
|  | @ -26,6 +26,7 @@ | |||
|  */ | ||||
| 
 | ||||
| using System; | ||||
| using OpenMetaverse; | ||||
| 
 | ||||
| namespace OpenSim.Framework | ||||
| { | ||||
|  | @ -71,5 +72,11 @@ namespace OpenSim.Framework | |||
|         /// This includes scene object data and the appearance data of other avatars. | ||||
|         /// </remarks> | ||||
|         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.AllowDeedToGroup | (uint) ParcelFlags.AllowTerraform | | ||||
|                                 (uint) ParcelFlags.CreateObjects | (uint) ParcelFlags.AllowOtherScripts | | ||||
|                                 (uint) ParcelFlags.SoundLocal; | ||||
|                                 (uint) ParcelFlags.SoundLocal | (uint) ParcelFlags.AllowVoiceChat; | ||||
| 
 | ||||
|         private byte _landingType = 0; | ||||
|         private string _name = "Your Parcel"; | ||||
|  |  | |||
|  | @ -99,8 +99,13 @@ namespace OpenSim.Framework | |||
|                     } | ||||
|                     else | ||||
|                     { | ||||
|                         item = oldHeadNext.Item; | ||||
|                         item = oldHeadNext.Item;                        | ||||
|                         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() | ||||
|         { | ||||
|             // ugly | ||||
|             T item; | ||||
|             while(count > 0) | ||||
|                 Dequeue(out item); | ||||
|             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() | ||||
|             { | ||||
|                 this.value = default(T); | ||||
|                 if (this.handle != null) | ||||
|                 { | ||||
|                     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) | ||||
|             { | ||||
|                 Set(this.items[this.size], index); | ||||
|                 this.items[this.size].ClearRef(); | ||||
|                 if (!BubbleUp(index)) | ||||
|                     BubbleDown(index); | ||||
|             } | ||||
|  |  | |||
|  | @ -44,8 +44,6 @@ namespace OpenSim.Framework.Serialization.External | |||
|     { | ||||
|         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 | ||||
|             = new Dictionary<string, Action<LandData, XmlTextReader>>(); | ||||
| 
 | ||||
|  | @ -163,7 +161,7 @@ namespace OpenSim.Framework.Serialization.External | |||
|         /// <exception cref="System.Xml.XmlException"></exception> | ||||
|         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> | ||||
|  |  | |||
|  | @ -38,8 +38,6 @@ namespace OpenSim.Framework.Serialization.External | |||
|     /// </summary> | ||||
|     public class RegionSettingsSerializer | ||||
|     { | ||||
|         protected static ASCIIEncoding m_asciiEncoding = new ASCIIEncoding(); | ||||
|          | ||||
|         /// <summary> | ||||
|         /// Deserialize settings | ||||
|         /// </summary> | ||||
|  | @ -48,7 +46,7 @@ namespace OpenSim.Framework.Serialization.External | |||
|         /// <exception cref="System.Xml.XmlException"></exception> | ||||
|         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> | ||||
|  |  | |||
|  | @ -53,8 +53,6 @@ namespace OpenSim.Framework.Serialization | |||
|             TYPE_CONTIGUOUS_FILE = 8, | ||||
|         } | ||||
| 
 | ||||
|         protected static ASCIIEncoding m_asciiEncoding = new ASCIIEncoding(); | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Binary reader for the underlying stream | ||||
|         /// </summary> | ||||
|  | @ -120,13 +118,13 @@ namespace OpenSim.Framework.Serialization | |||
|             if (header[156] == (byte)'L') | ||||
|             { | ||||
|                 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); | ||||
|                 header = m_br.ReadBytes(512); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 tarHeader.FilePath = m_asciiEncoding.GetString(header, 0, 100); | ||||
|                 tarHeader.FilePath = Encoding.ASCII.GetString(header, 0, 100); | ||||
|                 tarHeader.FilePath = tarHeader.FilePath.Trim(m_nullCharArray); | ||||
|                 //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 | ||||
|             // 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; | ||||
| 
 | ||||
|  |  | |||
|  | @ -41,9 +41,6 @@ namespace OpenSim.Framework.Serialization | |||
|     { | ||||
| //        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> | ||||
|         /// Binary writer for the underlying stream | ||||
|         /// </summary> | ||||
|  | @ -74,7 +71,7 @@ namespace OpenSim.Framework.Serialization | |||
|         /// <param name="data"></param> | ||||
|         public void WriteFile(string filePath, string data) | ||||
|         { | ||||
|             WriteFile(filePath, m_utf8Encoding.GetBytes(data)); | ||||
|             WriteFile(filePath, Util.UTF8NoBomEncoding.GetBytes(data)); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|  | @ -85,7 +82,7 @@ namespace OpenSim.Framework.Serialization | |||
|         public void WriteFile(string filePath, byte[] data) | ||||
|         { | ||||
|             if (filePath.Length > 100) | ||||
|                 WriteEntry("././@LongLink", m_asciiEncoding.GetBytes(filePath), 'L'); | ||||
|                 WriteEntry("././@LongLink", Encoding.ASCII.GetBytes(filePath), 'L'); | ||||
| 
 | ||||
|             char fileType; | ||||
| 
 | ||||
|  | @ -137,7 +134,7 @@ namespace OpenSim.Framework.Serialization | |||
|                 oString = "0" + oString; | ||||
|             } | ||||
| 
 | ||||
|             byte[] oBytes = m_asciiEncoding.GetBytes(oString); | ||||
|             byte[] oBytes = Encoding.ASCII.GetBytes(oString); | ||||
| 
 | ||||
|             return oBytes; | ||||
|         } | ||||
|  | @ -156,20 +153,20 @@ namespace OpenSim.Framework.Serialization | |||
|             byte[] header = new byte[512]; | ||||
| 
 | ||||
|             // file path field (100) | ||||
|             byte[] nameBytes = m_asciiEncoding.GetBytes(filePath); | ||||
|             byte[] nameBytes = Encoding.ASCII.GetBytes(filePath); | ||||
|             int nameSize = (nameBytes.Length >= 100) ? 100 : nameBytes.Length; | ||||
|             Array.Copy(nameBytes, header, nameSize); | ||||
| 
 | ||||
|             // file mode (8) | ||||
|             byte[] modeBytes = m_asciiEncoding.GetBytes("0000777"); | ||||
|             byte[] modeBytes = Encoding.ASCII.GetBytes("0000777"); | ||||
|             Array.Copy(modeBytes, 0, header, 100, 7); | ||||
| 
 | ||||
|             // owner user id (8) | ||||
|             byte[] ownerIdBytes = m_asciiEncoding.GetBytes("0000764"); | ||||
|             byte[] ownerIdBytes = Encoding.ASCII.GetBytes("0000764"); | ||||
|             Array.Copy(ownerIdBytes, 0, header, 108, 7); | ||||
| 
 | ||||
|             // group user id (8) | ||||
|             byte[] groupIdBytes = m_asciiEncoding.GetBytes("0000764"); | ||||
|             byte[] groupIdBytes = Encoding.ASCII.GetBytes("0000764"); | ||||
|             Array.Copy(groupIdBytes, 0, header, 116, 7); | ||||
| 
 | ||||
|             // file size in bytes (12) | ||||
|  | @ -181,17 +178,17 @@ namespace OpenSim.Framework.Serialization | |||
|             Array.Copy(fileSizeBytes, 0, header, 124, 11); | ||||
| 
 | ||||
|             // last modification time (12) | ||||
|             byte[] lastModTimeBytes = m_asciiEncoding.GetBytes("11017037332"); | ||||
|             byte[] lastModTimeBytes = Encoding.ASCII.GetBytes("11017037332"); | ||||
|             Array.Copy(lastModTimeBytes, 0, header, 136, 11); | ||||
| 
 | ||||
|             // 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(m_asciiEncoding.GetBytes("0000000"), 0, header, 337, 7); | ||||
|             Array.Copy(Encoding.ASCII.GetBytes("0000000"), 0, header, 329, 7); | ||||
|             Array.Copy(Encoding.ASCII.GetBytes("0000000"), 0, header, 337, 7); | ||||
| 
 | ||||
|             // 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; | ||||
|             foreach (byte b in header) | ||||
|  |  | |||
|  | @ -161,43 +161,43 @@ namespace OpenSim.Framework.Servers | |||
|                     Notice(String.Format("Console log level is {0}", m_consoleAppender.Threshold)); | ||||
|                 } | ||||
|                  | ||||
|                 m_console.Commands.AddCommand("base", false, "quit", | ||||
|                 m_console.Commands.AddCommand("General", false, "quit", | ||||
|                         "quit", | ||||
|                         "Quit the application", HandleQuit); | ||||
| 
 | ||||
|                 m_console.Commands.AddCommand("base", false, "shutdown", | ||||
|                 m_console.Commands.AddCommand("General", false, "shutdown", | ||||
|                         "shutdown", | ||||
|                         "Quit the application", HandleQuit); | ||||
| 
 | ||||
|                 m_console.Commands.AddCommand("base", false, "set log level", | ||||
|                 m_console.Commands.AddCommand("General", false, "set log level", | ||||
|                         "set log level <level>", | ||||
|                         "Set the console logging level", HandleLogLevel); | ||||
| 
 | ||||
|                 m_console.Commands.AddCommand("base", false, "show info", | ||||
|                 m_console.Commands.AddCommand("General", false, "show info", | ||||
|                         "show info", | ||||
|                         "Show general information about the server", HandleShow); | ||||
| 
 | ||||
|                 m_console.Commands.AddCommand("base", false, "show stats", | ||||
|                 m_console.Commands.AddCommand("General", false, "show stats", | ||||
|                         "show stats", | ||||
|                         "Show statistics", HandleShow); | ||||
| 
 | ||||
|                 m_console.Commands.AddCommand("base", false, "show threads", | ||||
|                 m_console.Commands.AddCommand("General", false, "show threads", | ||||
|                         "show threads", | ||||
|                         "Show thread status", HandleShow); | ||||
| 
 | ||||
|                 m_console.Commands.AddCommand("base", false, "show uptime", | ||||
|                 m_console.Commands.AddCommand("General", false, "show uptime", | ||||
|                         "show uptime", | ||||
|                         "Show server uptime", HandleShow); | ||||
| 
 | ||||
|                 m_console.Commands.AddCommand("base", false, "show version", | ||||
|                 m_console.Commands.AddCommand("General", false, "show version", | ||||
|                         "show version", | ||||
|                         "Show server version", HandleShow); | ||||
| 
 | ||||
|                 m_console.Commands.AddCommand("base", false, "threads abort", | ||||
|                 m_console.Commands.AddCommand("General", false, "threads abort", | ||||
|                         "threads abort <thread-id>", | ||||
|                         "Abort a managed thread.  Use \"show threads\" to find possible threads.", HandleThreadsAbort); | ||||
| 
 | ||||
|                 m_console.Commands.AddCommand("base", false, "threads show", | ||||
|                 m_console.Commands.AddCommand("General", false, "threads show", | ||||
|                         "threads show", | ||||
|                         "Show thread status.  Synonym for \"show threads\"", | ||||
|                         (string module, string[] args) => Notice(GetThreadsReport())); | ||||
|  | @ -269,15 +269,19 @@ namespace OpenSim.Framework.Servers | |||
|                     t.Priority, | ||||
|                     t.ThreadState); | ||||
| 
 | ||||
|                 sb.Append(Environment.NewLine); | ||||
|                 sb.Append("\n"); | ||||
|             } | ||||
| 
 | ||||
|             int workers = 0, ports = 0, maxWorkers = 0, maxPorts = 0; | ||||
|             ThreadPool.GetAvailableThreads(out workers, out ports); | ||||
|             ThreadPool.GetMaxThreads(out maxWorkers, out maxPorts); | ||||
|             sb.Append("\n"); | ||||
| 
 | ||||
|             sb.Append(Environment.NewLine + "*** ThreadPool threads ***"  + Environment.NewLine); | ||||
|             sb.Append("workers: " + (maxWorkers - workers) + " (" + maxWorkers + "); ports: " + (maxPorts - ports) + " (" + maxPorts + ")" + Environment.NewLine); | ||||
|             // For some reason mono 2.6.7 returns an empty threads set!  Not going to confuse people by reporting | ||||
|             // zero active threads. | ||||
|             int totalThreads = Process.GetCurrentProcess().Threads.Count; | ||||
|             if (totalThreads > 0) | ||||
|                 sb.AppendFormat("Total threads active: {0}\n\n", totalThreads); | ||||
| 
 | ||||
|             sb.Append("Main threadpool (excluding script engine pools)\n"); | ||||
|             sb.Append(Util.GetThreadPoolReport()); | ||||
| 
 | ||||
|             return sb.ToString(); | ||||
|         } | ||||
|  | @ -316,7 +320,9 @@ namespace OpenSim.Framework.Servers | |||
|              | ||||
|             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> | ||||
|  | @ -585,8 +591,8 @@ namespace OpenSim.Framework.Servers | |||
|             { | ||||
|                 string pidstring = System.Diagnostics.Process.GetCurrentProcess().Id.ToString(); | ||||
|                 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.Close(); | ||||
|                 m_pidFile = path; | ||||
|  |  | |||
|  | @ -33,9 +33,9 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
|     { | ||||
|         public abstract Hashtable Handle(string path, Hashtable Request); | ||||
| 
 | ||||
|         protected BaseHTTPHandler(string httpMethod, string path) | ||||
|             : base(httpMethod, path) | ||||
|         { | ||||
|         } | ||||
|         protected BaseHTTPHandler(string httpMethod, string path) : this(httpMethod, path, null, null) {} | ||||
| 
 | ||||
|         protected BaseHTTPHandler(string httpMethod, string path, string name, string description) | ||||
|             : base(httpMethod, path, name, description) {} | ||||
|     } | ||||
| } | ||||
| } | ||||
|  | @ -53,6 +53,8 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
|         private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||||
|         private HttpServerLogWriter httpserverlog = new HttpServerLogWriter(); | ||||
| 
 | ||||
|         public int DebugLevel { get; set; } | ||||
| 
 | ||||
|         private volatile int NotSocketErrors = 0; | ||||
|         public volatile bool HTTPDRunning = false; | ||||
| 
 | ||||
|  | @ -79,11 +81,6 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
| 
 | ||||
|         private PollServiceRequestManager m_PollServiceManager; | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Control the printing of certain debug messages. | ||||
|         /// </summary> | ||||
|         public int DebugLevel { get; set; } | ||||
| 
 | ||||
|         public uint SSLPort | ||||
|         { | ||||
|             get { return m_sslport; } | ||||
|  | @ -156,7 +153,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public List<string>  GetStreamHandlerKeys() | ||||
|         public List<string> GetStreamHandlerKeys() | ||||
|         { | ||||
|             lock (m_streamHandlers) | ||||
|                 return new List<string>(m_streamHandlers.Keys); | ||||
|  | @ -356,7 +353,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
|             } | ||||
|             catch (Exception e) | ||||
|             { | ||||
|                 m_log.ErrorFormat("[BASE HTTP SERVER]: OnRequest() failed with {0}{1}", e.Message, e.StackTrace); | ||||
|                 m_log.Error(String.Format("[BASE HTTP SERVER]: OnRequest() failed: {0} ", e.Message), e); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|  | @ -408,7 +405,12 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
|             string uriString = request.RawUrl; | ||||
| 
 | ||||
| //            string reqnum = "unknown"; | ||||
|             int tickstart = Environment.TickCount; | ||||
|             int requestStartTick = Environment.TickCount; | ||||
| 
 | ||||
|             // Will be adjusted later on. | ||||
|             int requestEndTick = requestStartTick; | ||||
| 
 | ||||
|             IRequestHandler requestHandler = null; | ||||
| 
 | ||||
|             try | ||||
|             { | ||||
|  | @ -431,6 +433,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
|                 { | ||||
|                     if (HandleAgentRequest(agentHandler, request, response)) | ||||
|                     { | ||||
|                         requestEndTick = Environment.TickCount; | ||||
|                         return; | ||||
|                     } | ||||
|                 } | ||||
|  | @ -438,20 +441,14 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
|                 //response.KeepAlive = true; | ||||
|                 response.SendChunked = false; | ||||
| 
 | ||||
|                 IRequestHandler requestHandler; | ||||
| 
 | ||||
|                 string path = request.RawUrl; | ||||
|                 string handlerKey = GetHandlerKey(request.HttpMethod, path); | ||||
|                 byte[] buffer = null; | ||||
| 
 | ||||
|                 if (TryGetStreamHandler(handlerKey, out requestHandler)) | ||||
|                 { | ||||
|                     if (DebugLevel >= 1) | ||||
|                         m_log.DebugFormat( | ||||
|                             "[BASE HTTP SERVER]: Found stream handler for {0} {1}", | ||||
|                             request.HttpMethod, request.Url.PathAndQuery); | ||||
| 
 | ||||
|                     // Okay, so this is bad, but should be considered temporary until everything is IStreamHandler. | ||||
|                     byte[] buffer = null; | ||||
|                     if (DebugLevel >= 3) | ||||
|                         LogIncomingToStreamHandler(request, requestHandler); | ||||
| 
 | ||||
|                     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); | ||||
| 
 | ||||
|                         } | ||||
|                         DoHTTPGruntWork(HTTPRequestHandler.Handle(path, keysvals), response); | ||||
|                         return; | ||||
| 
 | ||||
|                         buffer = DoHTTPGruntWork(HTTPRequestHandler.Handle(path, keysvals), response); | ||||
|                     } | ||||
|                     else | ||||
|                     { | ||||
|  | @ -521,133 +518,93 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
|                             buffer = memoryStream.ToArray(); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     switch (request.ContentType) | ||||
|                     { | ||||
|                         case null: | ||||
|                         case "text/html": | ||||
|      | ||||
|                             if (DebugLevel >= 3) | ||||
|                                 m_log.DebugFormat( | ||||
|                                     "[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}", | ||||
|                                     request.ContentType, request.HttpMethod, request.Url.PathAndQuery); | ||||
|      | ||||
|                             buffer = HandleHTTPRequest(request, response); | ||||
|                             break; | ||||
|      | ||||
|                         case "application/llsd+xml": | ||||
|                         case "application/xml+llsd": | ||||
|                         case "application/llsd+json": | ||||
|      | ||||
|                             if (DebugLevel >= 3) | ||||
|                                 m_log.DebugFormat( | ||||
|                                     "[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}", | ||||
|                                     request.ContentType, request.HttpMethod, request.Url.PathAndQuery); | ||||
|      | ||||
|                             buffer = HandleLLSDRequests(request, response); | ||||
|                             break; | ||||
|      | ||||
|                         case "text/xml": | ||||
|                         case "application/xml": | ||||
|                         case "application/json": | ||||
|                         default: | ||||
|                             //m_log.Info("[Debug BASE HTTP SERVER]: in default handler"); | ||||
|                             // Point of note..  the DoWeHaveA methods check for an EXACT path | ||||
|                             //                        if (request.RawUrl.Contains("/CAPS/EQG")) | ||||
|                             //                        { | ||||
|                             //                            int i = 1; | ||||
|                             //                        } | ||||
|                             //m_log.Info("[Debug BASE HTTP SERVER]: Checking for LLSD Handler"); | ||||
|                             if (DoWeHaveALLSDHandler(request.RawUrl)) | ||||
|                             { | ||||
|                                 if (DebugLevel >= 3) | ||||
|                                     LogIncomingToContentTypeHandler(request); | ||||
|      | ||||
|                                 buffer = HandleLLSDRequests(request, response); | ||||
|                             } | ||||
|     //                        m_log.DebugFormat("[BASE HTTP SERVER]: Checking for HTTP Handler for request {0}", request.RawUrl); | ||||
|                             else if (DoWeHaveAHTTPHandler(request.RawUrl)) | ||||
|                             { | ||||
|                                 if (DebugLevel >= 3) | ||||
|                                     LogIncomingToContentTypeHandler(request); | ||||
|      | ||||
|                                 buffer = HandleHTTPRequest(request, response); | ||||
|                             } | ||||
|                             else | ||||
|                             { | ||||
|                                 if (DebugLevel >= 3) | ||||
|                                     LogIncomingToXmlRpcHandler(request); | ||||
|      | ||||
|                                 // generic login request. | ||||
|                                 buffer = HandleXmlRpcRequests(request, response); | ||||
|                             } | ||||
|      | ||||
|                             break; | ||||
|                     } | ||||
|                 } | ||||
| 
 | ||||
|                     request.InputStream.Close(); | ||||
| 
 | ||||
|                     // HTTP IN support. The script engine takes it from here | ||||
|                     // Nothing to worry about for us. | ||||
|                     // | ||||
|                     if (buffer == null) | ||||
|                         return; | ||||
|                 request.InputStream.Close(); | ||||
| 
 | ||||
|                 if (buffer != null) | ||||
|                 { | ||||
|                     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; | ||||
|                     response.OutputStream.Write(buffer, 0, buffer.Length); | ||||
|                 } | ||||
| 
 | ||||
|                 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); | ||||
|                 // 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; | ||||
| 
 | ||||
|                             HandleLLSDRequests(request, response); | ||||
|                             return; | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|                 response.Send(); | ||||
| 
 | ||||
|                 switch (request.ContentType) | ||||
|                 { | ||||
|                     case null: | ||||
|                     case "text/html": | ||||
|                 //response.OutputStream.Close(); | ||||
| 
 | ||||
|                         if (DebugLevel >= 1) | ||||
|                             m_log.DebugFormat( | ||||
|                                 "[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}", | ||||
|                                 request.ContentType, request.HttpMethod, request.Url.PathAndQuery); | ||||
| 
 | ||||
|                         HandleHTTPRequest(request, response); | ||||
|                         return; | ||||
| 
 | ||||
|                     case "application/llsd+xml": | ||||
|                     case "application/xml+llsd": | ||||
|                     case "application/llsd+json": | ||||
| 
 | ||||
|                         if (DebugLevel >= 1) | ||||
|                             m_log.DebugFormat( | ||||
|                                 "[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}", | ||||
|                                 request.ContentType, request.HttpMethod, request.Url.PathAndQuery); | ||||
| 
 | ||||
|                         HandleLLSDRequests(request, response); | ||||
|                         return; | ||||
| 
 | ||||
|                     case "text/xml": | ||||
|                     case "application/xml": | ||||
|                     case "application/json": | ||||
|                     default: | ||||
|                         //m_log.Info("[Debug BASE HTTP SERVER]: in default handler"); | ||||
|                         // Point of note..  the DoWeHaveA methods check for an EXACT path | ||||
|                         //                        if (request.RawUrl.Contains("/CAPS/EQG")) | ||||
|                         //                        { | ||||
|                         //                            int i = 1; | ||||
|                         //                        } | ||||
|                         //m_log.Info("[Debug BASE HTTP SERVER]: Checking for LLSD Handler"); | ||||
|                         if (DoWeHaveALLSDHandler(request.RawUrl)) | ||||
|                         { | ||||
|                             if (DebugLevel >= 1) | ||||
|                                 m_log.DebugFormat( | ||||
|                                     "[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}", | ||||
|                                     request.ContentType, request.HttpMethod, request.Url.PathAndQuery); | ||||
| 
 | ||||
|                             HandleLLSDRequests(request, response); | ||||
|                             return; | ||||
|                         } | ||||
| 
 | ||||
| //                        m_log.DebugFormat("[BASE HTTP SERVER]: Checking for HTTP Handler for request {0}", request.RawUrl); | ||||
|                         if (DoWeHaveAHTTPHandler(request.RawUrl)) | ||||
|                         { | ||||
|                             if (DebugLevel >= 1) | ||||
|                                 m_log.DebugFormat( | ||||
|                                     "[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}", | ||||
|                                     request.ContentType, request.HttpMethod, request.Url.PathAndQuery); | ||||
| 
 | ||||
|                             HandleHTTPRequest(request, response); | ||||
|                             return; | ||||
|                         } | ||||
| 
 | ||||
|                         if (DebugLevel >= 1) | ||||
|                             m_log.DebugFormat( | ||||
|                                 "[BASE HTTP SERVER]: Assuming a generic XMLRPC request for {0} {1}", | ||||
|                                 request.HttpMethod, request.Url.PathAndQuery); | ||||
| 
 | ||||
|                         // generic login request. | ||||
|                         HandleXmlRpcRequests(request, response); | ||||
| 
 | ||||
|                         return; | ||||
|                 } | ||||
|                 //response.FreeContext(); | ||||
|             } | ||||
|             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 | ||||
|                 // with the minimum first | ||||
|                 m_log.WarnFormat("[BASE HTTP SERVER]: HandleRequest threw {0}.\nNOTE: this may be spurious on Linux", e); | ||||
|                 m_log.Warn(String.Format("[BASE HTTP SERVER]: HandleRequest threw {0}.\nNOTE: this may be spurious on Linux ", e.Message), e); | ||||
|             } | ||||
|             catch (IOException e) | ||||
|             { | ||||
|                 m_log.ErrorFormat("[BASE HTTP SERVER]: HandleRequest() threw ", e); | ||||
|                 m_log.Error(String.Format("[BASE HTTP SERVER]: HandleRequest() threw {0} ", e.Message), e); | ||||
|             } | ||||
|             catch (Exception e) | ||||
|             { | ||||
|                 m_log.ErrorFormat("[BASE HTTP SERVER]: HandleRequest() threw " + e.ToString()); | ||||
|                 m_log.Error(String.Format("[BASE HTTP SERVER]: HandleRequest() threw {0} ", e.Message), e); | ||||
|                 SendHTML500(response); | ||||
|             } | ||||
|             finally | ||||
|             { | ||||
|                 // 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 | ||||
|                 int tickdiff = Environment.TickCount - tickstart; | ||||
|                 // since its just for reporting | ||||
|                 int tickdiff = requestEndTick - requestStartTick; | ||||
|                 if (tickdiff > 3000) | ||||
|                 { | ||||
|                     m_log.InfoFormat( | ||||
|                         "[BASE HTTP SERVER]: slow {0} request for {1} from {2} took {3} ms", requestMethod, uriString, request.RemoteIPEndPoint.ToString(), tickdiff); | ||||
|                         "[BASE HTTP SERVER]: Slow handling of {0} {1} {2} {3} from {4} took {5}ms", | ||||
|                         requestMethod, | ||||
|                         uriString, | ||||
|                         requestHandler != null ? requestHandler.Name : "", | ||||
|                         requestHandler != null ? requestHandler.Description : "", | ||||
|                         request.RemoteIPEndPoint.ToString(), | ||||
|                         tickdiff); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         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> | ||||
|         /// <param name="request"></param> | ||||
|         /// <param name="response"></param> | ||||
|         private void HandleXmlRpcRequests(OSHttpRequest request, OSHttpResponse response) | ||||
|         private byte[] HandleXmlRpcRequests(OSHttpRequest request, OSHttpResponse response) | ||||
|         { | ||||
|             Stream requestStream = request.InputStream; | ||||
| 
 | ||||
|  | @ -816,8 +833,23 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
|             { | ||||
|                 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) | ||||
|  | @ -887,6 +919,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
|                             String.Format("Requested method [{0}] not found", methodName)); | ||||
|                     } | ||||
| 
 | ||||
|                     response.ContentType = "text/xml"; | ||||
|                     responseString = XmlRpcResponseSerializer.Singleton.Serialize(xmlRpcResponse); | ||||
|                 } | ||||
|                 else | ||||
|  | @ -896,82 +929,25 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
|                     response.StatusCode = 404; | ||||
|                     response.StatusDescription = "Not Found"; | ||||
|                     response.ProtocolVersion = "HTTP/1.0"; | ||||
|                     byte[] buf = Encoding.UTF8.GetBytes("Not found"); | ||||
|                     responseString = "Not found"; | ||||
|                     response.KeepAlive = false; | ||||
| 
 | ||||
|                     m_log.ErrorFormat( | ||||
|                         "[BASE HTTP SERVER]: Handler not found for http request {0} {1}", | ||||
|                         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); | ||||
| 
 | ||||
|             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("[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 buffer; | ||||
|         } | ||||
| 
 | ||||
|         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"); | ||||
|             Stream requestStream = request.InputStream; | ||||
|  | @ -1057,34 +1033,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
|             response.ContentEncoding = Encoding.UTF8; | ||||
|             response.KeepAlive = true; | ||||
| 
 | ||||
|             try | ||||
|             { | ||||
|                 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); | ||||
|                 } | ||||
|             } | ||||
|             return buffer; | ||||
|         } | ||||
| 
 | ||||
|         private byte[] BuildLLSDResponse(OSHttpRequest request, OSHttpResponse response, OSD llsdResponse) | ||||
|  | @ -1334,8 +1283,8 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
|                     catch (SocketException f) | ||||
|                     { | ||||
|                         // This has to be here to prevent a Linux/Mono crash | ||||
|                         m_log.WarnFormat( | ||||
|                             "[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux.", f); | ||||
|                         m_log.Warn( | ||||
|                             String.Format("[BASE HTTP SERVER]: XmlRpcRequest issue {0}.\nNOTE: this may be spurious on Linux. ", f.Message), f); | ||||
|                     } | ||||
|                 } | ||||
|                 catch(Exception) | ||||
|  | @ -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( | ||||
| //                "[BASE HTTP SERVER]: HandleHTTPRequest for request to {0}, method {1}", | ||||
|  | @ -1359,15 +1308,14 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
|             { | ||||
|                 case "OPTIONS": | ||||
|                     response.StatusCode = (int)OSHttpStatusCode.SuccessOk; | ||||
|                     return; | ||||
|                     return null; | ||||
| 
 | ||||
|                 default: | ||||
|                     HandleContentVerbs(request, response); | ||||
|                     return; | ||||
|                     return HandleContentVerbs(request, response); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         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); | ||||
| 
 | ||||
|  | @ -1383,6 +1331,8 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
|             // to display the form, or process it. | ||||
|             // a better way would be nifty. | ||||
| 
 | ||||
|             byte[] buffer; | ||||
| 
 | ||||
|             Stream requestStream = request.InputStream; | ||||
| 
 | ||||
|             Encoding encoding = Encoding.UTF8; | ||||
|  | @ -1443,14 +1393,14 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
|                 if (foundHandler) | ||||
|                 { | ||||
|                     Hashtable responsedata1 = requestprocessor(keysvals); | ||||
|                     DoHTTPGruntWork(responsedata1,response); | ||||
|                     buffer = DoHTTPGruntWork(responsedata1,response); | ||||
| 
 | ||||
|                     //SendHTML500(response); | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
| //                    m_log.Warn("[BASE HTTP SERVER]: Handler Not Found"); | ||||
|                     SendHTML404(response, host); | ||||
|                     buffer = SendHTML404(response, host); | ||||
|                 } | ||||
|             } | ||||
|             else | ||||
|  | @ -1460,16 +1410,18 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
|                 if (foundHandler) | ||||
|                 { | ||||
|                     Hashtable responsedata2 = requestprocessor(keysvals); | ||||
|                     DoHTTPGruntWork(responsedata2, response); | ||||
|                     buffer = DoHTTPGruntWork(responsedata2, response); | ||||
| 
 | ||||
|                     //SendHTML500(response); | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
| //                    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) | ||||
|  | @ -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"); | ||||
|             int responsecode = (int)responsedata["int_response_code"]; | ||||
|             string responseString = (string)responsedata["str_response_string"]; | ||||
|             string contentType = (string)responsedata["content_type"]; | ||||
| 
 | ||||
| 
 | ||||
|             if (responsedata.ContainsKey("error_status_text")) | ||||
|             { | ||||
|                 response.StatusDescription = (string)responsedata["error_status_text"]; | ||||
|  | @ -1608,38 +1559,10 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
|             response.ContentLength64 = buffer.Length; | ||||
|             response.ContentEncoding = Encoding.UTF8; | ||||
| 
 | ||||
|             try | ||||
|             { | ||||
|                 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); | ||||
|                 } | ||||
|             } | ||||
|             return buffer; | ||||
|         } | ||||
| 
 | ||||
|         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 | ||||
|             response.StatusCode = 404; | ||||
|  | @ -1652,31 +1575,10 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
|             response.ContentLength64 = buffer.Length; | ||||
|             response.ContentEncoding = Encoding.UTF8; | ||||
| 
 | ||||
|             try | ||||
|             { | ||||
|                 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); | ||||
|                 } | ||||
|             } | ||||
|             return buffer; | ||||
|         } | ||||
| 
 | ||||
|         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 | ||||
|             response.StatusCode = (int)OSHttpStatusCode.SuccessOk; | ||||
|  | @ -1688,28 +1590,8 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
|             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("[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); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             return buffer; | ||||
|         } | ||||
| 
 | ||||
|         public void Start() | ||||
|  | @ -1719,6 +1601,9 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
| 
 | ||||
|         private void StartHTTP() | ||||
|         { | ||||
|             m_log.InfoFormat( | ||||
|                 "[BASE HTTP SERVER]: Starting {0} server on port {1}", UseSSL ? "HTTPS" : "HTTP", Port); | ||||
| 
 | ||||
|             try | ||||
|             { | ||||
|                 //m_httpListener = new HttpListener(); | ||||
|  | @ -1786,7 +1671,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
| 
 | ||||
|         public void httpServerException(object source, Exception exception) | ||||
|         { | ||||
|             m_log.ErrorFormat("[BASE HTTP SERVER]: {0} had an exception {1}", source.ToString(), exception.ToString()); | ||||
|             m_log.Error(String.Format("[BASE HTTP SERVER]: {0} had an exception: {1} ", source.ToString(), exception.Message), exception); | ||||
|            /* | ||||
|             if (HTTPDRunning)// && NotSocketErrors > 5) | ||||
|             { | ||||
|  |  | |||
|  | @ -45,8 +45,16 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
| 
 | ||||
|         private readonly string m_path; | ||||
| 
 | ||||
|         protected BaseRequestHandler(string httpMethod, string path) | ||||
|         public string Name { get; private set; } | ||||
| 
 | ||||
|         public string Description { get; private set; } | ||||
| 
 | ||||
|         protected BaseRequestHandler(string httpMethod, string path) : this(httpMethod, path, null, null) {} | ||||
| 
 | ||||
|         protected BaseRequestHandler(string httpMethod, string path, string name, string description) | ||||
|         { | ||||
|             Name = name; | ||||
|             Description = description; | ||||
|             m_httpMethod = httpMethod; | ||||
|             m_path = path; | ||||
|         } | ||||
|  |  | |||
|  | @ -34,8 +34,9 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
|         public abstract byte[] Handle(string path, Stream request, | ||||
|                                       IOSHttpRequest httpRequest, IOSHttpResponse httpResponse); | ||||
| 
 | ||||
|         protected BaseStreamHandler(string httpMethod, string path) : base(httpMethod, path) | ||||
|         { | ||||
|         } | ||||
|         protected BaseStreamHandler(string httpMethod, string path) : this(httpMethod, path, null, null) {} | ||||
| 
 | ||||
|         protected BaseStreamHandler(string httpMethod, string path, string name, string description) | ||||
|             : base(httpMethod, path, name, description) {} | ||||
|     } | ||||
| } | ||||
| } | ||||
|  | @ -36,6 +36,15 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
|     { | ||||
|         private BinaryMethod m_method; | ||||
| 
 | ||||
|         public BinaryStreamHandler(string httpMethod, string path, BinaryMethod binaryMethod) | ||||
|             : this(httpMethod, path, binaryMethod, null, null) {} | ||||
| 
 | ||||
|         public BinaryStreamHandler(string httpMethod, string path, BinaryMethod binaryMethod, string name, string description) | ||||
|             : base(httpMethod, path, name, description) | ||||
|         { | ||||
|             m_method = binaryMethod; | ||||
|         } | ||||
| 
 | ||||
|         public override byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) | ||||
|         { | ||||
|             byte[] data = ReadFully(request); | ||||
|  | @ -45,12 +54,6 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
|             return Encoding.UTF8.GetBytes(responseString); | ||||
|         } | ||||
| 
 | ||||
|         public BinaryStreamHandler(string httpMethod, string path, BinaryMethod binaryMethod) | ||||
|             : base(httpMethod, path) | ||||
|         { | ||||
|             m_method = binaryMethod; | ||||
|         } | ||||
| 
 | ||||
|         private static byte[] ReadFully(Stream stream) | ||||
|         { | ||||
|             byte[] buffer = new byte[1024]; | ||||
|  | @ -70,4 +73,4 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| } | ||||
|  | @ -128,11 +128,5 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
|         /// <param name="value">string containing the header field | ||||
|         /// value</param> | ||||
|         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 | ||||
|     { | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Name for this handler. | ||||
|         /// </summary> | ||||
|         /// <remarks> | ||||
|         /// Used for diagnostics.  The path doesn't always describe what the handler does.  Can be null if none | ||||
|         /// specified. | ||||
|         /// </remarks> | ||||
|         string Name { get; } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Description for this handler. | ||||
|         /// </summary> | ||||
|         /// <remarks> | ||||
|         /// Used for diagnostics.  The path doesn't always describe what the handler does.  Can be null if none | ||||
|         /// specified. | ||||
|         /// </remarks> | ||||
|         string Description { get; } | ||||
| 
 | ||||
|         // Return response content type | ||||
|         string ContentType { get; } | ||||
| 
 | ||||
|  | @ -58,4 +77,4 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
|     { | ||||
|         Hashtable Handle(string path, Hashtable request); | ||||
|     } | ||||
| } | ||||
| } | ||||
|  | @ -321,13 +321,12 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
|         { | ||||
|             _httpResponse.Body.Flush(); | ||||
|             _httpResponse.Send(); | ||||
|              | ||||
|         } | ||||
| 
 | ||||
|         public void FreeContext() | ||||
|         { | ||||
|             if (_httpClientContext != null) | ||||
|                 _httpClientContext.Close(); | ||||
|         } | ||||
|          | ||||
|     } | ||||
| } | ||||
|  | @ -28,6 +28,7 @@ | |||
| using System; | ||||
| using System.Collections; | ||||
| using OpenMetaverse; | ||||
| 
 | ||||
| namespace OpenSim.Framework.Servers.HttpServer | ||||
| { | ||||
|     public delegate void RequestMethod(UUID requestID, Hashtable request); | ||||
|  | @ -44,7 +45,11 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
|         public NoEventsMethod NoEvents; | ||||
|         public RequestMethod Request; | ||||
|         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; | ||||
|             HasEvents = pHasEvents; | ||||
|  | @ -53,4 +58,4 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
|             Id = pId; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| } | ||||
|  | @ -31,7 +31,6 @@ using OpenMetaverse; | |||
| 
 | ||||
| namespace OpenSim.Framework.Servers.HttpServer | ||||
| { | ||||
| 
 | ||||
|     public class PollServiceHttpRequest | ||||
|     { | ||||
|         public readonly PollServiceEventArgs PollServiceArgs; | ||||
|  | @ -39,7 +38,9 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
|         public readonly IHttpRequest Request; | ||||
|         public readonly int RequestTime; | ||||
|         public readonly UUID RequestID; | ||||
|         public PollServiceHttpRequest(PollServiceEventArgs pPollServiceArgs, IHttpClientContext pHttpContext, IHttpRequest pRequest) | ||||
| 
 | ||||
|         public PollServiceHttpRequest( | ||||
|             PollServiceEventArgs pPollServiceArgs, IHttpClientContext pHttpContext, IHttpRequest pRequest) | ||||
|         { | ||||
|             PollServiceArgs = pPollServiceArgs; | ||||
|             HttpContext = pHttpContext; | ||||
|  | @ -48,4 +49,4 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
|             RequestID = UUID.Random(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| } | ||||
|  | @ -66,6 +66,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
|                         ThreadPriority.Normal, | ||||
|                         false, | ||||
|                         true, | ||||
|                         null, | ||||
|                         int.MaxValue); | ||||
|             } | ||||
| 
 | ||||
|  | @ -75,6 +76,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
|                 ThreadPriority.Normal, | ||||
|                 false, | ||||
|                 true, | ||||
|                 null, | ||||
|                 1000 * 60 * 10); | ||||
|         } | ||||
| 
 | ||||
|  | @ -138,9 +140,8 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
|             foreach (object o in m_requests) | ||||
|             { | ||||
|                 PollServiceHttpRequest req = (PollServiceHttpRequest) o; | ||||
|                 m_server.DoHTTPGruntWork( | ||||
|                     req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id), | ||||
|                     new OSHttpResponse(new HttpResponse(req.HttpContext, req.Request), req.HttpContext)); | ||||
|                 PollServiceWorkerThread.DoHTTPGruntWork( | ||||
|                     m_server, req, req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id)); | ||||
|             } | ||||
| 
 | ||||
|             m_requests.Clear(); | ||||
|  | @ -149,6 +150,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
|             { | ||||
|                 t.Abort(); | ||||
|             } | ||||
|              | ||||
|             m_running = false; | ||||
|         } | ||||
|     } | ||||
|  |  | |||
|  | @ -90,15 +90,16 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
|                         } | ||||
| 
 | ||||
|                         Hashtable responsedata = req.PollServiceArgs.GetEvents(req.RequestID, req.PollServiceArgs.Id, str.ReadToEnd()); | ||||
|                         m_server.DoHTTPGruntWork(responsedata, | ||||
|                                                  new OSHttpResponse(new HttpResponse(req.HttpContext, req.Request),req.HttpContext)); | ||||
|                         DoHTTPGruntWork(m_server, req, responsedata); | ||||
|                     } | ||||
|                     else | ||||
|                     { | ||||
|                         if ((Environment.TickCount - req.RequestTime) > m_timeout) | ||||
|                         { | ||||
|                             m_server.DoHTTPGruntWork(req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id), | ||||
|                                                      new OSHttpResponse(new HttpResponse(req.HttpContext, req.Request),req.HttpContext)); | ||||
|                             DoHTTPGruntWork( | ||||
|                                 m_server, | ||||
|                                 req, | ||||
|                                 req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id)); | ||||
|                         } | ||||
|                         else | ||||
|                         { | ||||
|  | @ -119,5 +120,45 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
|         { | ||||
|             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; | ||||
| 
 | ||||
|         public RestDeserialiseHandler(string httpMethod, string path, RestDeserialiseMethod<TRequest, TResponse> method) | ||||
|             : base(httpMethod, path) | ||||
|             : this(httpMethod, path, method, null, null) {} | ||||
| 
 | ||||
|         public RestDeserialiseHandler( | ||||
|             string httpMethod, string path, RestDeserialiseMethod<TRequest, TResponse> method, string name, string description) | ||||
|             : base(httpMethod, path, name, description) | ||||
|         { | ||||
|             m_method = method; | ||||
|         } | ||||
|  |  | |||
|  | @ -38,19 +38,25 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
|             get { return m_dhttpMethod; } | ||||
|         } | ||||
| 
 | ||||
|         public override Hashtable Handle(string path, Hashtable request) | ||||
|         { | ||||
| 
 | ||||
|             string param = GetParam(path); | ||||
|             request.Add("param", param); | ||||
|             request.Add("path", path); | ||||
|             return m_dhttpMethod(request); | ||||
|         } | ||||
| 
 | ||||
|         public RestHTTPHandler(string httpMethod, string path, GenericHTTPMethod dhttpMethod) | ||||
|             : base(httpMethod, path) | ||||
|         { | ||||
|             m_dhttpMethod = dhttpMethod; | ||||
|         } | ||||
| 
 | ||||
|         public RestHTTPHandler( | ||||
|             string httpMethod, string path, GenericHTTPMethod dhttpMethod, string name, string description) | ||||
|             : base(httpMethod, path, name, description) | ||||
|         { | ||||
|             m_dhttpMethod = dhttpMethod; | ||||
|         } | ||||
| 
 | ||||
|         public override Hashtable Handle(string path, Hashtable request) | ||||
|         { | ||||
|             string param = GetParam(path); | ||||
|             request.Add("param", param); | ||||
|             request.Add("path", path); | ||||
|             return m_dhttpMethod(request); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -39,6 +39,15 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
|             get { return m_restMethod; } | ||||
|         } | ||||
| 
 | ||||
|         public RestStreamHandler(string httpMethod, string path, RestMethod restMethod) | ||||
|             : this(httpMethod, path, restMethod, null, null) {} | ||||
| 
 | ||||
|         public RestStreamHandler(string httpMethod, string path, RestMethod restMethod, string name, string description) | ||||
|             : base(httpMethod, path, name, description) | ||||
|         { | ||||
|             m_restMethod = restMethod; | ||||
|         } | ||||
| 
 | ||||
|         public override byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) | ||||
|         { | ||||
|             Encoding encoding = Encoding.UTF8; | ||||
|  | @ -52,10 +61,5 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
| 
 | ||||
|             return Encoding.UTF8.GetBytes(responseString); | ||||
|         } | ||||
| 
 | ||||
|         public RestStreamHandler(string httpMethod, string path, RestMethod restMethod) : base(httpMethod, path) | ||||
|         { | ||||
|             m_restMethod = restMethod; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -25,57 +25,262 @@ | |||
|  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
|  */ | ||||
| 
 | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Reflection; | ||||
| using System.Net; | ||||
| using System.Text; | ||||
| using log4net; | ||||
| using OpenSim.Framework; | ||||
| using OpenSim.Framework.Console; | ||||
| using OpenSim.Framework.Servers.HttpServer; | ||||
| 
 | ||||
| namespace OpenSim.Framework.Servers | ||||
| { | ||||
|     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 Dictionary<uint, BaseHttpServer> m_Servers = | ||||
|                 new Dictionary<uint, BaseHttpServer>(); | ||||
|         private static Dictionary<uint, BaseHttpServer> m_Servers = 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 | ||||
|         { | ||||
|             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; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public static IHttpServer GetHttpServer(uint port) | ||||
|         /// <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 | ||||
|         { | ||||
|             return GetHttpServer(port,null); | ||||
|             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) | ||||
|         { | ||||
|             m_Servers.Add(server.Port, 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) | ||||
|         { | ||||
|             return GetHttpServer(port, null); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Get the default http server, an http server for a specific port | ||||
|         /// 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) | ||||
|         { | ||||
|             if (port == 0) | ||||
|                 return Instance; | ||||
|              | ||||
|             if (instance != null && port == Instance.Port) | ||||
|                 return Instance; | ||||
| 
 | ||||
|             if (m_Servers.ContainsKey(port)) | ||||
|             lock (m_Servers) | ||||
|             { | ||||
|                 if (m_Servers.ContainsKey(port)) | ||||
|                     return m_Servers[port]; | ||||
| 
 | ||||
|                 m_Servers[port] = new BaseHttpServer(port); | ||||
| 
 | ||||
|                 if (ipaddr != null) | ||||
|                     m_Servers[port].ListenIPAddress = ipaddr; | ||||
| 
 | ||||
|                 m_Servers[port].Start(); | ||||
| 
 | ||||
|                 return m_Servers[port]; | ||||
| 
 | ||||
|             m_Servers[port] = new BaseHttpServer(port); | ||||
| 
 | ||||
|             if (ipaddr != null) | ||||
|                 m_Servers[port].ListenIPAddress = ipaddr; | ||||
| 
 | ||||
|             m_log.InfoFormat("[MAIN HTTP SERVER]: Starting main http server on port {0}", port); | ||||
|             m_Servers[port].Start(); | ||||
| 
 | ||||
|             return m_Servers[port]; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| } | ||||
|  | @ -30,7 +30,7 @@ namespace OpenSim | |||
|     public class VersionInfo | ||||
|     { | ||||
|         private const string VERSION_NUMBER = "0.7.3"; | ||||
|         private const Flavour VERSION_FLAVOUR = Flavour.Dev; | ||||
|         private const Flavour VERSION_FLAVOUR = Flavour.Extended; | ||||
| 
 | ||||
|         public enum Flavour | ||||
|         { | ||||
|  | @ -39,7 +39,8 @@ namespace OpenSim | |||
|             RC1, | ||||
|             RC2, | ||||
|             Release, | ||||
|             Post_Fixes | ||||
|             Post_Fixes, | ||||
|             Extended | ||||
|         } | ||||
| 
 | ||||
|         public static string Version | ||||
|  |  | |||
|  | @ -26,8 +26,8 @@ | |||
|  */ | ||||
| 
 | ||||
| using System; | ||||
| using System.Diagnostics; | ||||
| using System.Text; | ||||
| 
 | ||||
| using OpenMetaverse; | ||||
| using OpenMetaverse.StructuredData; | ||||
| 
 | ||||
|  | @ -44,10 +44,18 @@ namespace OpenSim.Framework.Statistics | |||
|             StringBuilder sb = new StringBuilder(Environment.NewLine); | ||||
|             sb.Append("MEMORY STATISTICS"); | ||||
|             sb.Append(Environment.NewLine); | ||||
|             sb.Append( | ||||
|                 string.Format( | ||||
|                     "Allocated to OpenSim : {0} MB" + Environment.NewLine, | ||||
|                     Math.Round(GC.GetTotalMemory(false) / 1024.0 / 1024.0))); | ||||
| 
 | ||||
|             sb.AppendFormat( | ||||
|                 "Allocated to OpenSim objects: {0} MB\n", | ||||
|                 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(); | ||||
|         } | ||||
|  |  | |||
|  | @ -34,14 +34,12 @@ namespace OpenSim.Framework.Statistics | |||
|     { | ||||
|         private static AssetStatsCollector assetStats; | ||||
|         private static UserStatsCollector userStats; | ||||
|         private static SimExtraStatsCollector simExtraStats; | ||||
|         private static SimExtraStatsCollector simExtraStats = new SimExtraStatsCollector(); | ||||
| 
 | ||||
|         public static AssetStatsCollector AssetStats { get { return assetStats; } } | ||||
|         public static UserStatsCollector UserStats { get { return userStats; } } | ||||
|         public static SimExtraStatsCollector SimExtraStats { get { return simExtraStats; } } | ||||
| 
 | ||||
|         private StatsManager() {} | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Start collecting statistics related to assets. | ||||
|         /// Should only be called once. | ||||
|  | @ -63,16 +61,5 @@ namespace OpenSim.Framework.Statistics | |||
| 
 | ||||
|             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 Random randomClass = new Random(); | ||||
| 
 | ||||
|         // Get a list of invalid file characters (OS dependent) | ||||
|         private static string regexInvalidFileChars = "[" + new String(Path.GetInvalidFileNameChars()) + "]"; | ||||
|         private static string regexInvalidPathChars = "[" + new String(Path.GetInvalidPathChars()) + "]"; | ||||
|         private static object XferLock = new object(); | ||||
|         /// <summary>Thread pool used for Util.FireAndForget if | ||||
|         /// FireAndForgetMethod.SmartThreadPool is used</summary> | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Thread pool used for Util.FireAndForget if FireAndForgetMethod.SmartThreadPool is used | ||||
|         /// </summary> | ||||
|         private static SmartThreadPool m_ThreadPool; | ||||
| 
 | ||||
|         // Unix-epoch starts at January 1st 1970, 00:00:00 UTC. And all our times in the server are (or at least should be) in UTC. | ||||
|  | @ -144,8 +147,8 @@ namespace OpenSim.Framework | |||
|             return lerp(y, lerp(x, a, b), lerp(x, c, d)); | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         public static Encoding UTF8 = Encoding.UTF8; | ||||
|         public static Encoding UTF8NoBomEncoding = new UTF8Encoding(false); | ||||
| 
 | ||||
|         /// <value> | ||||
|         /// 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) | ||||
|         { | ||||
|             return SendXmlRpcCommand(url, methodName, args); | ||||
|  | @ -1234,8 +1269,7 @@ namespace OpenSim.Framework | |||
| 
 | ||||
|         public static string Base64ToString(string str) | ||||
|         { | ||||
|             UTF8Encoding encoder = new UTF8Encoding(); | ||||
|             Decoder utf8Decode = encoder.GetDecoder(); | ||||
|             Decoder utf8Decode = Encoding.UTF8.GetDecoder(); | ||||
| 
 | ||||
|             byte[] todecode_byte = Convert.FromBase64String(str); | ||||
|             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) | ||||
|         { | ||||
|             object[] array = (object[])o; | ||||
|  | @ -1696,6 +1785,20 @@ namespace OpenSim.Framework | |||
|         } | ||||
|         const Int32 EnvironmentTickCountMask = 0x3fffffff; | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Environment.TickCount is an int but it counts all 32 bits so it goes positive | ||||
|         /// and negative every 24.9 days. Subtracts the passed value (previously fetched by | ||||
|         /// 'EnvironmentTickCount()') and accounts for any wrapping. | ||||
|         /// </summary> | ||||
|         /// <param name="newValue"></param> | ||||
|         /// <param name="prevValue"></param> | ||||
|         /// <returns>subtraction of passed prevValue from current Environment.TickCount</returns> | ||||
|         public static Int32 EnvironmentTickCountSubtract(Int32 newValue, Int32 prevValue) | ||||
|         { | ||||
|             Int32 diff = newValue - prevValue; | ||||
|             return (diff >= 0) ? diff : (diff + EnvironmentTickCountMask + 1); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Environment.TickCount is an int but it counts all 32 bits so it goes positive | ||||
|         /// and negative every 24.9 days. Subtracts the passed value (previously fetched by | ||||
|  | @ -1704,8 +1807,7 @@ namespace OpenSim.Framework | |||
|         /// <returns>subtraction of passed prevValue from current Environment.TickCount</returns> | ||||
|         public static Int32 EnvironmentTickCountSubtract(Int32 prevValue) | ||||
|         { | ||||
|             Int32 diff = EnvironmentTickCount() - prevValue; | ||||
|             return (diff >= 0) ? diff : (diff + EnvironmentTickCountMask + 1); | ||||
|             return EnvironmentTickCountSubtract(EnvironmentTickCount(), prevValue); | ||||
|         } | ||||
| 
 | ||||
|         // Returns value of Tick Count A - TickCount B accounting for wrapping of TickCount | ||||
|  |  | |||
|  | @ -41,8 +41,8 @@ namespace OpenSim.Framework | |||
|         /// <summary>Timer interval in milliseconds for the watchdog timer</summary> | ||||
|         const double WATCHDOG_INTERVAL_MS = 2500.0d; | ||||
| 
 | ||||
|         /// <summary>Maximum timeout in milliseconds before a thread is considered dead</summary> | ||||
|         const int WATCHDOG_TIMEOUT_MS = 5000; | ||||
|         /// <summary>Default timeout in milliseconds before a thread is considered dead</summary> | ||||
|         public const int DEFAULT_WATCHDOG_TIMEOUT_MS = 5000; | ||||
| 
 | ||||
|         [System.Diagnostics.DebuggerDisplay("{Thread.Name}")] | ||||
|         public class ThreadWatchdogInfo | ||||
|  | @ -58,7 +58,7 @@ namespace OpenSim.Framework | |||
|             public int FirstTick { get; private set; } | ||||
| 
 | ||||
|             /// <summary> | ||||
|             /// First time this heartbeat update was invoked | ||||
|             /// Last time this heartbeat update was invoked | ||||
|             /// </summary> | ||||
|             public int LastTick { get; set; } | ||||
| 
 | ||||
|  | @ -77,6 +77,11 @@ namespace OpenSim.Framework | |||
|             /// </summary> | ||||
|             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) | ||||
|             { | ||||
|                 Thread = thread; | ||||
|  | @ -87,27 +92,33 @@ namespace OpenSim.Framework | |||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// This event is called whenever a tracked thread is stopped or | ||||
|         /// has not called UpdateThread() in time | ||||
|         /// </summary> | ||||
|         /// <param name="thread">The thread that has been identified as dead</param> | ||||
|         /// <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; | ||||
|         /// This event is called whenever a tracked thread is | ||||
|         /// stopped or has not called UpdateThread() in time< | ||||
|         /// /summary> | ||||
|         public static event Action<ThreadWatchdogInfo> OnWatchdogTimeout; | ||||
| 
 | ||||
|         private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); | ||||
|         private static Dictionary<int, ThreadWatchdogInfo> m_threads; | ||||
|         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() | ||||
|         { | ||||
|             m_threads = new Dictionary<int, ThreadWatchdogInfo>(); | ||||
|             m_watchdogTimer = new System.Timers.Timer(WATCHDOG_INTERVAL_MS); | ||||
|             m_watchdogTimer.AutoReset = false; | ||||
|             m_watchdogTimer.Elapsed += WatchdogTimerElapsed; | ||||
| 
 | ||||
|             // Set now so we don't get alerted on the first run | ||||
|             LastWatchdogThreadTick = Environment.TickCount & Int32.MaxValue; | ||||
| 
 | ||||
|             m_watchdogTimer.Start(); | ||||
|         } | ||||
| 
 | ||||
|  | @ -123,7 +134,7 @@ namespace OpenSim.Framework | |||
|         public static Thread StartThread( | ||||
|             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> | ||||
|  | @ -135,17 +146,24 @@ namespace OpenSim.Framework | |||
|         /// <param name="isBackground">True to run this thread as a background | ||||
|         /// thread, otherwise false</param> | ||||
|         /// <param name="alarmIfTimeout">Trigger an alarm function is we have timed out</param> | ||||
|         /// <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> | ||||
|         /// <returns>The newly created Thread object</returns> | ||||
|         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.Name = name; | ||||
|             thread.Priority = priority; | ||||
|             thread.IsBackground = isBackground; | ||||
|              | ||||
|             ThreadWatchdogInfo twi = new ThreadWatchdogInfo(thread, timeout) { AlarmIfTimeout = alarmIfTimeout }; | ||||
|             ThreadWatchdogInfo twi | ||||
|                 = new ThreadWatchdogInfo(thread, timeout) | ||||
|                     { AlarmIfTimeout = alarmIfTimeout, AlarmMethod = alarmMethod }; | ||||
| 
 | ||||
|             m_log.DebugFormat( | ||||
|                 "[WATCHDOG]: Started tracking thread {0}, ID {1}", twi.Thread.Name, twi.Thread.ManagedThreadId); | ||||
|  | @ -258,7 +276,17 @@ namespace OpenSim.Framework | |||
|         /// <param name="e"></param> | ||||
|         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) | ||||
|             { | ||||
|  | @ -266,8 +294,6 @@ namespace OpenSim.Framework | |||
| 
 | ||||
|                 lock (m_threads) | ||||
|                 { | ||||
|                     int now = Environment.TickCount & Int32.MaxValue; | ||||
| 
 | ||||
|                     foreach (ThreadWatchdogInfo threadInfo in m_threads.Values) | ||||
|                     { | ||||
|                         if (threadInfo.Thread.ThreadState == ThreadState.Stopped) | ||||
|  | @ -296,9 +322,12 @@ namespace OpenSim.Framework | |||
| 
 | ||||
|                 if (callbackInfos != null) | ||||
|                     foreach (ThreadWatchdogInfo callbackInfo in callbackInfos) | ||||
|                         callback(callbackInfo.Thread, callbackInfo.LastTick); | ||||
|                         callback(callbackInfo); | ||||
|             } | ||||
| 
 | ||||
|             if (MemoryWatchdog.Enabled) | ||||
|                 MemoryWatchdog.Update(); | ||||
| 
 | ||||
|             m_watchdogTimer.Start(); | ||||
|         } | ||||
|     } | ||||
|  |  | |||
|  | @ -53,45 +53,36 @@ namespace OpenSim.Framework | |||
|                 LogManager.GetLogger( | ||||
|                 MethodBase.GetCurrentMethod().DeclaringType); | ||||
| 
 | ||||
|         private static int m_requestNumber = 0; | ||||
|         /// <summary> | ||||
|         /// Request number for diagnostic purposes. | ||||
|         /// </summary> | ||||
|         public static int RequestNumber = 0; | ||||
| 
 | ||||
|         // this is the header field used to communicate the local request id | ||||
|         // used for performance and debugging | ||||
|         /// <summary> | ||||
|         /// this is the header field used to communicate the local request id | ||||
|         /// used for performance and debugging | ||||
|         /// </summary> | ||||
|         public const string OSHeaderRequestID = "opensim-request-id"; | ||||
| 
 | ||||
|         // number of milliseconds a call can take before it is considered | ||||
|         // a "long" call for warning & debugging purposes | ||||
|         public const int LongCallTime = 500; | ||||
|         /// <summary> | ||||
|         /// Number of milliseconds a call can take before it is considered | ||||
|         /// a "long" call for warning & debugging purposes | ||||
|         /// </summary> | ||||
|         public const int LongCallTime = 3000; | ||||
| 
 | ||||
| //        /// <summary> | ||||
| //        /// Send LLSD to an HTTP client in application/llsd+json form | ||||
| //        /// </summary> | ||||
| //        /// <param name="response">HTTP response to send the data in</param> | ||||
| //        /// <param name="body">LLSD to send to the client</param> | ||||
| //        public static void SendJSONResponse(OSHttpResponse response, OSDMap body) | ||||
| //        { | ||||
| //            byte[] responseData = Encoding.UTF8.GetBytes(OSDParser.SerializeJsonString(body)); | ||||
| // | ||||
| //            response.ContentEncoding = Encoding.UTF8; | ||||
| //            response.ContentLength = responseData.Length; | ||||
| //            response.ContentType = "application/llsd+json"; | ||||
| //            response.Body.Write(responseData, 0, responseData.Length); | ||||
| //        } | ||||
| // | ||||
| //        /// <summary> | ||||
| //        /// Send LLSD to an HTTP client in application/llsd+xml form | ||||
| //        /// </summary> | ||||
| //        /// <param name="response">HTTP response to send the data in</param> | ||||
| //        /// <param name="body">LLSD to send to the client</param> | ||||
| //        public static void SendXMLResponse(OSHttpResponse response, OSDMap body) | ||||
| //        { | ||||
| //            byte[] responseData = OSDParser.SerializeLLSDXmlBytes(body); | ||||
| // | ||||
| //            response.ContentEncoding = Encoding.UTF8; | ||||
| //            response.ContentLength = responseData.Length; | ||||
| //            response.ContentType = "application/llsd+xml"; | ||||
| //            response.Body.Write(responseData, 0, responseData.Length); | ||||
| //        } | ||||
|         /// <summary> | ||||
|         /// The maximum length of any data logged because of a long request time. | ||||
|         /// </summary> | ||||
|         /// <remarks> | ||||
|         /// This is to truncate any really large post data, such as an asset.  In theory, the first section should | ||||
|         /// give us useful information about the call (which agent it relates to if applicable, etc.). | ||||
|         /// </remarks> | ||||
|         public const int MaxRequestDiagLength = 100; | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Dictionary of end points | ||||
|         /// </summary> | ||||
|         private static Dictionary<string,object> m_endpointSerializer = new Dictionary<string,object>(); | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Make a GET or GET-like request to a web service that returns LLSD | ||||
|  | @ -166,12 +157,14 @@ namespace OpenSim.Framework | |||
|          | ||||
|         public static OSDMap ServiceOSDRequest(string url, OSDMap data, string method, int timeout, bool compressed) | ||||
|         { | ||||
|             int reqnum = m_requestNumber++; | ||||
|             int reqnum = RequestNumber++; | ||||
| 
 | ||||
|             // m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method); | ||||
| 
 | ||||
|             string errorMessage = "unknown error"; | ||||
|             int tickstart = Util.EnvironmentTickCount(); | ||||
|             int tickdata = 0; | ||||
|             string strBuffer = null; | ||||
| 
 | ||||
|             try | ||||
|             { | ||||
|  | @ -186,7 +179,7 @@ namespace OpenSim.Framework | |||
|                 // If there is some input, write it into the request | ||||
|                 if (data != null) | ||||
|                 { | ||||
|                     string strBuffer =  OSDParser.SerializeJsonString(data); | ||||
|                     strBuffer =  OSDParser.SerializeJsonString(data); | ||||
|                     byte[] buffer = System.Text.Encoding.UTF8.GetBytes(strBuffer); | ||||
| 
 | ||||
|                     if (compressed) | ||||
|  | @ -246,14 +239,23 @@ namespace OpenSim.Framework | |||
|             } | ||||
|             finally | ||||
|             { | ||||
|                 // This just dumps a warning for any operation that takes more than 100 ms | ||||
|                 int tickdiff = Util.EnvironmentTickCountSubtract(tickstart); | ||||
|                 if (tickdiff > LongCallTime) | ||||
|                     m_log.DebugFormat("[WEB UTIL]: osd request <{0}> (URI:{1}, METHOD:{2}) took {3}ms overall, {4}ms writing", | ||||
|                                      reqnum,url,method,tickdiff,tickdata); | ||||
|                     m_log.InfoFormat( | ||||
|                         "[OSD REQUEST]: Slow request to <{0}> {1} {2} took {3}ms, {4}ms writing, {5}", | ||||
|                         reqnum, | ||||
|                         method, | ||||
|                         url, | ||||
|                         tickdiff, | ||||
|                         tickdata, | ||||
|                         strBuffer != null | ||||
|                             ? (strBuffer.Length > MaxRequestDiagLength ? strBuffer.Remove(MaxRequestDiagLength) : strBuffer) | ||||
|                             : ""); | ||||
|             } | ||||
|             | ||||
| 	        m_log.DebugFormat("[WEB UTIL]: <{0}> osd request for {1}, method {2} FAILED: {3}", reqnum, url, method, errorMessage);  | ||||
|             m_log.DebugFormat( | ||||
|                 "[WEB UTIL]: <{0}> osd request for {1}, method {2} FAILED: {3}", reqnum, url, method, errorMessage); | ||||
| 
 | ||||
|             return ErrorResponseMap(errorMessage); | ||||
|         } | ||||
| 
 | ||||
|  | @ -314,17 +316,17 @@ namespace OpenSim.Framework | |||
|          | ||||
|         public static OSDMap ServiceFormRequest(string url, NameValueCollection data, int timeout) | ||||
|         { | ||||
|             int reqnum = m_requestNumber++; | ||||
|             int reqnum = RequestNumber++; | ||||
|             string method = (data != null && data["RequestMethod"] != null) ? data["RequestMethod"] : "unknown"; | ||||
|             // m_log.DebugFormat("[WEB UTIL]: <{0}> start form request for {1}, method {2}",reqnum,url,method); | ||||
|              | ||||
|             string errorMessage = "unknown error"; | ||||
|             int tickstart = Util.EnvironmentTickCount(); | ||||
|             int tickdata = 0; | ||||
|             string queryString = null; | ||||
| 
 | ||||
|             try | ||||
|             { | ||||
|                  | ||||
|                 HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url); | ||||
|                 request.Method = "POST"; | ||||
|                 request.Timeout = timeout; | ||||
|  | @ -335,7 +337,7 @@ namespace OpenSim.Framework | |||
|                  | ||||
|                 if (data != null) | ||||
|                 { | ||||
|                     string queryString = BuildQueryString(data); | ||||
|                     queryString = BuildQueryString(data); | ||||
|                     byte[] buffer = System.Text.Encoding.UTF8.GetBytes(queryString); | ||||
|                      | ||||
|                     request.ContentLength = buffer.Length; | ||||
|  | @ -378,11 +380,20 @@ namespace OpenSim.Framework | |||
|             { | ||||
|                 int tickdiff = Util.EnvironmentTickCountSubtract(tickstart); | ||||
|                 if (tickdiff > LongCallTime) | ||||
|                     m_log.InfoFormat("[WEB UTIL]: form request <{0}> (URI:{1}, METHOD:{2}) took {3}ms overall, {4}ms writing", | ||||
|                                      reqnum,url,method,tickdiff,tickdata); | ||||
|                     m_log.InfoFormat( | ||||
|                         "[SERVICE FORM]: Slow request to <{0}> {1} {2} took {3}ms, {4}ms writing, {5}", | ||||
|                         reqnum, | ||||
|                         method, | ||||
|                         url, | ||||
|                         tickdiff, | ||||
|                         tickdata, | ||||
|                         queryString != null | ||||
|                             ? (queryString.Length > MaxRequestDiagLength) ? queryString.Remove(MaxRequestDiagLength) : queryString | ||||
|                             : ""); | ||||
|             } | ||||
| 
 | ||||
|             m_log.WarnFormat("[WEB UTIL]: <{0}> form request failed: {1}",reqnum,errorMessage); | ||||
|             m_log.WarnFormat("[SERVICE FORM]: <{0}> form request to {1} failed: {2}", reqnum, url, errorMessage); | ||||
| 
 | ||||
|             return ErrorResponseMap(errorMessage); | ||||
|         } | ||||
| 
 | ||||
|  | @ -655,8 +666,6 @@ namespace OpenSim.Framework | |||
| 
 | ||||
|             return new string[0]; | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     public static class AsynchronousRestObjectRequester | ||||
|  | @ -679,6 +688,12 @@ namespace OpenSim.Framework | |||
|         public static void MakeRequest<TRequest, TResponse>(string verb, | ||||
|                 string requestUrl, TRequest obj, Action<TResponse> action) | ||||
|         { | ||||
|             int reqnum = WebUtil.RequestNumber++; | ||||
|             // m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method); | ||||
| 
 | ||||
|             int tickstart = Util.EnvironmentTickCount(); | ||||
|             int tickdata = 0; | ||||
| 
 | ||||
|             //            m_log.DebugFormat("[ASYNC REQUEST]: Starting {0} {1}", verb, requestUrl); | ||||
| 
 | ||||
|             Type type = typeof(TRequest); | ||||
|  | @ -689,12 +704,13 @@ namespace OpenSim.Framework | |||
|             XmlSerializer deserializer = new XmlSerializer(typeof(TResponse)); | ||||
| 
 | ||||
|             request.Method = verb; | ||||
|             MemoryStream buffer = null; | ||||
| 
 | ||||
|             if (verb == "POST") | ||||
|             { | ||||
|                 request.ContentType = "text/xml"; | ||||
| 
 | ||||
|                 MemoryStream buffer = new MemoryStream(); | ||||
|                 buffer = new MemoryStream(); | ||||
| 
 | ||||
|                 XmlWriterSettings settings = new XmlWriterSettings(); | ||||
|                 settings.Encoding = Encoding.UTF8; | ||||
|  | @ -716,6 +732,9 @@ namespace OpenSim.Framework | |||
|                     requestStream.Write(buffer.ToArray(), 0, length); | ||||
|                     requestStream.Close(); | ||||
| 
 | ||||
|                     // capture how much time was spent writing | ||||
|                     tickdata = Util.EnvironmentTickCountSubtract(tickstart); | ||||
| 
 | ||||
|                     request.BeginGetResponse(delegate(IAsyncResult ar) | ||||
|                     { | ||||
|                         response = request.EndGetResponse(ar); | ||||
|  | @ -741,83 +760,108 @@ namespace OpenSim.Framework | |||
| 
 | ||||
|                     }, null); | ||||
|                 }, null); | ||||
| 
 | ||||
| 
 | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             request.BeginGetResponse(delegate(IAsyncResult res2) | ||||
|             else | ||||
|             { | ||||
|                 try | ||||
|                 request.BeginGetResponse(delegate(IAsyncResult res2) | ||||
|                 { | ||||
|                     // If the server returns a 404, this appears to trigger a System.Net.WebException even though that isn't | ||||
|                     // documented in MSDN | ||||
|                     response = request.EndGetResponse(res2); | ||||
| 
 | ||||
|                     Stream respStream = null; | ||||
|                     try | ||||
|                     { | ||||
|                         respStream = response.GetResponseStream(); | ||||
|                         deserial = (TResponse)deserializer.Deserialize(respStream); | ||||
|                     } | ||||
|                     catch (System.InvalidOperationException) | ||||
|                     { | ||||
|                     } | ||||
|                     finally | ||||
|                     { | ||||
|                         respStream.Close(); | ||||
|                         response.Close(); | ||||
|                     } | ||||
|                 } | ||||
|                 catch (WebException e) | ||||
|                 { | ||||
|                     if (e.Status == WebExceptionStatus.ProtocolError) | ||||
|                     { | ||||
|                         if (e.Response is HttpWebResponse) | ||||
|                         // If the server returns a 404, this appears to trigger a System.Net.WebException even though that isn't | ||||
|                         // documented in MSDN | ||||
|                         response = request.EndGetResponse(res2); | ||||
|      | ||||
|                         Stream respStream = null; | ||||
|                         try | ||||
|                         { | ||||
|                             HttpWebResponse httpResponse = (HttpWebResponse)e.Response; | ||||
| 
 | ||||
|                             if (httpResponse.StatusCode != HttpStatusCode.NotFound) | ||||
|                             { | ||||
|                                 // We don't appear to be handling any other status codes, so log these feailures to that | ||||
|                                 // people don't spend unnecessary hours hunting phantom bugs. | ||||
|                                 m_log.DebugFormat( | ||||
|                                     "[ASYNC REQUEST]: Request {0} {1} failed with unexpected status code {2}", | ||||
|                                     verb, requestUrl, httpResponse.StatusCode); | ||||
|                             } | ||||
|                             respStream = response.GetResponseStream(); | ||||
|                             deserial = (TResponse)deserializer.Deserialize(respStream); | ||||
|                         } | ||||
|                         catch (System.InvalidOperationException) | ||||
|                         { | ||||
|                         } | ||||
|                         finally | ||||
|                         { | ||||
|                             respStream.Close(); | ||||
|                             response.Close(); | ||||
|                         } | ||||
|                     } | ||||
|                     else | ||||
|                     catch (WebException e) | ||||
|                     { | ||||
|                         m_log.ErrorFormat("[ASYNC REQUEST]: Request {0} {1} failed with status {2} and message {3}", verb, requestUrl, e.Status, e.Message); | ||||
|                         if (e.Status == WebExceptionStatus.ProtocolError) | ||||
|                         { | ||||
|                             if (e.Response is HttpWebResponse) | ||||
|                             { | ||||
|                                 HttpWebResponse httpResponse = (HttpWebResponse)e.Response; | ||||
|      | ||||
|                                 if (httpResponse.StatusCode != HttpStatusCode.NotFound) | ||||
|                                 { | ||||
|                                     // We don't appear to be handling any other status codes, so log these feailures to that | ||||
|                                     // people don't spend unnecessary hours hunting phantom bugs. | ||||
|                                     m_log.DebugFormat( | ||||
|                                         "[ASYNC REQUEST]: Request {0} {1} failed with unexpected status code {2}", | ||||
|                                         verb, requestUrl, httpResponse.StatusCode); | ||||
|                                 } | ||||
|                             } | ||||
|                         } | ||||
|                         else | ||||
|                         { | ||||
|                             m_log.ErrorFormat( | ||||
|                                 "[ASYNC REQUEST]: Request {0} {1} failed with status {2} and message {3}", | ||||
|                                 verb, requestUrl, e.Status, e.Message); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|                 catch (Exception e) | ||||
|                     catch (Exception e) | ||||
|                     { | ||||
|                         m_log.ErrorFormat( | ||||
|                             "[ASYNC REQUEST]: Request {0} {1} failed with exception {2}{3}", | ||||
|                             verb, requestUrl, e.Message, e.StackTrace); | ||||
|                     } | ||||
|      | ||||
|                     //  m_log.DebugFormat("[ASYNC REQUEST]: Received {0}", deserial.ToString()); | ||||
| 
 | ||||
|                     try | ||||
|                     { | ||||
|                         action(deserial); | ||||
|                     } | ||||
|                     catch (Exception e) | ||||
|                     { | ||||
|                         m_log.ErrorFormat( | ||||
|                             "[ASYNC REQUEST]: Request {0} {1} callback failed with exception {2}{3}", | ||||
|                             verb, requestUrl, e.Message, e.StackTrace); | ||||
|                     } | ||||
|      | ||||
|                 }, null); | ||||
|             } | ||||
| 
 | ||||
|             int tickdiff = Util.EnvironmentTickCountSubtract(tickstart); | ||||
|             if (tickdiff > WebUtil.LongCallTime) | ||||
|             { | ||||
|                 string originalRequest = null; | ||||
| 
 | ||||
|                 if (buffer != null) | ||||
|                 { | ||||
|                     m_log.ErrorFormat("[ASYNC REQUEST]: Request {0} {1} failed with exception {2}", verb, requestUrl, e); | ||||
|                     originalRequest = Encoding.UTF8.GetString(buffer.ToArray()); | ||||
| 
 | ||||
|                     if (originalRequest.Length > WebUtil.MaxRequestDiagLength) | ||||
|                         originalRequest = originalRequest.Remove(WebUtil.MaxRequestDiagLength); | ||||
|                 } | ||||
| 
 | ||||
|                 //  m_log.DebugFormat("[ASYNC REQUEST]: Received {0}", deserial.ToString()); | ||||
| 
 | ||||
|                 try | ||||
|                 { | ||||
|                     action(deserial); | ||||
|                 } | ||||
|                 catch (Exception e) | ||||
|                 { | ||||
|                     m_log.ErrorFormat( | ||||
|                         "[ASYNC REQUEST]: Request {0} {1} callback failed with exception {2}", verb, requestUrl, e); | ||||
|                 } | ||||
| 
 | ||||
|             }, null); | ||||
|                 m_log.InfoFormat( | ||||
|                     "[ASYNC REQUEST]: Slow request to <{0}> {1} {2} took {3}ms, {4}ms writing, {5}", | ||||
|                     reqnum, | ||||
|                     verb, | ||||
|                     requestUrl, | ||||
|                     tickdiff, | ||||
|                     tickdata, | ||||
|                     originalRequest); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public static class SynchronousRestFormsRequester | ||||
|     { | ||||
|         private static readonly ILog m_log = | ||||
|                 LogManager.GetLogger( | ||||
|                 MethodBase.GetCurrentMethod().DeclaringType); | ||||
|         private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Perform a synchronous REST request. | ||||
|  | @ -831,6 +875,12 @@ namespace OpenSim.Framework | |||
|         /// the request.  You'll want to make sure you deal with this as they're not uncommon</exception> | ||||
|         public static string MakeRequest(string verb, string requestUrl, string obj) | ||||
|         { | ||||
|             int reqnum = WebUtil.RequestNumber++; | ||||
|             // m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method); | ||||
| 
 | ||||
|             int tickstart = Util.EnvironmentTickCount(); | ||||
|             int tickdata = 0; | ||||
| 
 | ||||
|             WebRequest request = WebRequest.Create(requestUrl); | ||||
|             request.Method = verb; | ||||
|             string respstring = String.Empty; | ||||
|  | @ -859,12 +909,16 @@ namespace OpenSim.Framework | |||
|                     } | ||||
|                     catch (Exception e) | ||||
|                     { | ||||
|                         m_log.DebugFormat("[FORMS]: exception occured on sending request to {0}: " + e.ToString(), requestUrl); | ||||
|                         m_log.DebugFormat( | ||||
|                             "[FORMS]: exception occured {0} {1}: {2}{3}", verb, requestUrl, e.Message, e.StackTrace); | ||||
|                     } | ||||
|                     finally | ||||
|                     { | ||||
|                         if (requestStream != null) | ||||
|                             requestStream.Close(); | ||||
| 
 | ||||
|                         // capture how much time was spent writing | ||||
|                         tickdata = Util.EnvironmentTickCountSubtract(tickstart); | ||||
|                     } | ||||
|                 } | ||||
| 
 | ||||
|  | @ -885,7 +939,9 @@ namespace OpenSim.Framework | |||
|                             } | ||||
|                             catch (Exception e) | ||||
|                             { | ||||
|                                 m_log.DebugFormat("[FORMS]: exception occured on receiving reply " + e.ToString()); | ||||
|                                 m_log.DebugFormat( | ||||
|                                     "[FORMS]: Exception occured on receiving {0} {1}: {2}{3}", | ||||
|                                     verb, requestUrl, e.Message, e.StackTrace); | ||||
|                             } | ||||
|                             finally | ||||
|                             { | ||||
|  | @ -898,9 +954,21 @@ namespace OpenSim.Framework | |||
|                 catch (System.InvalidOperationException) | ||||
|                 { | ||||
|                     // This is what happens when there is invalid XML | ||||
|                     m_log.DebugFormat("[FORMS]: InvalidOperationException on receiving request"); | ||||
|                     m_log.DebugFormat("[FORMS]: InvalidOperationException on receiving {0} {1}", verb, requestUrl); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             int tickdiff = Util.EnvironmentTickCountSubtract(tickstart); | ||||
|             if (tickdiff > WebUtil.LongCallTime) | ||||
|                 m_log.InfoFormat( | ||||
|                     "[FORMS]: Slow request to <{0}> {1} {2} took {3}ms, {4}ms writing, {5}", | ||||
|                     reqnum, | ||||
|                     verb, | ||||
|                     requestUrl, | ||||
|                     tickdiff, | ||||
|                     tickdata, | ||||
|                     obj.Length > WebUtil.MaxRequestDiagLength ? obj.Remove(WebUtil.MaxRequestDiagLength) : obj); | ||||
| 
 | ||||
|             return respstring; | ||||
|         } | ||||
|     } | ||||
|  | @ -923,17 +991,24 @@ namespace OpenSim.Framework | |||
|         /// the request.  You'll want to make sure you deal with this as they're not uncommon</exception> | ||||
|         public static TResponse MakeRequest<TRequest, TResponse>(string verb, string requestUrl, TRequest obj) | ||||
|         { | ||||
|             int reqnum = WebUtil.RequestNumber++; | ||||
|             // m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method); | ||||
| 
 | ||||
|             int tickstart = Util.EnvironmentTickCount(); | ||||
|             int tickdata = 0; | ||||
| 
 | ||||
|             Type type = typeof(TRequest); | ||||
|             TResponse deserial = default(TResponse); | ||||
| 
 | ||||
|             WebRequest request = WebRequest.Create(requestUrl); | ||||
|             request.Method = verb; | ||||
|             MemoryStream buffer = null; | ||||
| 
 | ||||
|             if ((verb == "POST") || (verb == "PUT")) | ||||
|             { | ||||
|                 request.ContentType = "text/xml"; | ||||
| 
 | ||||
|                 MemoryStream buffer = new MemoryStream(); | ||||
|                 buffer = new MemoryStream(); | ||||
| 
 | ||||
|                 XmlWriterSettings settings = new XmlWriterSettings(); | ||||
|                 settings.Encoding = Encoding.UTF8; | ||||
|  | @ -956,13 +1031,19 @@ namespace OpenSim.Framework | |||
|                 } | ||||
|                 catch (Exception e) | ||||
|                 { | ||||
|                     m_log.DebugFormat("[SynchronousRestObjectRequester]: exception in sending data to {0}: {1}", requestUrl, e);  | ||||
|                     m_log.DebugFormat( | ||||
|                         "[SynchronousRestObjectRequester]: Exception in making request {0} {1}: {2}{3}", | ||||
|                         verb, requestUrl, e.Message, e.StackTrace); | ||||
| 
 | ||||
|                     return deserial; | ||||
|                 } | ||||
|                 finally | ||||
|                 { | ||||
|                     if (requestStream != null) | ||||
|                         requestStream.Close(); | ||||
| 
 | ||||
|                     // capture how much time was spent writing | ||||
|                     tickdata = Util.EnvironmentTickCountSubtract(tickstart); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|  | @ -978,7 +1059,11 @@ namespace OpenSim.Framework | |||
|                         respStream.Close(); | ||||
|                     } | ||||
|                     else | ||||
|                         m_log.DebugFormat("[SynchronousRestObjectRequester]: Oops! no content found in response stream from {0} {1}", requestUrl, verb); | ||||
|                     { | ||||
|                         m_log.DebugFormat( | ||||
|                             "[SynchronousRestObjectRequester]: Oops! no content found in response stream from {0} {1}", | ||||
|                             verb, requestUrl); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             catch (WebException e) | ||||
|  | @ -989,17 +1074,44 @@ namespace OpenSim.Framework | |||
|                     return deserial; | ||||
|                 else | ||||
|                     m_log.ErrorFormat( | ||||
|                         "[SynchronousRestObjectRequester]: WebException {0} {1} {2} {3}", | ||||
|                         requestUrl, typeof(TResponse).ToString(), e.Message, e.StackTrace); | ||||
|                         "[SynchronousRestObjectRequester]: WebException for {0} {1} {2}: {3} {4}", | ||||
|                         verb, requestUrl, typeof(TResponse).ToString(), e.Message, e.StackTrace); | ||||
|             } | ||||
|             catch (System.InvalidOperationException) | ||||
|             { | ||||
|                 // This is what happens when there is invalid XML | ||||
|                 m_log.DebugFormat("[SynchronousRestObjectRequester]: Invalid XML {0} {1}", requestUrl, typeof(TResponse).ToString()); | ||||
|                 m_log.DebugFormat( | ||||
|                     "[SynchronousRestObjectRequester]: Invalid XML from {0} {1} {2}", | ||||
|                     verb, requestUrl, typeof(TResponse).ToString()); | ||||
|             } | ||||
|             catch (Exception e) | ||||
|             { | ||||
|                 m_log.DebugFormat("[SynchronousRestObjectRequester]: Exception on response from {0} {1}", requestUrl, e); | ||||
|                 m_log.DebugFormat( | ||||
|                     "[SynchronousRestObjectRequester]: Exception on response from {0} {1}: {2}{3}", | ||||
|                     verb, requestUrl, e.Message, e.StackTrace); | ||||
|             } | ||||
| 
 | ||||
|             int tickdiff = Util.EnvironmentTickCountSubtract(tickstart); | ||||
|             if (tickdiff > WebUtil.LongCallTime) | ||||
|             { | ||||
|                 string originalRequest = null; | ||||
| 
 | ||||
|                 if (buffer != null) | ||||
|                 { | ||||
|                     originalRequest = Encoding.UTF8.GetString(buffer.ToArray()); | ||||
| 
 | ||||
|                     if (originalRequest.Length > WebUtil.MaxRequestDiagLength) | ||||
|                         originalRequest = originalRequest.Remove(WebUtil.MaxRequestDiagLength); | ||||
|                 } | ||||
| 
 | ||||
|                 m_log.InfoFormat( | ||||
|                     "[SynchronousRestObjectRequester]: Slow request to <{0}> {1} {2} took {3}ms, {4}ms writing, {5}", | ||||
|                     reqnum, | ||||
|                     verb, | ||||
|                     requestUrl, | ||||
|                     tickdiff, | ||||
|                     tickdata, | ||||
|                     originalRequest); | ||||
|             } | ||||
| 
 | ||||
|             return deserial; | ||||
|  |  | |||
|  | @ -92,9 +92,14 @@ namespace OpenSim | |||
|                 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); | ||||
| 
 | ||||
|             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 | ||||
|             int workerThreads, iocpThreads; | ||||
|             System.Threading.ThreadPool.GetMaxThreads(out workerThreads, out iocpThreads); | ||||
|  | @ -109,7 +114,6 @@ namespace OpenSim | |||
| 
 | ||||
|             // Check if the system is compatible with OpenSimulator. | ||||
|             // Ensures that the minimum system requirements are met | ||||
|             m_log.Info("Performing compatibility checks... \n"); | ||||
|             string supported = String.Empty; | ||||
|             if (Util.IsEnvironmentSupported(ref supported)) | ||||
|             { | ||||
|  |  | |||
|  | @ -28,12 +28,14 @@ | |||
| using System; | ||||
| using System.Collections; | ||||
| using System.Collections.Generic; | ||||
| using System.Diagnostics; | ||||
| using System.IO; | ||||
| using System.Reflection; | ||||
| using System.Text; | ||||
| using System.Text.RegularExpressions; | ||||
| using System.Timers; | ||||
| using log4net; | ||||
| using NDesk.Options; | ||||
| using Nini.Config; | ||||
| using OpenMetaverse; | ||||
| using OpenSim.Framework; | ||||
|  | @ -138,7 +140,7 @@ namespace OpenSim | |||
|             m_log.Info("===================================================================="); | ||||
|             m_log.Info("========================= STARTING OPENSIM ========================="); | ||||
|             m_log.Info("===================================================================="); | ||||
|              | ||||
| 
 | ||||
|             //m_log.InfoFormat("[OPENSIM MAIN]: GC Is Server GC: {0}", GCSettings.IsServerGC.ToString()); | ||||
|             // http://msdn.microsoft.com/en-us/library/bb384202.aspx | ||||
|             //GCSettings.LatencyMode = GCLatencyMode.Batch; | ||||
|  | @ -194,9 +196,9 @@ namespace OpenSim | |||
|             PrintFileToConsole("startuplogo.txt"); | ||||
| 
 | ||||
|             // 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", | ||||
|                                      new string[] {"change", "region", m_sceneManager.Scenes[0].RegionInfo.RegionName}); | ||||
|                                      new string[] {"change", "region", SceneManager.Scenes[0].RegionInfo.RegionName}); | ||||
|             else | ||||
|                 ChangeSelectedRegion("region", new string[] {"change", "region", "root"}); | ||||
| 
 | ||||
|  | @ -225,12 +227,14 @@ namespace OpenSim | |||
|         /// </summary> | ||||
|         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 the update of all objects on clients", | ||||
|                                           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>]", | ||||
|                                           "Turn on packet debugging", | ||||
|                                             "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", | ||||
|                                           Debug); | ||||
| 
 | ||||
|             m_console.Commands.AddCommand("region", false, "debug http", | ||||
|                                           "debug http <level>", | ||||
|                                           "Turn on inbound http request debugging for everything except the event queue (see debug eq).", | ||||
|                                             "If level >= 2 then the handler used to service the request is logged.\n" | ||||
|                                           + "If level >= 1 then incoming HTTP requests are logged.\n" | ||||
|                                           + "If level <= 0 then no extra http logging is done.\n", | ||||
|                                           Debug); | ||||
|             m_console.Commands.AddCommand("Debug", false, "debug teleport", "debug teleport", "Toggle teleport route debugging", Debug); | ||||
| 
 | ||||
|             m_console.Commands.AddCommand("region", false, "debug teleport", "debug teleport", "Toggle teleport route debugging", Debug); | ||||
| 
 | ||||
|             m_console.Commands.AddCommand("region", false, "debug scene", | ||||
|             m_console.Commands.AddCommand("Debug", false, "debug scene", | ||||
|                                           "debug scene <scripting> <collisions> <physics>", | ||||
|                                           "Turn on scene debugging", Debug); | ||||
| 
 | ||||
|             m_console.Commands.AddCommand("region", false, "change region", | ||||
|             m_console.Commands.AddCommand("General", false, "change region", | ||||
|                                           "change region <region name>", | ||||
|                                           "Change current console region", ChangeSelectedRegion); | ||||
| 
 | ||||
|             m_console.Commands.AddCommand("region", false, "save xml", | ||||
|             m_console.Commands.AddCommand("Archiving", false, "save xml", | ||||
|                                           "save xml", | ||||
|                                           "Save a region's data in XML format", SaveXml); | ||||
| 
 | ||||
|             m_console.Commands.AddCommand("region", false, "save xml2", | ||||
|             m_console.Commands.AddCommand("Archiving", false, "save xml2", | ||||
|                                           "save xml2", | ||||
|                                           "Save a region's data in XML2 format", SaveXml2); | ||||
| 
 | ||||
|             m_console.Commands.AddCommand("region", false, "load xml", | ||||
|             m_console.Commands.AddCommand("Archiving", false, "load xml", | ||||
|                                           "load xml [-newIDs [<x> <y> <z>]]", | ||||
|                                           "Load a region's data from XML format", LoadXml); | ||||
| 
 | ||||
|             m_console.Commands.AddCommand("region", false, "load xml2", | ||||
|             m_console.Commands.AddCommand("Archiving", false, "load xml2", | ||||
|                                           "load xml2", | ||||
|                                           "Load a region's data from XML2 format", LoadXml2); | ||||
| 
 | ||||
|             m_console.Commands.AddCommand("region", false, "save prims xml2", | ||||
|             m_console.Commands.AddCommand("Archiving", false, "save prims xml2", | ||||
|                                           "save prims xml2 [<prim name> <file name>]", | ||||
|                                           "Save named prim to XML2", SavePrimsXml2); | ||||
| 
 | ||||
|             m_console.Commands.AddCommand("region", false, "load oar", | ||||
|             m_console.Commands.AddCommand("Archiving", false, "load oar", | ||||
|                                           "load oar [--merge] [--skip-assets] [<OAR path>]", | ||||
|                                           "Load a region's data from an OAR archive.", | ||||
|                                           "--merge will merge the OAR with the existing scene." + Environment.NewLine | ||||
|  | @ -289,7 +285,7 @@ namespace OpenSim | |||
|                                           + "  If this is not given then the command looks for an OAR named region.oar in the current directory.", | ||||
|                                           LoadOar); | ||||
| 
 | ||||
|             m_console.Commands.AddCommand("region", false, "save oar", | ||||
|             m_console.Commands.AddCommand("Archiving", false, "save oar", | ||||
|                                           //"save oar [-v|--version=<N>] [-p|--profile=<url>] [<OAR path>]", | ||||
|                                           "save oar [-h|--home=<url>] [--noassets] [--publish] [--perm=<permissions>] [<OAR path>]", | ||||
|                                           "Save a region's data to an OAR archive.", | ||||
|  | @ -306,54 +302,53 @@ namespace OpenSim | |||
|                                           + " If this is not given then the oar is saved to region.oar in the current directory.", | ||||
|                                           SaveOar); | ||||
| 
 | ||||
|             m_console.Commands.AddCommand("region", false, "edit scale", | ||||
|             m_console.Commands.AddCommand("Objects", false, "edit scale", | ||||
|                                           "edit scale <name> <x> <y> <z>", | ||||
|                                           "Change the scale of a named prim", HandleEditScale); | ||||
| 
 | ||||
|             m_console.Commands.AddCommand("region", false, "kick user", | ||||
|                                           "kick user <first> <last> [message]", | ||||
|                                           "Kick a user off the simulator", KickUserCommand); | ||||
|             m_console.Commands.AddCommand("Users", false, "kick user", | ||||
|                                           "kick user <first> <last> [--force] [message]", | ||||
|                                           "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 user data for users currently on the region",  | ||||
|                                           "Without the 'full' option, only users actually on the region are shown." | ||||
|                                             + "  With the 'full' option child agents of users in neighbouring regions are also shown.", | ||||
|                                           HandleShow); | ||||
| 
 | ||||
|             m_console.Commands.AddCommand("region", false, "show connections", | ||||
|             m_console.Commands.AddCommand("Comms", false, "show connections", | ||||
|                                           "show connections", | ||||
|                                           "Show connection data", HandleShow); | ||||
| 
 | ||||
|             m_console.Commands.AddCommand("region", false, "show circuits", | ||||
|             m_console.Commands.AddCommand("Comms", false, "show circuits", | ||||
|                                           "show circuits", | ||||
|                                           "Show agent circuit data", HandleShow); | ||||
| 
 | ||||
|             m_console.Commands.AddCommand("region", false, "show http-handlers", | ||||
|                                           "show http-handlers", | ||||
|                                           "Show all registered http handlers", HandleShow); | ||||
| 
 | ||||
|             m_console.Commands.AddCommand("region", false, "show pending-objects", | ||||
|             m_console.Commands.AddCommand("Comms", false, "show pending-objects", | ||||
|                                           "show pending-objects", | ||||
|                                           "Show # of objects on the pending queues of all scene viewers", HandleShow); | ||||
| 
 | ||||
|             m_console.Commands.AddCommand("region", false, "show modules", | ||||
|             m_console.Commands.AddCommand("General", false, "show modules", | ||||
|                                           "show modules", | ||||
|                                           "Show module data", HandleShow); | ||||
| 
 | ||||
|             m_console.Commands.AddCommand("region", false, "show regions", | ||||
|             m_console.Commands.AddCommand("Regions", false, "show regions", | ||||
|                                           "show regions", | ||||
|                                           "Show region data", HandleShow); | ||||
|              | ||||
|             m_console.Commands.AddCommand("region", false, "show ratings", | ||||
|             m_console.Commands.AddCommand("Regions", false, "show ratings", | ||||
|                                           "show ratings", | ||||
|                                           "Show rating data", HandleShow); | ||||
| 
 | ||||
|             m_console.Commands.AddCommand("region", false, "backup", | ||||
|             m_console.Commands.AddCommand("Objects", false, "backup", | ||||
|                                           "backup", | ||||
|                                           "Persist currently unsaved object changes immediately instead of waiting for the normal persistence call.", RunCommand); | ||||
| 
 | ||||
|             m_console.Commands.AddCommand("region", false, "create region", | ||||
|             m_console.Commands.AddCommand("Regions", false, "create region", | ||||
|                                           "create region [\"region name\"] <region_file.ini>", | ||||
|                                           "Create a new region.", | ||||
|                                           "The settings for \"region name\" are read from <region_file.ini>. Paths specified with <region_file.ini> are relative to your Regions directory, unless an absolute path is given." | ||||
|  | @ -362,62 +357,57 @@ namespace OpenSim | |||
|                                           + "If <region_file.ini> does not exist, it will be created.", | ||||
|                                           HandleCreateRegion); | ||||
| 
 | ||||
|             m_console.Commands.AddCommand("region", false, "restart", | ||||
|             m_console.Commands.AddCommand("Regions", false, "restart", | ||||
|                                           "restart", | ||||
|                                           "Restart all sims in this instance", RunCommand); | ||||
| 
 | ||||
|             m_console.Commands.AddCommand("region", false, "config set", | ||||
|             m_console.Commands.AddCommand("General", false, "config set", | ||||
|                                           "config set <section> <key> <value>", | ||||
|                                           "Set a config option.  In most cases this is not useful since changed parameters are not dynamically reloaded.  Neither do changed parameters persist - you will have to change a config file manually and restart.", HandleConfig); | ||||
| 
 | ||||
|             m_console.Commands.AddCommand("region", false, "config get", | ||||
|             m_console.Commands.AddCommand("General", false, "config get", | ||||
|                                           "config get [<section>] [<key>]", | ||||
|                                           "Synonym for config show", | ||||
|                                           HandleConfig); | ||||
|              | ||||
|             m_console.Commands.AddCommand("region", false, "config show", | ||||
|             m_console.Commands.AddCommand("General", false, "config show", | ||||
|                                           "config show [<section>] [<key>]", | ||||
|                                           "Show config information",  | ||||
|                                           "If neither section nor field are specified, then the whole current configuration is printed." + Environment.NewLine | ||||
|                                           + "If a section is given but not a field, then all fields in that section are printed.", | ||||
|                                           HandleConfig);             | ||||
| 
 | ||||
|             m_console.Commands.AddCommand("region", false, "config save", | ||||
|             m_console.Commands.AddCommand("General", false, "config save", | ||||
|                                           "config save <path>", | ||||
|                                           "Save current configuration to a file at the given path", HandleConfig); | ||||
| 
 | ||||
|             m_console.Commands.AddCommand("region", false, "command-script", | ||||
|             m_console.Commands.AddCommand("General", false, "command-script", | ||||
|                                           "command-script <script>", | ||||
|                                           "Run a command script from file", RunCommand); | ||||
| 
 | ||||
|             m_console.Commands.AddCommand("region", false, "remove-region", | ||||
|             m_console.Commands.AddCommand("Regions", false, "remove-region", | ||||
|                                           "remove-region <name>", | ||||
|                                           "Remove a region from this simulator", RunCommand); | ||||
| 
 | ||||
|             m_console.Commands.AddCommand("region", false, "delete-region", | ||||
|             m_console.Commands.AddCommand("Regions", false, "delete-region", | ||||
|                                           "delete-region <name>", | ||||
|                                           "Delete a region from disk", RunCommand); | ||||
| 
 | ||||
|             m_console.Commands.AddCommand("region", false, "modules list", | ||||
|             m_console.Commands.AddCommand("General", false, "modules list", | ||||
|                                           "modules list", | ||||
|                                           "List modules", HandleModules); | ||||
| 
 | ||||
|             m_console.Commands.AddCommand("region", false, "modules load", | ||||
|             m_console.Commands.AddCommand("General", false, "modules load", | ||||
|                                           "modules load <name>", | ||||
|                                           "Load a module", HandleModules); | ||||
| 
 | ||||
|             m_console.Commands.AddCommand("region", false, "modules unload", | ||||
|             m_console.Commands.AddCommand("General", false, "modules unload", | ||||
|                                           "modules unload <name>", | ||||
|                                           "Unload a module", HandleModules); | ||||
| 
 | ||||
|             m_console.Commands.AddCommand("region", false, "Add-InventoryHost", | ||||
|                                           "Add-InventoryHost <host>", | ||||
|                                           String.Empty, RunCommand); | ||||
| 
 | ||||
|             m_console.Commands.AddCommand("region", false, "kill uuid", | ||||
|             m_console.Commands.AddCommand("Objects", false, "kill uuid", | ||||
|                                           "kill uuid <UUID>", | ||||
|                                           "Kill an object by UUID", KillUUID); | ||||
| 
 | ||||
|         } | ||||
| 
 | ||||
|         public override void ShutdownSpecific() | ||||
|  | @ -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; | ||||
| 
 | ||||
|             m_log.ErrorFormat("[WATCHDOG]: Timeout detected for thread \"{0}\". ThreadState={1}. Last tick was {2}ms ago", | ||||
|                 thread.Name, thread.ThreadState, now - lastTick); | ||||
|             m_log.ErrorFormat( | ||||
|                 "[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 | ||||
|  | @ -459,21 +453,27 @@ namespace OpenSim | |||
|         /// <param name="cmdparams">name of avatar to kick</param> | ||||
|         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; | ||||
| 
 | ||||
|             string alert = null; | ||||
|             if (cmdparams.Length > 4) | ||||
|             if (mainParams.Count > 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) | ||||
|             { | ||||
|                 RegionInfo regionInfo = presence.Scene.RegionInfo; | ||||
| 
 | ||||
|                 if (presence.Firstname.ToLower().Contains(cmdparams[2].ToLower()) && | ||||
|                     presence.Lastname.ToLower().Contains(cmdparams[3].ToLower())) | ||||
|                 if (presence.Firstname.ToLower().Contains(mainParams[2].ToLower()) && | ||||
|                     presence.Lastname.ToLower().Contains(mainParams[3].ToLower())) | ||||
|                 { | ||||
|                     MainConsole.Instance.Output( | ||||
|                         String.Format( | ||||
|  | @ -486,10 +486,10 @@ namespace OpenSim | |||
|                     else | ||||
|                         presence.ControllingClient.Kick("\nThe OpenSim manager kicked you out.\n"); | ||||
| 
 | ||||
|                     // ...and close on our side | ||||
|                     presence.Scene.IncomingCloseAgent(presence.UUID); | ||||
|                     presence.Scene.IncomingCloseAgent(presence.UUID, force); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             MainConsole.Instance.Output(""); | ||||
|         } | ||||
| 
 | ||||
|  | @ -543,7 +543,7 @@ namespace OpenSim | |||
|         private void HandleForceUpdate(string module, string[] args) | ||||
|         { | ||||
|             MainConsole.Instance.Output("Updating all clients"); | ||||
|             m_sceneManager.ForceCurrentSceneClientUpdate(); | ||||
|             SceneManager.ForceCurrentSceneClientUpdate(); | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|  | @ -555,7 +555,7 @@ namespace OpenSim | |||
|         { | ||||
|             if (args.Length == 6) | ||||
|             { | ||||
|                 m_sceneManager.HandleEditCommandOnCurrentScene(args); | ||||
|                 SceneManager.HandleEditCommandOnCurrentScene(args); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|  | @ -765,7 +765,7 @@ namespace OpenSim | |||
|                     case "load": | ||||
|                         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])); | ||||
|                                 m_moduleLoader.LoadRegionModules(cmdparams[1], s); | ||||
|  | @ -803,14 +803,14 @@ namespace OpenSim | |||
| 
 | ||||
|                 case "backup": | ||||
|                     MainConsole.Instance.Output("Triggering save of pending object updates to persistent store"); | ||||
|                     m_sceneManager.BackupCurrentScene(); | ||||
|                     SceneManager.BackupCurrentScene(); | ||||
|                     break; | ||||
| 
 | ||||
|                 case "remove-region": | ||||
|                     string regRemoveName = CombineParams(cmdparams, 0); | ||||
| 
 | ||||
|                     Scene removeScene; | ||||
|                     if (m_sceneManager.TryGetScene(regRemoveName, out removeScene)) | ||||
|                     if (SceneManager.TryGetScene(regRemoveName, out removeScene)) | ||||
|                         RemoveRegion(removeScene, false); | ||||
|                     else | ||||
|                         MainConsole.Instance.Output("No region with that name"); | ||||
|  | @ -820,23 +820,15 @@ namespace OpenSim | |||
|                     string regDeleteName = CombineParams(cmdparams, 0); | ||||
| 
 | ||||
|                     Scene killScene; | ||||
|                     if (m_sceneManager.TryGetScene(regDeleteName, out killScene)) | ||||
|                     if (SceneManager.TryGetScene(regDeleteName, out killScene)) | ||||
|                         RemoveRegion(killScene, true); | ||||
|                     else | ||||
|                         MainConsole.Instance.Output("no region with that name"); | ||||
|                     break; | ||||
| 
 | ||||
|                 case "restart": | ||||
|                     m_sceneManager.RestartCurrentScene(); | ||||
|                     SceneManager.RestartCurrentScene(); | ||||
|                     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); | ||||
| 
 | ||||
|                 if (!m_sceneManager.TrySetCurrentScene(newRegionName)) | ||||
|                 if (!SceneManager.TrySetCurrentScene(newRegionName)) | ||||
|                     MainConsole.Instance.Output(String.Format("Couldn't select region {0}", newRegionName)); | ||||
|             } | ||||
|             else | ||||
|  | @ -858,7 +850,7 @@ namespace OpenSim | |||
|                 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)); | ||||
| 
 | ||||
| //            m_log.DebugFormat("Original prompt is {0}", m_consolePrompt); | ||||
|  | @ -876,7 +868,7 @@ namespace OpenSim | |||
|             }); | ||||
| 
 | ||||
|             m_console.DefaultPrompt = prompt; | ||||
|             m_console.ConsoleScene = m_sceneManager.CurrentScene; | ||||
|             m_console.ConsoleScene = SceneManager.CurrentScene; | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|  | @ -900,7 +892,7 @@ namespace OpenSim | |||
|                         int 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. | ||||
| //                            MainConsole.Instance.OutputFormat("Debug packet level set to {0}", newDebug); | ||||
|                         } | ||||
|  | @ -912,63 +904,30 @@ namespace OpenSim | |||
| 
 | ||||
|                     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": | ||||
|                     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"); | ||||
|                         } | ||||
|                         else | ||||
|                         { | ||||
|                             bool scriptingOn = !Convert.ToBoolean(args[2]); | ||||
|                             bool collisionsOn = !Convert.ToBoolean(args[3]); | ||||
|                             bool physicsOn = !Convert.ToBoolean(args[4]); | ||||
|                             m_sceneManager.CurrentScene.SetSceneCoreDebug(scriptingOn, collisionsOn, physicsOn); | ||||
|                             string key = args[2]; | ||||
|                             string value = args[3]; | ||||
|                             SceneManager.CurrentScene.SetSceneCoreDebug( | ||||
|                                 new Dictionary<string, string>() { { key, value } }); | ||||
| 
 | ||||
|                             MainConsole.Instance.Output( | ||||
|                                 String.Format( | ||||
|                                     "Set debug scene scripting = {0}, collisions = {1}, physics = {2}", | ||||
|                                     !scriptingOn, !collisionsOn, !physicsOn)); | ||||
|                             MainConsole.Instance.OutputFormat("Set debug scene {0} = {1}", key, value); | ||||
|                         } | ||||
|                     } | ||||
|                     else | ||||
|                     { | ||||
|                         MainConsole.Instance.Output("Usage: debug scene <scripting> <collisions> <physics> (where inside <> is true/false)"); | ||||
|                         MainConsole.Instance.Output("Usage: debug scene scripting|collisions|physics|teleport true|false"); | ||||
|                     } | ||||
| 
 | ||||
|                     break; | ||||
| 
 | ||||
|                 case "teleport": | ||||
|                     foreach(Scene s in m_sceneManager.Scenes) | ||||
|                     { | ||||
|                         if (s.DEBUG) | ||||
|                         { | ||||
|                             s.DEBUG = false; | ||||
|                             MainConsole.Instance.Output("Teleport debugging is disabled!"); | ||||
|                         } | ||||
|                         else{ | ||||
|                             s.DEBUG = true; | ||||
|                             MainConsole.Instance.Output("Teleport debugging is enabled!"); | ||||
|                         } | ||||
|                     } | ||||
|                     break; | ||||
| 
 | ||||
|                 default: | ||||
|                     MainConsole.Instance.Output("Unknown debug command"); | ||||
|                     break; | ||||
|  | @ -995,11 +954,10 @@ namespace OpenSim | |||
|                     IList agents; | ||||
|                     if (showParams.Length > 1 && showParams[1] == "full") | ||||
|                     { | ||||
|                         agents = m_sceneManager.GetCurrentScenePresences(); | ||||
|                     } | ||||
|                     else | ||||
|                         agents = SceneManager.GetCurrentScenePresences(); | ||||
|                     } else | ||||
|                     { | ||||
|                         agents = m_sceneManager.GetCurrentSceneAvatars(); | ||||
|                         agents = SceneManager.GetCurrentSceneAvatars(); | ||||
|                     } | ||||
|                  | ||||
|                     MainConsole.Instance.Output(String.Format("\nAgents connected: {0}\n", agents.Count)); | ||||
|  | @ -1037,63 +995,11 @@ namespace OpenSim | |||
|                     break; | ||||
| 
 | ||||
|                 case "connections": | ||||
|                     System.Text.StringBuilder connections = new System.Text.StringBuilder("Connections:\n"); | ||||
|                     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()); | ||||
|                     HandleShowConnections(); | ||||
|                     break; | ||||
| 
 | ||||
|                 case "circuits": | ||||
|                     System.Text.StringBuilder acd = new System.Text.StringBuilder("Agent Circuits:\n"); | ||||
|                     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()); | ||||
|                     HandleShowCircuits(); | ||||
|                     break; | ||||
| 
 | ||||
|                 case "modules": | ||||
|  | @ -1103,24 +1009,37 @@ namespace OpenSim | |||
|                         MainConsole.Instance.Output("Shared Module: " + module.Name); | ||||
|                     } | ||||
| 
 | ||||
|                     m_sceneManager.ForEachScene( | ||||
|                         delegate(Scene scene) | ||||
|                     SceneManager.ForEachScene( | ||||
|                         delegate(Scene scene) { | ||||
|                         m_log.Error("The currently loaded modules in " + scene.RegionInfo.RegionName + " are:"); | ||||
| 
 | ||||
|                         foreach (IRegionModule module in scene.Modules.Values) | ||||
|                         { | ||||
|                             m_log.Error("The currently loaded modules in " + scene.RegionInfo.RegionName + " are:"); | ||||
|                             foreach (IRegionModule module in scene.Modules.Values) | ||||
|                             if (!module.IsSharedModule) | ||||
|                             { | ||||
|                                 if (!module.IsSharedModule) | ||||
|                                 { | ||||
|                                     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(""); | ||||
|                     break; | ||||
| 
 | ||||
|                 case "regions": | ||||
|                     m_sceneManager.ForEachScene( | ||||
|                     SceneManager.ForEachScene( | ||||
|                         delegate(Scene scene) | ||||
|                             { | ||||
|                                 MainConsole.Instance.Output(String.Format( | ||||
|  | @ -1134,7 +1053,7 @@ namespace OpenSim | |||
|                     break; | ||||
| 
 | ||||
|                 case "ratings": | ||||
|                     m_sceneManager.ForEachScene( | ||||
|                     SceneManager.ForEachScene( | ||||
|                     delegate(Scene scene) | ||||
|                     { | ||||
|                         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> | ||||
|         /// Use XML2 format to serialize data to a file | ||||
|         /// </summary> | ||||
|  | @ -1168,11 +1134,11 @@ namespace OpenSim | |||
|         { | ||||
|             if (cmdparams.Length > 5) | ||||
|             { | ||||
|                 m_sceneManager.SaveNamedPrimsToXml2(cmdparams[3], cmdparams[4]); | ||||
|                 SceneManager.SaveNamedPrimsToXml2(cmdparams[3], cmdparams[4]); | ||||
|             } | ||||
|             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) | ||||
|             { | ||||
|                 m_sceneManager.SaveCurrentSceneToXml(cmdparams[2]); | ||||
|                 SceneManager.SaveCurrentSceneToXml(cmdparams[2]); | ||||
|             } | ||||
|             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)); | ||||
|                     } | ||||
|                 } | ||||
|                 m_sceneManager.LoadCurrentSceneFromXml(cmdparams[2], generateNewIDS, loadOffset); | ||||
|                 SceneManager.LoadCurrentSceneFromXml(cmdparams[2], generateNewIDS, loadOffset); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 try | ||||
|                 { | ||||
|                     m_sceneManager.LoadCurrentSceneFromXml(DEFAULT_PRIM_BACKUP_FILENAME, false, loadOffset); | ||||
|                     SceneManager.LoadCurrentSceneFromXml(DEFAULT_PRIM_BACKUP_FILENAME, false, loadOffset); | ||||
|                 } | ||||
|                 catch (FileNotFoundException) | ||||
|                 { | ||||
|  | @ -1251,11 +1217,11 @@ namespace OpenSim | |||
|         { | ||||
|             if (cmdparams.Length > 2) | ||||
|             { | ||||
|                 m_sceneManager.SaveCurrentSceneToXml2(cmdparams[2]); | ||||
|                 SceneManager.SaveCurrentSceneToXml2(cmdparams[2]); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 m_sceneManager.SaveCurrentSceneToXml2(DEFAULT_PRIM_BACKUP_FILENAME); | ||||
|                 SceneManager.SaveCurrentSceneToXml2(DEFAULT_PRIM_BACKUP_FILENAME); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|  | @ -1270,7 +1236,7 @@ namespace OpenSim | |||
|             { | ||||
|                 try | ||||
|                 { | ||||
|                     m_sceneManager.LoadCurrentSceneFromXml2(cmdparams[2]); | ||||
|                     SceneManager.LoadCurrentSceneFromXml2(cmdparams[2]); | ||||
|                 } | ||||
|                 catch (FileNotFoundException) | ||||
|                 { | ||||
|  | @ -1281,7 +1247,7 @@ namespace OpenSim | |||
|             { | ||||
|                 try | ||||
|                 { | ||||
|                     m_sceneManager.LoadCurrentSceneFromXml2(DEFAULT_PRIM_BACKUP_FILENAME); | ||||
|                     SceneManager.LoadCurrentSceneFromXml2(DEFAULT_PRIM_BACKUP_FILENAME); | ||||
|                 } | ||||
|                 catch (FileNotFoundException) | ||||
|                 { | ||||
|  | @ -1298,7 +1264,7 @@ namespace OpenSim | |||
|         { | ||||
|             try | ||||
|             { | ||||
|                 m_sceneManager.LoadArchiveToCurrentScene(cmdparams); | ||||
|                 SceneManager.LoadArchiveToCurrentScene(cmdparams); | ||||
|             } | ||||
|             catch (Exception e) | ||||
|             { | ||||
|  | @ -1312,7 +1278,7 @@ namespace OpenSim | |||
|         /// <param name="cmdparams"></param> | ||||
|         protected void SaveOar(string module, string[] cmdparams) | ||||
|         { | ||||
|             m_sceneManager.SaveCurrentSceneToArchive(cmdparams); | ||||
|             SceneManager.SaveCurrentSceneToArchive(cmdparams); | ||||
|         } | ||||
| 
 | ||||
|         private static string CombineParams(string[] commandParams, int pos) | ||||
|  | @ -1344,7 +1310,7 @@ namespace OpenSim | |||
|                     return; | ||||
|                 } | ||||
| 
 | ||||
|                 m_sceneManager.ForEachScene( | ||||
|                 SceneManager.ForEachScene( | ||||
|                     delegate(Scene scene) | ||||
|                     { | ||||
|                         SceneObjectPart part = scene.GetSceneObjectPart(id); | ||||
|  |  | |||
|  | @ -219,7 +219,7 @@ namespace OpenSim | |||
| 
 | ||||
|             base.StartupSpecific(); | ||||
| 
 | ||||
|             m_stats = StatsManager.StartCollectingSimExtraStats(); | ||||
|             m_stats = StatsManager.SimExtraStats; | ||||
| 
 | ||||
|             // Create a ModuleLoader instance | ||||
|             m_moduleLoader = new ModuleLoader(m_config.Source); | ||||
|  | @ -242,15 +242,18 @@ namespace OpenSim | |||
| 
 | ||||
|                 foreach (string topic in topics) | ||||
|                 { | ||||
|                     m_console.Commands.AddCommand("plugin", false, "help " + topic, | ||||
|                                                   "help " + topic, | ||||
|                     string capitalizedTopic = char.ToUpper(topic[0]) + topic.Substring(1); | ||||
| 
 | ||||
|                     // This is a hack to allow the user to enter the help command in upper or lowercase.  This will go | ||||
|                     // away at some point. | ||||
|                     m_console.Commands.AddCommand(capitalizedTopic, false, "help " + topic, | ||||
|                                                   "help " + capitalizedTopic, | ||||
|                                                   "Get help on plugin command '" + topic + "'", | ||||
|                                                   HandleCommanderHelp); | ||||
|                     m_console.Commands.AddCommand(capitalizedTopic, false, "help " + capitalizedTopic, | ||||
|                                                   "help " + capitalizedTopic, | ||||
|                                                   "Get help on plugin command '" + topic + "'", | ||||
|                                                   HandleCommanderHelp); | ||||
| 
 | ||||
|                     m_console.Commands.AddCommand("plugin", false, topic, | ||||
|                                                   topic, | ||||
|                                                   "Execute subcommand for plugin '" + topic + "'", | ||||
|                                                   null); | ||||
| 
 | ||||
|                     ICommander commander = null; | ||||
| 
 | ||||
|  | @ -267,7 +270,7 @@ namespace OpenSim | |||
| 
 | ||||
|                     foreach (string command in commander.Commands.Keys) | ||||
|                     { | ||||
|                         m_console.Commands.AddCommand(topic, false, | ||||
|                         m_console.Commands.AddCommand(capitalizedTopic, false, | ||||
|                                                       topic + " " + command, | ||||
|                                                       topic + " " + commander.Commands[command].ShortHelp(), | ||||
|                                                       String.Empty, HandleCommanderCommand); | ||||
|  | @ -278,7 +281,7 @@ namespace OpenSim | |||
| 
 | ||||
|         private void HandleCommanderCommand(string module, string[] cmd) | ||||
|         { | ||||
|             m_sceneManager.SendCommandToPluginModules(cmd); | ||||
|             SceneManager.SendCommandToPluginModules(cmd); | ||||
|         } | ||||
| 
 | ||||
|         private void HandleCommanderHelp(string module, string[] cmd) | ||||
|  | @ -286,7 +289,7 @@ namespace OpenSim | |||
|             // Only safe for the interactive console, since it won't | ||||
|             // let us come here unless both scene and commander exist | ||||
|             // | ||||
|             ICommander moduleCommander = SceneManager.CurrentOrFirstScene.GetCommander(cmd[1]); | ||||
|             ICommander moduleCommander = SceneManager.CurrentOrFirstScene.GetCommander(cmd[1].ToLower()); | ||||
|             if (moduleCommander != null) | ||||
|                 m_console.Output(moduleCommander.Help); | ||||
|         } | ||||
|  | @ -296,7 +299,10 @@ namespace OpenSim | |||
|             // Called from base.StartUp() | ||||
| 
 | ||||
|             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> | ||||
|  | @ -381,7 +387,7 @@ namespace OpenSim | |||
|             scene.LoadPrimsFromStorage(regionInfo.originRegionID); | ||||
|              | ||||
|             // TODO : Try setting resource for region xstats here on scene | ||||
|             MainServer.Instance.AddStreamHandler(new Region.Framework.Scenes.RegionStatsHandler(regionInfo));  | ||||
|             MainServer.Instance.AddStreamHandler(new RegionStatsHandler(regionInfo)); | ||||
|              | ||||
|             scene.loadAllLandObjectsFromStorage(regionInfo.originRegionID); | ||||
|             scene.EventManager.TriggerParcelPrimCountUpdate(); | ||||
|  | @ -405,7 +411,7 @@ namespace OpenSim | |||
|             // scripting engines. | ||||
|             scene.CreateScriptInstances(); | ||||
| 
 | ||||
|             m_sceneManager.Add(scene); | ||||
|             SceneManager.Add(scene); | ||||
| 
 | ||||
|             if (m_autoCreateClientStack) | ||||
|             { | ||||
|  | @ -424,8 +430,7 @@ namespace OpenSim | |||
| 
 | ||||
|             mscene = scene; | ||||
| 
 | ||||
|             scene.StartTimer(); | ||||
| 
 | ||||
|             scene.Start(); | ||||
|             scene.StartScripts(); | ||||
| 
 | ||||
|             return clientServer; | ||||
|  | @ -512,14 +517,14 @@ namespace OpenSim | |||
|         { | ||||
|             // only need to check this if we are not at the | ||||
|             // root level | ||||
|             if ((m_sceneManager.CurrentScene != null) && | ||||
|                 (m_sceneManager.CurrentScene.RegionInfo.RegionID == scene.RegionInfo.RegionID)) | ||||
|             if ((SceneManager.CurrentScene != null) && | ||||
|                 (SceneManager.CurrentScene.RegionInfo.RegionID == scene.RegionInfo.RegionID)) | ||||
|             { | ||||
|                 m_sceneManager.TrySetCurrentScene(".."); | ||||
|                 SceneManager.TrySetCurrentScene(".."); | ||||
|             } | ||||
| 
 | ||||
|             scene.DeleteAllSceneObjects(); | ||||
|             m_sceneManager.CloseScene(scene); | ||||
|             SceneManager.CloseScene(scene); | ||||
|             ShutdownClientServer(scene.RegionInfo); | ||||
|              | ||||
|             if (!cleanup) | ||||
|  | @ -561,7 +566,7 @@ namespace OpenSim | |||
|         public void RemoveRegion(string name, bool cleanUp) | ||||
|         { | ||||
|             Scene target; | ||||
|             if (m_sceneManager.TryGetScene(name, out target)) | ||||
|             if (SceneManager.TryGetScene(name, out target)) | ||||
|                 RemoveRegion(target, cleanUp); | ||||
|         } | ||||
| 
 | ||||
|  | @ -574,13 +579,13 @@ namespace OpenSim | |||
|         { | ||||
|             // only need to check this if we are not at the | ||||
|             // root level | ||||
|             if ((m_sceneManager.CurrentScene != null) && | ||||
|                 (m_sceneManager.CurrentScene.RegionInfo.RegionID == scene.RegionInfo.RegionID)) | ||||
|             if ((SceneManager.CurrentScene != null) && | ||||
|                 (SceneManager.CurrentScene.RegionInfo.RegionID == scene.RegionInfo.RegionID)) | ||||
|             { | ||||
|                 m_sceneManager.TrySetCurrentScene(".."); | ||||
|                 SceneManager.TrySetCurrentScene(".."); | ||||
|             } | ||||
| 
 | ||||
|             m_sceneManager.CloseScene(scene); | ||||
|             SceneManager.CloseScene(scene); | ||||
|             ShutdownClientServer(scene.RegionInfo); | ||||
|         } | ||||
|          | ||||
|  | @ -592,7 +597,7 @@ namespace OpenSim | |||
|         public void CloseRegion(string name) | ||||
|         { | ||||
|             Scene target; | ||||
|             if (m_sceneManager.TryGetScene(name, out target)) | ||||
|             if (SceneManager.TryGetScene(name, out target)) | ||||
|                 CloseRegion(target); | ||||
|         } | ||||
|          | ||||
|  | @ -724,6 +729,9 @@ namespace OpenSim | |||
|                 return Util.UTF8.GetBytes("OK"); | ||||
|             } | ||||
| 
 | ||||
|             public string Name { get { return "SimStatus"; } } | ||||
|             public string Description { get { return "Simulator Status"; } } | ||||
| 
 | ||||
|             public string ContentType | ||||
|             { | ||||
|                 get { return "text/plain"; } | ||||
|  | @ -748,6 +756,9 @@ namespace OpenSim | |||
|         { | ||||
|             OpenSimBase m_opensim; | ||||
|             string osXStatsURI = String.Empty; | ||||
| 
 | ||||
|             public string Name { get { return "XSimStatus"; } } | ||||
|             public string Description { get { return "Simulator XStatus"; } } | ||||
|          | ||||
|             public XSimStatusHandler(OpenSimBase sim) | ||||
|             { | ||||
|  | @ -788,6 +799,9 @@ namespace OpenSim | |||
|         { | ||||
|             OpenSimBase m_opensim; | ||||
|             string osUXStatsURI = String.Empty; | ||||
| 
 | ||||
|             public string Name { get { return "UXSimStatus"; } } | ||||
|             public string Description { get { return "Simulator UXStatus"; } } | ||||
|          | ||||
|             public UXSimStatusHandler(OpenSimBase sim) | ||||
|             { | ||||
|  | @ -839,7 +853,7 @@ namespace OpenSim | |||
| 
 | ||||
|             try | ||||
|             { | ||||
|                 m_sceneManager.Close(); | ||||
|                 SceneManager.Close(); | ||||
|             } | ||||
|             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> | ||||
|         public void GetAvatarNumber(out int usernum) | ||||
|         { | ||||
|             usernum = m_sceneManager.GetCurrentSceneAvatars().Count; | ||||
|             usernum = SceneManager.GetCurrentSceneAvatars().Count; | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|  | @ -873,7 +887,7 @@ namespace OpenSim | |||
|         /// <param name="regionnum">The first out parameter describing the number of regions</param> | ||||
|         public void GetRegionNumber(out int regionnum) | ||||
|         { | ||||
|             regionnum = m_sceneManager.Scenes.Count; | ||||
|             regionnum = SceneManager.Scenes.Count; | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|  |  | |||
|  | @ -151,7 +151,9 @@ namespace OpenSim.Region.ClientStack.Linden | |||
|             try | ||||
|             { | ||||
|                 // the root of all evil | ||||
|                 m_HostCapsObj.RegisterHandler("SEED", new RestStreamHandler("POST", capsBase + m_requestPath, SeedCapRequest)); | ||||
|                 m_HostCapsObj.RegisterHandler( | ||||
|                     "SEED", new RestStreamHandler("POST", capsBase + m_requestPath, SeedCapRequest, "SEED", null)); | ||||
| 
 | ||||
|                 m_log.DebugFormat( | ||||
|                     "[CAPS]: Registered seed capability {0} for {1}", capsBase + m_requestPath, m_HostCapsObj.AgentID); | ||||
| 
 | ||||
|  | @ -159,7 +161,10 @@ namespace OpenSim.Region.ClientStack.Linden | |||
|                 //    new LLSDStreamhandler<OSDMapRequest, OSDMapLayerResponse>("POST", | ||||
|                 //                                                                capsBase + m_mapLayerPath, | ||||
|                 //                                                                GetMapLayer); | ||||
|                 IRequestHandler req = new RestStreamHandler("POST", capsBase + m_notecardTaskUpdatePath, ScriptTaskInventory); | ||||
|                 IRequestHandler req | ||||
|                     = new RestStreamHandler( | ||||
|                         "POST", capsBase + m_notecardTaskUpdatePath, ScriptTaskInventory, "UpdateScript", null); | ||||
| 
 | ||||
|                 m_HostCapsObj.RegisterHandler("UpdateScriptTaskInventory", req); | ||||
|                 m_HostCapsObj.RegisterHandler("UpdateScriptTask", req); | ||||
|             } | ||||
|  | @ -174,14 +179,27 @@ namespace OpenSim.Region.ClientStack.Linden | |||
|             try | ||||
|             { | ||||
|                 // I don't think this one works... | ||||
|                 m_HostCapsObj.RegisterHandler("NewFileAgentInventory", new LLSDStreamhandler<LLSDAssetUploadRequest, LLSDAssetUploadResponse>("POST", | ||||
|                                                                                            capsBase + m_newInventory, | ||||
|                                                                                            NewAgentInventoryRequest)); | ||||
|                 IRequestHandler req = new RestStreamHandler("POST", capsBase + m_notecardUpdatePath, NoteCardAgentInventory); | ||||
|                 m_HostCapsObj.RegisterHandler( | ||||
|                     "NewFileAgentInventory", | ||||
|                     new LLSDStreamhandler<LLSDAssetUploadRequest, LLSDAssetUploadResponse>( | ||||
|                         "POST", | ||||
|                         capsBase + m_newInventory, | ||||
|                         NewAgentInventoryRequest, | ||||
|                         "NewFileAgentInventory", | ||||
|                         null)); | ||||
| 
 | ||||
|                 IRequestHandler req | ||||
|                     = new RestStreamHandler( | ||||
|                         "POST", capsBase + m_notecardUpdatePath, NoteCardAgentInventory, "Update*", null); | ||||
| 
 | ||||
|                 m_HostCapsObj.RegisterHandler("UpdateNotecardAgentInventory", req); | ||||
|                 m_HostCapsObj.RegisterHandler("UpdateScriptAgentInventory", req); | ||||
|                 m_HostCapsObj.RegisterHandler("UpdateScriptAgent", req); | ||||
|                 m_HostCapsObj.RegisterHandler("CopyInventoryFromNotecard", new RestStreamHandler("POST", capsBase + m_copyFromNotecardPath, CopyInventoryFromNotecard)); | ||||
| 
 | ||||
|                 m_HostCapsObj.RegisterHandler( | ||||
|                     "CopyInventoryFromNotecard", | ||||
|                     new RestStreamHandler( | ||||
|                         "POST", capsBase + m_copyFromNotecardPath, CopyInventoryFromNotecard, "CopyInventoryFromNotecard", null)); | ||||
|               | ||||
|                 // As of RC 1.22.9 of the Linden client this is | ||||
|                 // supported | ||||
|  | @ -231,7 +249,10 @@ namespace OpenSim.Region.ClientStack.Linden | |||
| 
 | ||||
|             if (!m_Scene.CheckClient(m_HostCapsObj.AgentID, httpRequest.RemoteIPEndPoint)) | ||||
|             { | ||||
|                 m_log.DebugFormat("[CAPS]: Unauthorized CAPS client"); | ||||
|                 m_log.DebugFormat( | ||||
|                     "[CAPS]: Unauthorized CAPS client {0} from {1}", | ||||
|                     m_HostCapsObj.AgentID, httpRequest.RemoteIPEndPoint); | ||||
| 
 | ||||
|                 return string.Empty; | ||||
|             } | ||||
| 
 | ||||
|  | @ -262,7 +283,7 @@ namespace OpenSim.Region.ClientStack.Linden | |||
|         { | ||||
|             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); | ||||
| 
 | ||||
|                 Hashtable hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request)); | ||||
|  | @ -282,7 +303,9 @@ namespace OpenSim.Region.ClientStack.Linden | |||
|                         m_dumpAssetsToFile); | ||||
|                 uploader.OnUpLoad += TaskScriptUpdated; | ||||
| 
 | ||||
|                 m_HostCapsObj.HttpListener.AddStreamHandler(new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps)); | ||||
|                 m_HostCapsObj.HttpListener.AddStreamHandler( | ||||
|                     new BinaryStreamHandler( | ||||
|                         "POST", capsBase + uploaderPath, uploader.uploaderCaps, "TaskInventoryScriptUpdater", null)); | ||||
| 
 | ||||
|                 string protocol = "http://"; | ||||
| 
 | ||||
|  | @ -393,8 +416,14 @@ namespace OpenSim.Region.ClientStack.Linden | |||
|             AssetUploader uploader = | ||||
|                 new AssetUploader(assetName, assetDes, newAsset, newInvItem, parentFolder, llsdRequest.inventory_type, | ||||
|                                   llsdRequest.asset_type, capsBase + uploaderPath, m_HostCapsObj.HttpListener, m_dumpAssetsToFile); | ||||
| 
 | ||||
|             m_HostCapsObj.HttpListener.AddStreamHandler( | ||||
|                 new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps)); | ||||
|                 new BinaryStreamHandler( | ||||
|                     "POST", | ||||
|                     capsBase + uploaderPath, | ||||
|                     uploader.uploaderCaps, | ||||
|                     "NewAgentInventoryRequest", | ||||
|                     m_HostCapsObj.AgentID.ToString())); | ||||
| 
 | ||||
|             string protocol = "http://"; | ||||
| 
 | ||||
|  | @ -710,7 +739,8 @@ namespace OpenSim.Region.ClientStack.Linden | |||
|             uploader.OnUpLoad += ItemUpdated; | ||||
| 
 | ||||
|             m_HostCapsObj.HttpListener.AddStreamHandler( | ||||
|                 new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps)); | ||||
|                 new BinaryStreamHandler( | ||||
|                     "POST", capsBase + uploaderPath, uploader.uploaderCaps, "NoteCardAgentInventory", null)); | ||||
| 
 | ||||
|             string protocol = "http://"; | ||||
| 
 | ||||
|  |  | |||
|  | @ -94,7 +94,7 @@ namespace OpenSim.Region.ClientStack.Linden | |||
|                  | ||||
|                 //scene.CommsManager.HttpServer.AddLLSDHandler("/CAPS/EQG/", EventQueueFallBack); | ||||
| 
 | ||||
|                 scene.EventManager.OnNewClient += OnNewClient; | ||||
| //                scene.EventManager.OnNewClient += OnNewClient; | ||||
| 
 | ||||
|                 // TODO: Leaving these open, or closing them when we | ||||
|                 // become a child is incorrect. It messes up TP in a big | ||||
|  | @ -102,17 +102,19 @@ namespace OpenSim.Region.ClientStack.Linden | |||
|                 // circuit is there. | ||||
| 
 | ||||
|                 scene.EventManager.OnClientClosed += ClientClosed; | ||||
|                  | ||||
|                 scene.EventManager.OnMakeChildAgent += MakeChildAgent; | ||||
|                 scene.EventManager.OnRegisterCaps += OnRegisterCaps; | ||||
| 
 | ||||
|                 MainConsole.Instance.Commands.AddCommand( | ||||
|                     "event queue", | ||||
|                     "Debug", | ||||
|                     false, | ||||
|                     "debug eq", | ||||
|                     "debug eq [0|1]", | ||||
|                     "Turn on event queue debugging",                                    | ||||
|                     "debug eq 1 will turn on event queue debugging.  This will log all outgoing event queue messages to clients.\n" | ||||
|                         + "debug eq 0 will turn off event queue debugging.", | ||||
|                     "debug eq [0|1|2]", | ||||
|                     "Turn on event queue debugging" | ||||
|                         + "<= 0 - turns off all event queue logging" | ||||
|                         + ">= 1 - turns on outgoing event logging" | ||||
|                         + ">= 2 - turns on poll notification", | ||||
|                     HandleDebugEq); | ||||
|             } | ||||
|             else | ||||
|  | @ -225,29 +227,19 @@ namespace OpenSim.Region.ClientStack.Linden | |||
| 
 | ||||
|         #endregion | ||||
| 
 | ||||
|         private void OnNewClient(IClientAPI client) | ||||
|         private void ClientClosed(UUID agentID, Scene scene) | ||||
|         { | ||||
|             //client.OnLogout += ClientClosed; | ||||
|         } | ||||
| 
 | ||||
| //        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); | ||||
| //            m_log.DebugFormat("[EVENTQUEUE]: Closed client {0} in region {1}", agentID, m_scene.RegionInfo.RegionName); | ||||
| 
 | ||||
|             int count = 0; | ||||
|             while (queues.ContainsKey(AgentID) && queues[AgentID].Count > 0 && count++ < 5) | ||||
|             while (queues.ContainsKey(agentID) && queues[agentID].Count > 0 && count++ < 5) | ||||
|             { | ||||
|                 Thread.Sleep(1000); | ||||
|             } | ||||
| 
 | ||||
|             lock (queues) | ||||
|             { | ||||
|                 queues.Remove(AgentID); | ||||
|                 queues.Remove(agentID); | ||||
|             } | ||||
| 
 | ||||
|             List<UUID> removeitems = new List<UUID>(); | ||||
|  | @ -256,7 +248,7 @@ namespace OpenSim.Region.ClientStack.Linden | |||
|                 foreach (UUID ky in m_AvatarQueueUUIDMapping.Keys) | ||||
|                 { | ||||
| //                    m_log.DebugFormat("[EVENTQUEUE]: Found key {0} in m_AvatarQueueUUIDMapping while looking for {1}", ky, AgentID); | ||||
|                     if (ky == AgentID) | ||||
|                     if (ky == agentID) | ||||
|                     { | ||||
|                         removeitems.Add(ky); | ||||
|                     } | ||||
|  | @ -267,7 +259,12 @@ namespace OpenSim.Region.ClientStack.Linden | |||
|                     UUID eventQueueGetUuid = m_AvatarQueueUUIDMapping[ky]; | ||||
|                     m_AvatarQueueUUIDMapping.Remove(ky); | ||||
| 
 | ||||
|                     MainServer.Instance.RemovePollServiceHTTPHandler("","/CAPS/EQG/" + eventQueueGetUuid.ToString() + "/"); | ||||
|                     string eqgPath = GenerateEqgCapPath(eventQueueGetUuid); | ||||
|                     MainServer.Instance.RemovePollServiceHTTPHandler("", eqgPath); | ||||
| 
 | ||||
| //                    m_log.DebugFormat( | ||||
| //                        "[EVENT QUEUE GET MODULE]: Removed EQG handler {0} for {1} in {2}", | ||||
| //                        eqgPath, agentID, m_scene.RegionInfo.RegionName); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|  | @ -281,7 +278,7 @@ namespace OpenSim.Region.ClientStack.Linden | |||
|                 { | ||||
|                     searchval = m_QueueUUIDAvatarMapping[ky]; | ||||
| 
 | ||||
|                     if (searchval == AgentID) | ||||
|                     if (searchval == agentID) | ||||
|                     { | ||||
|                         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) | ||||
|         { | ||||
|             // 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 | ||||
|             TryGetQueue(agentID); | ||||
| 
 | ||||
|             string capsBase = "/CAPS/EQG/"; | ||||
|             UUID EventQueueGetUUID = UUID.Zero; | ||||
|             UUID eventQueueGetUUID; | ||||
| 
 | ||||
|             lock (m_AvatarQueueUUIDMapping) | ||||
|             { | ||||
|  | @ -325,44 +330,50 @@ namespace OpenSim.Region.ClientStack.Linden | |||
|                 if (m_AvatarQueueUUIDMapping.ContainsKey(agentID)) | ||||
|                 { | ||||
|                     //m_log.DebugFormat("[EVENTQUEUE]: Found Existing UUID!"); | ||||
|                     EventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID]; | ||||
|                     eventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID]; | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     EventQueueGetUUID = UUID.Random(); | ||||
|                     eventQueueGetUUID = UUID.Random(); | ||||
|                     //m_log.DebugFormat("[EVENTQUEUE]: Using random UUID!"); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             lock (m_QueueUUIDAvatarMapping) | ||||
|             { | ||||
|                 if (!m_QueueUUIDAvatarMapping.ContainsKey(EventQueueGetUUID)) | ||||
|                     m_QueueUUIDAvatarMapping.Add(EventQueueGetUUID, agentID); | ||||
|                 if (!m_QueueUUIDAvatarMapping.ContainsKey(eventQueueGetUUID)) | ||||
|                     m_QueueUUIDAvatarMapping.Add(eventQueueGetUUID, agentID); | ||||
|             } | ||||
| 
 | ||||
|             lock (m_AvatarQueueUUIDMapping) | ||||
|             { | ||||
|                 if (!m_AvatarQueueUUIDMapping.ContainsKey(agentID)) | ||||
|                     m_AvatarQueueUUIDMapping.Add(agentID, EventQueueGetUUID); | ||||
|                     m_AvatarQueueUUIDMapping.Add(agentID, eventQueueGetUUID); | ||||
|             } | ||||
| 
 | ||||
|             string eventQueueGetPath = GenerateEqgCapPath(eventQueueGetUUID); | ||||
| 
 | ||||
|             // Register this as a caps handler | ||||
|             // FIXME: Confusingly, we need to register separate as a capability so that the client is told about | ||||
|             // EventQueueGet when it receive capability information, but then we replace the rest handler immediately | ||||
|             // afterwards with the poll service.  So for now, we'll pass a null instead to simplify code reading, but | ||||
|             // really it should be possible to directly register the poll handler as a capability. | ||||
|             caps.RegisterHandler("EventQueueGet", | ||||
|                                  new RestHTTPHandler("POST", capsBase + EventQueueGetUUID.ToString() + "/", null)); | ||||
|             caps.RegisterHandler("EventQueueGet", new RestHTTPHandler("POST", eventQueueGetPath, null)); | ||||
| //                                                       delegate(Hashtable m_dhttpMethod) | ||||
| //                                                       { | ||||
| //                                                           return ProcessQueue(m_dhttpMethod, agentID, caps); | ||||
| //                                                       })); | ||||
| 
 | ||||
|             // This will persist this beyond the expiry of the caps handlers | ||||
|             // TODO: Add EventQueueGet name/description for diagnostics | ||||
|             MainServer.Instance.AddPollServiceHTTPHandler( | ||||
|                 capsBase + EventQueueGetUUID.ToString() + "/", | ||||
|                 eventQueueGetPath, | ||||
|                 new PollServiceEventArgs(null, HasEvents, GetEvents, NoEvents, agentID)); | ||||
| 
 | ||||
| //            m_log.DebugFormat( | ||||
| //                "[EVENT QUEUE GET MODULE]: Registered EQG handler {0} for {1} in {2}", | ||||
| //                eventQueueGetPath, agentID, m_scene.RegionInfo.RegionName); | ||||
| 
 | ||||
|             Random rnd = new Random(Environment.TickCount); | ||||
|             lock (m_ids) | ||||
|             { | ||||
|  | @ -384,9 +395,25 @@ namespace OpenSim.Region.ClientStack.Linden | |||
|             return false; | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Logs a debug line for an outbound event queue message if appropriate. | ||||
|         /// </summary> | ||||
|         /// <param name='element'>Element containing message</param> | ||||
|         private void LogOutboundDebugMessage(OSD element, UUID agentId) | ||||
|         { | ||||
|             if (element is OSDMap) | ||||
|             { | ||||
|                 OSDMap ev = (OSDMap)element; | ||||
|                 m_log.DebugFormat( | ||||
|                     "Eq OUT {0,-30} to {1,-20} {2,-20}", | ||||
|                     ev["message"], m_scene.GetScenePresence(agentId).Name, m_scene.RegionInfo.RegionName); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public Hashtable GetEvents(UUID requestID, UUID pAgentId, string request) | ||||
|         { | ||||
| //            m_log.DebugFormat("[EVENT QUEUE GET MODULE]: Invoked GetEvents() for {0}", pAgentId); | ||||
|             if (DebugLevel >= 2) | ||||
|                 m_log.DebugFormat("POLLED FOR EQ MESSAGES BY {0} in {1}", pAgentId, m_scene.RegionInfo.RegionName); | ||||
| 
 | ||||
|             Queue<OSD> queue = TryGetQueue(pAgentId); | ||||
|             OSD element; | ||||
|  | @ -410,13 +437,8 @@ namespace OpenSim.Region.ClientStack.Linden | |||
|             } | ||||
|             else | ||||
|             { | ||||
|                 if (DebugLevel > 0 && element is OSDMap) | ||||
|                 { | ||||
|                     OSDMap ev = (OSDMap)element; | ||||
|                     m_log.DebugFormat( | ||||
|                         "[EVENT QUEUE GET MODULE]: Eq OUT {0} to {1}", | ||||
|                         ev["message"], m_scene.GetScenePresence(pAgentId).Name); | ||||
|                 } | ||||
|                 if (DebugLevel > 0) | ||||
|                     LogOutboundDebugMessage(element, pAgentId); | ||||
| 
 | ||||
|                 array.Add(element); | ||||
| 
 | ||||
|  | @ -426,13 +448,8 @@ namespace OpenSim.Region.ClientStack.Linden | |||
|                     { | ||||
|                         element = queue.Dequeue(); | ||||
| 
 | ||||
|                         if (DebugLevel > 0 && element is OSDMap) | ||||
|                         { | ||||
|                             OSDMap ev = (OSDMap)element; | ||||
|                             m_log.DebugFormat( | ||||
|                                 "[EVENT QUEUE GET MODULE]: Eq OUT {0} to {1}", | ||||
|                                 ev["message"], m_scene.GetScenePresence(pAgentId).Name); | ||||
|                         } | ||||
|                         if (DebugLevel > 0) | ||||
|                             LogOutboundDebugMessage(element, pAgentId); | ||||
| 
 | ||||
|                         array.Add(element); | ||||
|                         thisID++; | ||||
|  |  | |||
|  | @ -51,7 +51,16 @@ namespace OpenSim.Region.ClientStack.Linden.Tests | |||
|         [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(); | ||||
|             config.AddConfig("Startup"); | ||||
|  | @ -60,7 +69,7 @@ namespace OpenSim.Region.ClientStack.Linden.Tests | |||
|             CapabilitiesModule capsModule = new CapabilitiesModule(); | ||||
|             EventQueueGetModule eqgModule = new EventQueueGetModule(); | ||||
| 
 | ||||
|             m_scene = SceneHelpers.SetupScene(); | ||||
|             m_scene = new SceneHelpers().SetupScene(); | ||||
|             SceneHelpers.SetupSceneModules(m_scene, config, capsModule, eqgModule); | ||||
|         } | ||||
| 
 | ||||
|  | @ -85,7 +94,7 @@ namespace OpenSim.Region.ClientStack.Linden.Tests | |||
|             UUID spId = TestHelpers.ParseTail(0x1); | ||||
| 
 | ||||
|             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 | ||||
|             Assert.That(MainServer.Instance.GetPollServiceHandlerKeys().Count, Is.EqualTo(0)); | ||||
|  |  | |||
|  | @ -132,7 +132,8 @@ namespace OpenSim.Region.ClientStack.Linden | |||
|                 capUrl = "/CAPS/" + UUID.Random(); | ||||
| 
 | ||||
|                 IRequestHandler reqHandler | ||||
|                     = new RestStreamHandler("POST", capUrl, m_fetchHandler.FetchInventoryRequest); | ||||
|                     = new RestStreamHandler( | ||||
|                         "POST", capUrl, m_fetchHandler.FetchInventoryRequest, capName, agentID.ToString()); | ||||
| 
 | ||||
|                 caps.RegisterHandler(capName, reqHandler); | ||||
|             } | ||||
|  |  | |||
|  | @ -120,11 +120,13 @@ namespace OpenSim.Region.ClientStack.Linden | |||
|             { | ||||
| //                m_log.DebugFormat("[GETMESH]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName); | ||||
|                 GetMeshHandler gmeshHandler = new GetMeshHandler(m_AssetService); | ||||
|                 IRequestHandler reqHandler = new RestHTTPHandler("GET", "/CAPS/" + UUID.Random(), | ||||
|                                                            delegate(Hashtable m_dhttpMethod) | ||||
|                                                            { | ||||
|                                                                return gmeshHandler.ProcessGetMesh(m_dhttpMethod, UUID.Zero, null); | ||||
|                                                            }); | ||||
|                 IRequestHandler reqHandler | ||||
|                     = new RestHTTPHandler( | ||||
|                         "GET", | ||||
|                         "/CAPS/" + UUID.Random(), | ||||
|                         httpMethod => gmeshHandler.ProcessGetMesh(httpMethod, UUID.Zero, null), | ||||
|                         "GetMesh", | ||||
|                         agentID.ToString()); | ||||
| 
 | ||||
|                 caps.RegisterHandler("GetMesh", reqHandler); | ||||
|             } | ||||
|  |  | |||
|  | @ -130,7 +130,9 @@ namespace OpenSim.Region.ClientStack.Linden | |||
|             if (m_URL == "localhost") | ||||
|             { | ||||
| //                m_log.DebugFormat("[GETTEXTURE]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName); | ||||
|                 caps.RegisterHandler("GetTexture", new GetTextureHandler("/CAPS/" + capID + "/", m_assetService)); | ||||
|                 caps.RegisterHandler( | ||||
|                     "GetTexture", | ||||
|                     new GetTextureHandler("/CAPS/" + capID + "/", m_assetService, "GetTexture", agentID.ToString())); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|  |  | |||
|  | @ -117,7 +117,9 @@ namespace OpenSim.Region.ClientStack.Linden | |||
| 
 | ||||
|         public void RegisterCaps(UUID agentID, Caps caps) | ||||
|         { | ||||
|             IRequestHandler reqHandler = new RestHTTPHandler("GET", "/CAPS/" + UUID.Random(), MeshUploadFlag); | ||||
|             IRequestHandler reqHandler | ||||
|                 = new RestHTTPHandler("GET", "/CAPS/" + UUID.Random(), MeshUploadFlag, "MeshUploadFlag", agentID.ToString()); | ||||
| 
 | ||||
|             caps.RegisterHandler("MeshUploadFlag", reqHandler); | ||||
| 	        m_agentID = agentID; | ||||
|         } | ||||
|  |  | |||
|  | @ -56,6 +56,7 @@ namespace OpenSim.Region.ClientStack.Linden | |||
| //        private IAssetService m_assetService; | ||||
|         private bool m_dumpAssetsToFile = false; | ||||
|         private bool m_enabled = true; | ||||
|         private int  m_levelUpload = 0; | ||||
| 
 | ||||
|         #region IRegionModuleBase Members | ||||
| 
 | ||||
|  | @ -72,6 +73,7 @@ namespace OpenSim.Region.ClientStack.Linden | |||
|                 return; | ||||
| 
 | ||||
|             m_enabled = meshConfig.GetBoolean("AllowMeshUpload", true); | ||||
|             m_levelUpload = meshConfig.GetInt("LevelUpload", 0); | ||||
|         } | ||||
| 
 | ||||
|         public void AddRegion(Scene pScene) | ||||
|  | @ -113,51 +115,66 @@ namespace OpenSim.Region.ClientStack.Linden | |||
|             UUID capID = UUID.Random(); | ||||
| 
 | ||||
| //            m_log.Debug("[NEW FILE AGENT INVENTORY VARIABLE PRICE]: /CAPS/" + capID); | ||||
|             caps.RegisterHandler("NewFileAgentInventoryVariablePrice", | ||||
| 
 | ||||
|                     new LLSDStreamhandler<LLSDAssetUploadRequest, LLSDNewFileAngentInventoryVariablePriceReplyResponse>("POST", | ||||
|                                                                                            "/CAPS/" + capID.ToString(), | ||||
|                                                                                            delegate(LLSDAssetUploadRequest req) | ||||
|                                                        { | ||||
|                                                            return NewAgentInventoryRequest(req,agentID); | ||||
|                                                        })); | ||||
|           | ||||
|             caps.RegisterHandler( | ||||
|                 "NewFileAgentInventoryVariablePrice", | ||||
|                 new LLSDStreamhandler<LLSDAssetUploadRequest, LLSDNewFileAngentInventoryVariablePriceReplyResponse>( | ||||
|                     "POST", | ||||
|                     "/CAPS/" + capID.ToString(), | ||||
|                     req => NewAgentInventoryRequest(req, agentID), | ||||
|                     "NewFileAgentInventoryVariablePrice", | ||||
|                     agentID.ToString()));          | ||||
|         } | ||||
| 
 | ||||
|         #endregion | ||||
| 
 | ||||
|         public LLSDNewFileAngentInventoryVariablePriceReplyResponse NewAgentInventoryRequest(LLSDAssetUploadRequest llsdRequest, UUID agentID) | ||||
|         { | ||||
| 
 | ||||
|             //TODO:  The Mesh uploader uploads many types of content. If you're going to implement a Money based limit | ||||
|             // You need to be aware of this and  | ||||
| 
 | ||||
|             // you need to be aware of this | ||||
| 
 | ||||
|             //if (llsdRequest.asset_type == "texture" || | ||||
|            //     llsdRequest.asset_type == "animation" || | ||||
|            //     llsdRequest.asset_type == "sound") | ||||
|            // { | ||||
|                 IClientAPI client = null; | ||||
|                 // check user level | ||||
| 
 | ||||
|                  | ||||
|                 IMoneyModule mm = m_scene.RequestModuleInterface<IMoneyModule>(); | ||||
|                  | ||||
|                 if (mm != null) | ||||
|             ScenePresence avatar = null; | ||||
|             IClientAPI client = null; | ||||
|             m_scene.TryGetScenePresence(agentID, out avatar); | ||||
| 
 | ||||
|             if (avatar != null) | ||||
|             { | ||||
|                 client = avatar.ControllingClient; | ||||
| 
 | ||||
|                 if (avatar.UserLevel < m_levelUpload) | ||||
|                 { | ||||
|                     if (m_scene.TryGetClient(agentID, out client)) | ||||
|                     { | ||||
|                         if (!mm.UploadCovered(client.AgentId, mm.UploadCharge)) | ||||
|                         { | ||||
|                             if (client != null) | ||||
|                                 client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false); | ||||
|                     if (client != null) | ||||
|                         client.SendAgentAlertMessage("Unable to upload asset. Insufficient permissions.", false); | ||||
| 
 | ||||
|                             LLSDNewFileAngentInventoryVariablePriceReplyResponse errorResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse(); | ||||
|                             errorResponse.rsvp = ""; | ||||
|                             errorResponse.state = "error"; | ||||
|                             return errorResponse; | ||||
|                         } | ||||
|                     } | ||||
|                     LLSDNewFileAngentInventoryVariablePriceReplyResponse errorResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse(); | ||||
|                     errorResponse.rsvp = ""; | ||||
|                     errorResponse.state = "error"; | ||||
|                     return errorResponse; | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             // check funds | ||||
|             IMoneyModule mm = m_scene.RequestModuleInterface<IMoneyModule>(); | ||||
| 
 | ||||
|             if (mm != null) | ||||
|             { | ||||
|                 if (!mm.UploadCovered(agentID, mm.UploadCharge)) | ||||
|                 { | ||||
|                     if (client != null) | ||||
|                         client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false); | ||||
| 
 | ||||
|                     LLSDNewFileAngentInventoryVariablePriceReplyResponse errorResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse(); | ||||
|                     errorResponse.rsvp = ""; | ||||
|                     errorResponse.state = "error"; | ||||
|                     return errorResponse; | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|            // } | ||||
| 
 | ||||
|             string assetName = llsdRequest.name; | ||||
|  | @ -171,8 +188,14 @@ namespace OpenSim.Region.ClientStack.Linden | |||
|             AssetUploader uploader = | ||||
|                 new AssetUploader(assetName, assetDes, newAsset, newInvItem, parentFolder, llsdRequest.inventory_type, | ||||
|                                   llsdRequest.asset_type, capsBase + uploaderPath, MainServer.Instance, m_dumpAssetsToFile); | ||||
| 
 | ||||
|             MainServer.Instance.AddStreamHandler( | ||||
|                 new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps)); | ||||
|                 new BinaryStreamHandler( | ||||
|                     "POST", | ||||
|                     capsBase + uploaderPath, | ||||
|                     uploader.uploaderCaps, | ||||
|                     "NewFileAgentInventoryVariablePrice", | ||||
|                     agentID.ToString())); | ||||
| 
 | ||||
|             string protocol = "http://"; | ||||
| 
 | ||||
|  | @ -181,10 +204,9 @@ namespace OpenSim.Region.ClientStack.Linden | |||
| 
 | ||||
|             string uploaderURL = protocol + m_scene.RegionInfo.ExternalHostName + ":" + MainServer.Instance.Port.ToString() + capsBase + | ||||
|                                  uploaderPath; | ||||
|           | ||||
| 
 | ||||
| 
 | ||||
|             LLSDNewFileAngentInventoryVariablePriceReplyResponse uploadResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse(); | ||||
|             | ||||
|              | ||||
|             uploadResponse.rsvp = uploaderURL; | ||||
|             uploadResponse.state = "upload"; | ||||
|  | @ -202,6 +224,7 @@ namespace OpenSim.Region.ClientStack.Linden | |||
|                                           pinventoryItem, pparentFolder, pdata,  pinventoryType, | ||||
|                                           passetType,agentID); | ||||
|                }; | ||||
| 
 | ||||
|             return uploadResponse; | ||||
|         } | ||||
| 
 | ||||
|  |  | |||
|  | @ -66,12 +66,14 @@ namespace OpenSim.Region.ClientStack.Linden | |||
|              | ||||
| //            m_log.InfoFormat("[OBJECTADD]: {0}", "/CAPS/OA/" + capuuid + "/"); | ||||
| 
 | ||||
|             caps.RegisterHandler("ObjectAdd", | ||||
|                                  new RestHTTPHandler("POST", "/CAPS/OA/" + capuuid + "/", | ||||
|                                                        delegate(Hashtable m_dhttpMethod) | ||||
|                                                        { | ||||
|                                                            return ProcessAdd(m_dhttpMethod, agentID, caps); | ||||
|                                                        })); | ||||
|             caps.RegisterHandler( | ||||
|                 "ObjectAdd", | ||||
|                 new RestHTTPHandler( | ||||
|                     "POST", | ||||
|                     "/CAPS/OA/" + capuuid + "/", | ||||
|                     httpMethod => ProcessAdd(httpMethod, agentID, caps), | ||||
|                     "ObjectAdd", | ||||
|                     agentID.ToString()));; | ||||
|         } | ||||
| 
 | ||||
|         public Hashtable ProcessAdd(Hashtable request, UUID AgentId, Caps cap) | ||||
|  |  | |||
|  | @ -106,12 +106,15 @@ namespace OpenSim.Region.ClientStack.Linden | |||
|             UUID capID = UUID.Random(); | ||||
| 
 | ||||
| //            m_log.Debug("[UPLOAD OBJECT ASSET MODULE]: /CAPS/" + capID); | ||||
|             caps.RegisterHandler("UploadObjectAsset", | ||||
|                                  new RestHTTPHandler("POST", "/CAPS/OA/" + capID + "/", | ||||
|                                                        delegate(Hashtable m_dhttpMethod) | ||||
|                                                        { | ||||
|                                                            return ProcessAdd(m_dhttpMethod, agentID, caps); | ||||
|                                                        })); | ||||
|             caps.RegisterHandler( | ||||
|                 "UploadObjectAsset", | ||||
|                 new RestHTTPHandler( | ||||
|                     "POST", | ||||
|                     "/CAPS/OA/" + capID + "/", | ||||
|                     httpMethod => ProcessAdd(httpMethod, agentID, caps), | ||||
|                     "UploadObjectAsset", | ||||
|                     agentID.ToString())); | ||||
| 
 | ||||
|             /* | ||||
|                    caps.RegisterHandler("NewFileAgentInventoryVariablePrice", | ||||
| 
 | ||||
|  | @ -330,7 +333,6 @@ namespace OpenSim.Region.ClientStack.Linden | |||
|                 grp.AbsolutePosition = obj.Position; | ||||
|                 prim.RotationOffset = obj.Rotation; | ||||
|                  | ||||
|                 grp.IsAttachment = false; | ||||
|                 // Required for linking | ||||
|                 grp.RootPart.ClearUpdateSchedule(); | ||||
|                  | ||||
|  |  | |||
|  | @ -154,7 +154,9 @@ namespace OpenSim.Region.ClientStack.Linden | |||
|         public void RegisterCaps(UUID agentID, Caps caps) | ||||
|         { | ||||
|             IRequestHandler reqHandler | ||||
|                 = new RestHTTPHandler("GET", "/CAPS/" + UUID.Random(), HandleSimulatorFeaturesRequest); | ||||
|                 = new RestHTTPHandler( | ||||
|                     "GET", "/CAPS/" + UUID.Random(), | ||||
|                     HandleSimulatorFeaturesRequest, "SimulatorFeatures", agentID.ToString()); | ||||
| 
 | ||||
|             caps.RegisterHandler("SimulatorFeatures", reqHandler); | ||||
|         } | ||||
|  |  | |||
|  | @ -106,7 +106,9 @@ namespace OpenSim.Region.ClientStack.Linden | |||
|                     "POST", | ||||
|                     "/CAPS/" + caps.CapsObjectPath + m_uploadBakedTexturePath, | ||||
|                     new UploadBakedTextureHandler( | ||||
|                         caps, m_scene.AssetService, m_persistBakedTextures).UploadBakedTexture)); | ||||
|                         caps, m_scene.AssetService, m_persistBakedTextures).UploadBakedTexture, | ||||
|                     "UploadBakedTexture", | ||||
|                     agentID.ToString())); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -144,7 +144,12 @@ namespace OpenSim.Region.ClientStack.Linden | |||
|                 capUrl = "/CAPS/" + UUID.Random(); | ||||
| 
 | ||||
|                 IRequestHandler reqHandler | ||||
|                     = new RestStreamHandler("POST", capUrl, m_webFetchHandler.FetchInventoryDescendentsRequest); | ||||
|                     = new RestStreamHandler( | ||||
|                         "POST", | ||||
|                         capUrl, | ||||
|                         m_webFetchHandler.FetchInventoryDescendentsRequest, | ||||
|                         "FetchInventoryDescendents2", | ||||
|                         agentID.ToString()); | ||||
| 
 | ||||
|                 caps.RegisterHandler(capName, reqHandler); | ||||
|             } | ||||
|  | @ -160,4 +165,4 @@ namespace OpenSim.Region.ClientStack.Linden | |||
| //                capName, capUrl, m_scene.RegionInfo.RegionName, agentID); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| } | ||||
|  | @ -39,7 +39,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|     public sealed class IncomingPacket | ||||
|     { | ||||
|         /// <summary>Client this packet came from</summary> | ||||
|         public LLUDPClient Client; | ||||
|         public LLClientView Client; | ||||
| 
 | ||||
|         /// <summary>Packet data that has been received</summary> | ||||
|         public Packet Packet; | ||||
| 
 | ||||
|  | @ -48,7 +49,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|         /// </summary> | ||||
|         /// <param name="client">Reference to the client this packet came from</param> | ||||
|         /// <param name="packet">Packet data</param> | ||||
|         public IncomingPacket(LLUDPClient client, Packet packet) | ||||
|         public IncomingPacket(LLClientView client, Packet packet) | ||||
|         { | ||||
|             Client = client; | ||||
|             Packet = packet; | ||||
|  |  | |||
|  | @ -59,7 +59,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|     /// Handles new client connections | ||||
|     /// Constructor takes a single Packet and authenticates everything | ||||
|     /// </summary> | ||||
|     public class LLClientView : IClientAPI, IClientCore, IClientIM, IClientChat, IClientIPEndpoint, IStatsCollector | ||||
|     public class LLClientView : IClientAPI, IClientCore, IClientIM, IClientChat, IClientInventory, IStatsCollector | ||||
|     { | ||||
|         /// <value> | ||||
|         /// Debug packet level.  See OpenSim.RegisterConsoleCommands() for more details. | ||||
|  | @ -348,8 +348,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|         private int m_animationSequenceNumber = 1; | ||||
|         private bool m_SendLogoutPacketWhenClosing = true; | ||||
|         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<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 Thread m_clientThread; | ||||
|         protected Vector3 m_startpos; | ||||
|         protected EndPoint m_userEndPoint; | ||||
|         protected UUID m_activeGroupID; | ||||
|         protected string m_activeGroupName = String.Empty; | ||||
|         protected ulong m_activeGroupPowers; | ||||
|  | @ -385,7 +382,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|             set { m_startpos = value; } | ||||
|         } | ||||
|         public UUID AgentId { get { return m_agentId; } } | ||||
|         public ISceneAgent SceneAgent { get; private set; } | ||||
|         public ISceneAgent SceneAgent { get; set; } | ||||
|         public UUID ActiveGroupId { get { return m_activeGroupID; } } | ||||
|         public string ActiveGroupName { get { return m_activeGroupName; } } | ||||
|         public ulong ActiveGroupPowers { get { return m_activeGroupPowers; } } | ||||
|  | @ -414,16 +411,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|         public uint CircuitCode { get { return m_circuitCode; } } | ||||
|         public int MoneyBalance { get { return m_moneyBalance; } } | ||||
|         public int NextAnimationSequenceNumber { get { return m_animationSequenceNumber++; } } | ||||
|         public bool IsActive | ||||
|         { | ||||
|             get { return m_IsActive; } | ||||
|             set { m_IsActive = value; } | ||||
|         } | ||||
|         public bool IsLoggingOut | ||||
|         { | ||||
|             get { return m_IsLoggingOut; } | ||||
|             set { m_IsLoggingOut = value; } | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// As well as it's function in IClientAPI, in LLClientView we are locking on this property in order to | ||||
|         /// prevent race conditions by different threads calling Close(). | ||||
|         /// </summary> | ||||
|         public bool IsActive { get; set; } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Used to synchronise threads when client is being closed. | ||||
|         /// </summary> | ||||
|         public Object CloseSyncLock { get; private set; } | ||||
| 
 | ||||
|         public bool IsLoggingOut { get; set; } | ||||
| 
 | ||||
|         public bool DisableFacelights | ||||
|         { | ||||
|  | @ -443,14 +443,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|         /// <summary> | ||||
|         /// Constructor | ||||
|         /// </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) | ||||
|         { | ||||
| //            DebugPacketLevel = 1; | ||||
| 
 | ||||
|             CloseSyncLock = new Object(); | ||||
| 
 | ||||
|             RegisterInterface<IClientIM>(this); | ||||
|             RegisterInterface<IClientInventory>(this); | ||||
|             RegisterInterface<IClientChat>(this); | ||||
|             RegisterInterface<IClientIPEndpoint>(this); | ||||
| 
 | ||||
|             InitDefaultAnimations(); | ||||
| 
 | ||||
|  | @ -470,7 +472,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|             m_sessionId = sessionId; | ||||
|             m_secureSessionId = sessionInfo.LoginInfo.SecureSession; | ||||
|             m_circuitCode = circuitCode; | ||||
|             m_userEndPoint = remoteEP; | ||||
|             m_firstName = sessionInfo.LoginInfo.First; | ||||
|             m_lastName = sessionInfo.LoginInfo.Last; | ||||
|             m_startpos = sessionInfo.LoginInfo.StartPos; | ||||
|  | @ -484,25 +485,48 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|             m_prioritizer = new Prioritizer(m_scene); | ||||
| 
 | ||||
|             RegisterLocalPacketHandlers(); | ||||
| 
 | ||||
|             IsActive = true; | ||||
|         } | ||||
| 
 | ||||
|         #region Client Methods | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Shut down the client view | ||||
|         /// </summary> | ||||
|         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( | ||||
|                 "[CLIENT]: Close has been called for {0} attached to scene {1}", | ||||
|                 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 | ||||
|             ImageManager.Close(); | ||||
| 
 | ||||
|  | @ -698,7 +722,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
| 
 | ||||
|         public virtual void Start() | ||||
|         { | ||||
|             SceneAgent = m_scene.AddNewClient(this, PresenceType.User); | ||||
|             m_scene.AddNewClient(this, PresenceType.User); | ||||
| 
 | ||||
|             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) | ||||
|         { | ||||
| 
 | ||||
|  | @ -3563,7 +3600,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
| 
 | ||||
|         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); | ||||
|             loc.Header.Reliable = false; | ||||
|  | @ -3728,8 +3767,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|                         } | ||||
|                     } | ||||
|      | ||||
|                     ++updatesThisCall; | ||||
|      | ||||
|                     #region UpdateFlags to packet type conversion | ||||
|      | ||||
|                     PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags; | ||||
|  | @ -3786,20 +3823,53 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|      | ||||
|                     if (!canUseImproved && !canUseCompressed) | ||||
|                     { | ||||
|                         ObjectUpdatePacket.ObjectDataBlock updateBlock; | ||||
| 
 | ||||
|                         if (update.Entity is ScenePresence) | ||||
|                         { | ||||
|                             objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity)); | ||||
|                             objectUpdates.Value.Add(update); | ||||
|                             updateBlock = CreateAvatarUpdateBlock((ScenePresence)update.Entity); | ||||
|                         } | ||||
|                         else | ||||
|                         { | ||||
|                             objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId)); | ||||
|                             objectUpdates.Value.Add(update); | ||||
|                             SceneObjectPart part = (SceneObjectPart)update.Entity; | ||||
|                             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) | ||||
|                     { | ||||
|                         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); | ||||
|                     } | ||||
|                     else | ||||
|  | @ -3812,15 +3882,40 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|                         } | ||||
|                         else | ||||
|                         { | ||||
|                             ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseUpdateBlock | ||||
|                                 = CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)); | ||||
| 
 | ||||
|                             // 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); | ||||
|                         } | ||||
|                     } | ||||
| 
 | ||||
|                     ++updatesThisCall; | ||||
|      | ||||
|                     #endregion Block Construction | ||||
|                 } | ||||
|                  | ||||
|      | ||||
|                 #region Packet Sending | ||||
|                 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f); | ||||
|  | @ -4273,7 +4368,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|                 block.OwnerID = sop.OwnerID; | ||||
| 
 | ||||
|             block.ItemID = sop.FromUserInventoryItemID; | ||||
|             block.FolderID = UUID.Zero; // sop.FromFolderID ?? | ||||
|             block.FolderID = UUID.Zero; // sog.FromFolderID ?? | ||||
|             block.FromTaskID = UUID.Zero; // ??? | ||||
|             block.InventorySerial = (short)sop.InventorySerial; | ||||
|              | ||||
|  | @ -4959,7 +5054,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|             update.MediaURL = Utils.EmptyBytes; // FIXME: Support this in OpenSim | ||||
|             if (data.ParentGroup.IsAttachment) | ||||
|             { | ||||
|                 update.NameValue = Util.StringToBytes256("AttachItemID STRING RW SV " + data.FromItemID); | ||||
|                 update.NameValue = Util.StringToBytes256("AttachItemID STRING RW SV " + data.ParentGroup.FromItemID); | ||||
|                 update.State = (byte)((data.ParentGroup.AttachmentPoint % 16) * 16 + (data.ParentGroup.AttachmentPoint / 16)); | ||||
|             } | ||||
|             else | ||||
|  | @ -5104,7 +5199,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|             AddLocalPacketHandler(PacketType.ChatFromViewer, HandleChatFromViewer); | ||||
|             AddLocalPacketHandler(PacketType.AvatarPropertiesUpdate, HandlerAvatarPropertiesUpdate); | ||||
|             AddLocalPacketHandler(PacketType.ScriptDialogReply, HandlerScriptDialogReply); | ||||
|             AddLocalPacketHandler(PacketType.ImprovedInstantMessage, HandlerImprovedInstantMessage, false); | ||||
|             AddLocalPacketHandler(PacketType.ImprovedInstantMessage, HandlerImprovedInstantMessage); | ||||
|             AddLocalPacketHandler(PacketType.AcceptFriendship, HandlerAcceptFriendship); | ||||
|             AddLocalPacketHandler(PacketType.DeclineFriendship, HandlerDeclineFriendship); | ||||
|             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 | ||||
|             List<UUID> callingCardFolders = new List<UUID>(); | ||||
| 
 | ||||
|             UUID agentID = afriendpack.AgentData.AgentID; | ||||
|             UUID transactionID = afriendpack.TransactionBlock.TransactionID; | ||||
| 
 | ||||
|             for (int fi = 0; fi < afriendpack.FolderData.Length; fi++) | ||||
|  | @ -5798,10 +5892,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|             FriendActionDelegate handlerApproveFriendRequest = OnApproveFriendRequest; | ||||
|             if (handlerApproveFriendRequest != null) | ||||
|             { | ||||
|                 handlerApproveFriendRequest(this, agentID, transactionID, callingCardFolders); | ||||
|                 handlerApproveFriendRequest(this, transactionID, callingCardFolders); | ||||
|             } | ||||
|             return true; | ||||
| 
 | ||||
|             return true; | ||||
|         } | ||||
| 
 | ||||
|         private bool HandlerDeclineFriendship(IClientAPI sender, Packet Pack) | ||||
|  | @ -5820,7 +5914,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|             if (OnDenyFriendRequest != null) | ||||
|             { | ||||
|                 OnDenyFriendRequest(this, | ||||
|                                     dfriendpack.AgentData.AgentID, | ||||
|                                     dfriendpack.TransactionBlock.TransactionID, | ||||
|                                     null); | ||||
|             } | ||||
|  | @ -5840,14 +5933,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|             } | ||||
|             #endregion | ||||
| 
 | ||||
|             UUID listOwnerAgentID = tfriendpack.AgentData.AgentID; | ||||
|             UUID exFriendID = tfriendpack.ExBlock.OtherID; | ||||
|             FriendshipTermination TerminateFriendshipHandler = OnTerminateFriendship; | ||||
|             if (TerminateFriendshipHandler != null) | ||||
|             { | ||||
|                 TerminateFriendshipHandler(this, listOwnerAgentID, exFriendID); | ||||
|                 TerminateFriendshipHandler(this, exFriendID); | ||||
|                 return true; | ||||
|             } | ||||
| 
 | ||||
|             return false; | ||||
|         } | ||||
| 
 | ||||
|  | @ -11165,12 +11258,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|                     return true; | ||||
|             } | ||||
|             #endregion | ||||
| 
 | ||||
|             GrantUserFriendRights GrantUserRightsHandler = OnGrantUserRights; | ||||
|             if (GrantUserRightsHandler != null) | ||||
|                 GrantUserRightsHandler(this, | ||||
|                     GrantUserRights.AgentData.AgentID, | ||||
|                     GrantUserRights.Rights[0].AgentRelated, | ||||
|                     GrantUserRights.Rights[0].RelatedRights); | ||||
| 
 | ||||
|             return true; | ||||
|         } | ||||
| 
 | ||||
|  | @ -11683,7 +11777,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|                 if (DebugPacketLevel <= 100 && (packet.Type == PacketType.AvatarAnimation || packet.Type == PacketType.ViewerEffect)) | ||||
|                     logPacket = false; | ||||
|                  | ||||
|                 if (DebugPacketLevel <= 50 && packet.Type == PacketType.ImprovedTerseObjectUpdate) | ||||
|                 if (DebugPacketLevel <= 50 | ||||
|                     & (packet.Type == PacketType.ImprovedTerseObjectUpdate || packet.Type == PacketType.ObjectUpdate)) | ||||
|                     logPacket = false; | ||||
| 
 | ||||
|                 if (DebugPacketLevel <= 25 && packet.Type == PacketType.ObjectPropertiesFamily) | ||||
|  | @ -11796,7 +11891,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|         { | ||||
|             ClientInfo info = m_udpClient.GetClientInfo(); | ||||
| 
 | ||||
|             info.userEP = m_userEndPoint; | ||||
|             info.proxyEP = null; | ||||
|             info.agentcircuit = RequestClientInfo(); | ||||
| 
 | ||||
|  | @ -11808,11 +11902,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|             m_udpClient.SetClientInfo(info); | ||||
|         } | ||||
| 
 | ||||
|         public EndPoint GetClientEP() | ||||
|         { | ||||
|             return m_userEndPoint; | ||||
|         } | ||||
| 
 | ||||
|         #region Media Parcel Members | ||||
| 
 | ||||
|         public void SendParcelMediaCommand(uint flags, ParcelMediaCommandEnum command, float time) | ||||
|  | @ -11893,10 +11982,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|             return string.Empty; | ||||
|         } | ||||
| 
 | ||||
|         public void KillEndDone() | ||||
|         { | ||||
|         } | ||||
| 
 | ||||
|         #region IClientCore | ||||
| 
 | ||||
|         private readonly Dictionary<Type, object> m_clientInterfaces = new Dictionary<Type, object>(); | ||||
|  | @ -11937,7 +12022,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|         { | ||||
|             Kick(reason); | ||||
|             Thread.Sleep(1000); | ||||
|             Close(); | ||||
|             Disconnect(); | ||||
|         } | ||||
| 
 | ||||
|         public void Disconnect() | ||||
|  | @ -11984,21 +12069,24 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|         protected void MakeAssetRequest(TransferRequestPacket transferRequest, UUID taskID) | ||||
|         { | ||||
|             UUID requestID = UUID.Zero; | ||||
|             if (transferRequest.TransferInfo.SourceType == (int)SourceType.Asset) | ||||
|             int sourceType = transferRequest.TransferInfo.SourceType; | ||||
| 
 | ||||
|             if (sourceType == (int)SourceType.Asset) | ||||
|             { | ||||
|                 requestID = new UUID(transferRequest.TransferInfo.Params, 0); | ||||
|             } | ||||
|             else if (transferRequest.TransferInfo.SourceType == (int)SourceType.SimInventoryItem) | ||||
|             else if (sourceType == (int)SourceType.SimInventoryItem) | ||||
|             { | ||||
|                 requestID = new UUID(transferRequest.TransferInfo.Params, 80); | ||||
|             } | ||||
|             else if (transferRequest.TransferInfo.SourceType == (int)SourceType.SimEstate) | ||||
|             else if (sourceType == (int)SourceType.SimEstate) | ||||
|             { | ||||
|                 requestID = taskID; | ||||
|             } | ||||
| 
 | ||||
| 
 | ||||
| //            m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID); | ||||
| //            m_log.DebugFormat( | ||||
| //                "[LLCLIENTVIEW]: Received transfer request for {0} in {1} type {2} by {3}", | ||||
| //                requestID, taskID, (SourceType)sourceType, Name); | ||||
| 
 | ||||
|             m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived); | ||||
|         } | ||||
|  | @ -12011,14 +12099,27 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|         /// <param name="asset"></param> | ||||
|         protected void AssetReceived(string id, Object sender, AssetBase asset) | ||||
|         { | ||||
|             if (asset == null) | ||||
|                 return; | ||||
| 
 | ||||
|             TransferRequestPacket transferRequest = (TransferRequestPacket)sender; | ||||
| 
 | ||||
|             UUID requestID = UUID.Zero; | ||||
|             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) | ||||
|             { | ||||
|                 requestID = new UUID(transferRequest.TransferInfo.Params, 0); | ||||
|  | @ -12035,7 +12136,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|                 return; | ||||
| 
 | ||||
|             // 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.AssetRequestSource = source; | ||||
|             req.IsTextureRequest = false; | ||||
|  | @ -12071,24 +12171,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|             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) | ||||
|         { | ||||
|             RebakeAvatarTexturesPacket pack = | ||||
|  | @ -12292,5 +12374,175 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|             if (reply != null) | ||||
|                 OutPacket(reply, ThrottleOutPacketType.Task); | ||||
|         } | ||||
| 
 | ||||
|         public void SendRemoveInventoryItems(UUID[] items) | ||||
|         { | ||||
|             IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>(); | ||||
| 
 | ||||
|             if (eq == null) | ||||
|             { | ||||
|                 m_log.DebugFormat("[LLCLIENT]: Null event queue"); | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             OSDMap llsd = new OSDMap(3); | ||||
| 
 | ||||
|             OSDMap AgentDataMap = new OSDMap(1); | ||||
|             AgentDataMap.Add("AgentID", OSD.FromUUID(AgentId)); | ||||
|             AgentDataMap.Add("SessionID", OSD.FromUUID(SessionId)); | ||||
| 
 | ||||
|             OSDArray AgentData = new OSDArray(1); | ||||
|             AgentData.Add(AgentDataMap); | ||||
| 
 | ||||
|             llsd.Add("AgentData", AgentData); | ||||
| 
 | ||||
|             OSDArray ItemData = new OSDArray(); | ||||
| 
 | ||||
|             foreach (UUID item in items) | ||||
|             { | ||||
|                 OSDMap ItemDataMap = new OSDMap(2); | ||||
|                 ItemDataMap.Add("ItemID", OSD.FromUUID(item)); | ||||
|                 ItemDataMap.Add("AgentID", OSD.FromUUID(AgentId)); | ||||
| 
 | ||||
|                 ItemData.Add(ItemDataMap); | ||||
|             } | ||||
| 
 | ||||
|             llsd.Add("InventoryData", ItemData); | ||||
| 
 | ||||
|             eq.Enqueue(BuildEvent("RemoveInventoryItem", | ||||
|                     llsd), AgentId); | ||||
|         } | ||||
| 
 | ||||
|         public void SendRemoveInventoryFolders(UUID[] folders) | ||||
|         { | ||||
|             IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>(); | ||||
| 
 | ||||
|             if (eq == null) | ||||
|             { | ||||
|                 m_log.DebugFormat("[LLCLIENT]: Null event queue"); | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             OSDMap llsd = new OSDMap(3); | ||||
| 
 | ||||
|             OSDMap AgentDataMap = new OSDMap(1); | ||||
|             AgentDataMap.Add("AgentID", OSD.FromUUID(AgentId)); | ||||
|             AgentDataMap.Add("SessionID", OSD.FromUUID(SessionId)); | ||||
| 
 | ||||
|             OSDArray AgentData = new OSDArray(1); | ||||
|             AgentData.Add(AgentDataMap); | ||||
| 
 | ||||
|             llsd.Add("AgentData", AgentData); | ||||
| 
 | ||||
|             OSDArray FolderData = new OSDArray(); | ||||
| 
 | ||||
|             foreach (UUID folder in folders) | ||||
|             { | ||||
|                 OSDMap FolderDataMap = new OSDMap(2); | ||||
|                 FolderDataMap.Add("FolderID", OSD.FromUUID(folder)); | ||||
|                 FolderDataMap.Add("AgentID", OSD.FromUUID(AgentId)); | ||||
| 
 | ||||
|                 FolderData.Add(FolderDataMap); | ||||
|             } | ||||
| 
 | ||||
|             llsd.Add("FolderData", FolderData); | ||||
| 
 | ||||
|             eq.Enqueue(BuildEvent("RemoveInventoryFolder", | ||||
|                     llsd), AgentId); | ||||
|         } | ||||
| 
 | ||||
|         private byte[] EncodeU32(uint val) | ||||
|         { | ||||
|             byte[] ret = BitConverter.GetBytes(val); | ||||
|             if (BitConverter.IsLittleEndian) | ||||
|                 Array.Reverse(ret); | ||||
|             return ret; | ||||
|         } | ||||
| 
 | ||||
|         public void SendBulkUpdateInventory(InventoryFolderBase[] folders, InventoryItemBase[] items) | ||||
|         { | ||||
|             IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>(); | ||||
| 
 | ||||
|             if (eq == null) | ||||
|             { | ||||
|                 m_log.DebugFormat("[LLCLIENT]: Null event queue"); | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             OSDMap llsd = new OSDMap(3); | ||||
| 
 | ||||
|             OSDMap AgentDataMap = new OSDMap(1); | ||||
|             AgentDataMap.Add("AgentID", OSD.FromUUID(AgentId)); | ||||
|             AgentDataMap.Add("SessionID", OSD.FromUUID(SessionId)); | ||||
|             AgentDataMap.Add("TransactionID", OSD.FromUUID(UUID.Random())); | ||||
| 
 | ||||
|             OSDArray AgentData = new OSDArray(1); | ||||
|             AgentData.Add(AgentDataMap); | ||||
| 
 | ||||
|             llsd.Add("AgentData", AgentData); | ||||
| 
 | ||||
|             OSDArray FolderData = new OSDArray(); | ||||
| 
 | ||||
|             foreach (InventoryFolderBase folder in folders) | ||||
|             { | ||||
|                 OSDMap FolderDataMap = new OSDMap(5); | ||||
|                 FolderDataMap.Add("FolderID", OSD.FromUUID(folder.ID)); | ||||
|                 FolderDataMap.Add("AgentID", OSD.FromUUID(AgentId)); | ||||
|                 FolderDataMap.Add("ParentID", OSD.FromUUID(folder.ParentID)); | ||||
|                 FolderDataMap.Add("Type", OSD.FromInteger(folder.Type)); | ||||
|                 FolderDataMap.Add("Name", OSD.FromString(folder.Name)); | ||||
| 
 | ||||
|                 FolderData.Add(FolderDataMap); | ||||
|             } | ||||
| 
 | ||||
|             llsd.Add("FolderData", FolderData); | ||||
| 
 | ||||
|             OSDArray ItemData = new OSDArray(); | ||||
| 
 | ||||
|             foreach (InventoryItemBase item in items) | ||||
|             { | ||||
|                 OSDMap ItemDataMap = new OSDMap(); | ||||
|                  | ||||
|                 ItemDataMap.Add("ItemID", OSD.FromUUID(item.ID)); | ||||
|                 ItemDataMap.Add("FolderID", OSD.FromUUID(item.Folder)); | ||||
| 
 | ||||
|                 ItemDataMap.Add("CreatorID", OSD.FromUUID(item.CreatorIdAsUuid)); | ||||
|                 ItemDataMap.Add("OwnerID", OSD.FromUUID(item.Owner)); | ||||
|                 ItemDataMap.Add("GroupID", OSD.FromUUID(item.GroupID)); | ||||
|                 ItemDataMap.Add("BaseMask", OSD.FromBinary(EncodeU32((uint)item.BasePermissions))); | ||||
|                 ItemDataMap.Add("OwnerMask", OSD.FromBinary(EncodeU32((uint)item.CurrentPermissions))); | ||||
|                 ItemDataMap.Add("GroupMask", OSD.FromBinary(EncodeU32((uint)item.GroupPermissions))); | ||||
|                 ItemDataMap.Add("EveryoneMask", OSD.FromBinary(EncodeU32((uint)item.EveryOnePermissions))); | ||||
|                 ItemDataMap.Add("NextOwnerMask", OSD.FromBinary(EncodeU32((uint)item.NextPermissions))); | ||||
|                 ItemDataMap.Add("GroupOwned", OSD.FromBoolean(item.GroupOwned)); | ||||
|                 ItemDataMap.Add("AssetID", OSD.FromUUID(item.AssetID)); | ||||
|                 ItemDataMap.Add("Type", OSD.FromInteger(item.AssetType)); | ||||
|                 ItemDataMap.Add("InvType", OSD.FromInteger(item.InvType)); | ||||
|                 ItemDataMap.Add("Flags", OSD.FromBinary(EncodeU32((uint)item.Flags))); | ||||
|                 ItemDataMap.Add("SaleType", OSD.FromInteger((byte)item.SaleType)); | ||||
|                 ItemDataMap.Add("SalePrice", OSD.FromInteger(item.SalePrice)); | ||||
|                 ItemDataMap.Add("Name", OSD.FromString(item.Name)); | ||||
|                 ItemDataMap.Add("Description", OSD.FromString(item.Description)); | ||||
|                 ItemDataMap.Add("CreationDate", OSD.FromInteger(item.CreationDate)); | ||||
| 
 | ||||
|                 ItemDataMap.Add("CRC", OSD.FromBinary(EncodeU32( | ||||
|                         Helpers.InventoryCRC(1000, 0, (sbyte)item.InvType, | ||||
|                         (sbyte)item.AssetType, item.AssetID, | ||||
|                         item.GroupID, 100, | ||||
|                         item.Owner, item.CreatorIdAsUuid, | ||||
|                         item.ID, item.Folder, | ||||
|                         (uint)PermissionMask.All, 1, (uint)PermissionMask.All, (uint)PermissionMask.All, | ||||
|                         (uint)PermissionMask.All) | ||||
|                 ))); | ||||
|                 ItemDataMap.Add("CallbackID", 0); | ||||
| 
 | ||||
|                 ItemData.Add(ItemDataMap); | ||||
|             } | ||||
| 
 | ||||
|             llsd.Add("ItemData", ItemData); | ||||
| 
 | ||||
|             eq.Enqueue(BuildEvent("BulkUpdateInventory", | ||||
|                     llsd), AgentId); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -278,7 +278,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|         public string GetStats() | ||||
|         { | ||||
|             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,                                  | ||||
|                 PacketsSent, | ||||
|                 PacketsResent, | ||||
|  |  | |||
|  | @ -147,21 +147,34 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|         private int m_elapsed500MSOutgoingPacketHandler; | ||||
| 
 | ||||
|         /// <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> | ||||
|         private bool m_sendAcks; | ||||
|         protected bool m_sendAcks; | ||||
| 
 | ||||
|         /// <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_maxRTO = 0; | ||||
| 
 | ||||
|         private int m_ackTimeout = 0; | ||||
|         private int m_pausedAckTimeout = 0; | ||||
|         private bool m_disableFacelights = false; | ||||
| 
 | ||||
|         public Socket Server { get { return null; } } | ||||
| 
 | ||||
|         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) | ||||
|             : base(listenIP, (int)port) | ||||
|         { | ||||
|  | @ -198,11 +211,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|                 m_defaultRTO = config.GetInt("DefaultRTO", 0); | ||||
|                 m_maxRTO = config.GetInt("MaxRTO", 0); | ||||
|                 m_disableFacelights = config.GetBoolean("DisableFacelights", false); | ||||
|                 m_ackTimeout = 1000 * config.GetInt("AckTimeout", 60); | ||||
|                 m_pausedAckTimeout = 1000 * config.GetInt("PausedAckTimeout", 300); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 PrimUpdatesPerCallback = 100; | ||||
|                 TextureSendLimit = 20; | ||||
|                 m_ackTimeout = 1000 * 60; // 1 minute | ||||
|                 m_pausedAckTimeout = 1000 * 300; // 5 minutes | ||||
|             } | ||||
| 
 | ||||
|             #region BinaryStats | ||||
|  | @ -239,19 +256,56 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|             if (m_scene == null) | ||||
|                 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); | ||||
| 
 | ||||
|             // Start the packet processing threads | ||||
|             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( | ||||
|                 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; | ||||
|         } | ||||
| 
 | ||||
|         /// <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() | ||||
|         { | ||||
|             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); | ||||
|         } | ||||
| 
 | ||||
|         public void HandleUnacked(LLUDPClient udpClient) | ||||
|         public void HandleUnacked(LLClientView client) | ||||
|         { | ||||
|             LLUDPClient udpClient = client.UDPClient; | ||||
| 
 | ||||
|             if (!udpClient.IsConnected) | ||||
|                 return; | ||||
| 
 | ||||
|             // Disconnect an agent if no packets are received for some time | ||||
|             //FIXME: Make 60 an .ini setting | ||||
|             if ((Environment.TickCount & Int32.MaxValue) - udpClient.TickLastPacketReceived > 1000 * 60) | ||||
|             { | ||||
|                 m_log.Warn("[LLUDPSERVER]: Ack timeout, disconnecting " + udpClient.AgentID); | ||||
|                 StatsManager.SimExtraStats.AddAbnormalClientThreadTermination(); | ||||
|             int timeoutTicks = m_ackTimeout; | ||||
| 
 | ||||
|             // Allow more slack if the client is "paused" eg file upload dialogue is open | ||||
|             // Some sort of limit is needed in case the client crashes, loses its network connection | ||||
|             // 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; | ||||
|             } | ||||
| 
 | ||||
|  | @ -820,7 +889,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|             #endregion Ping Check Handling | ||||
| 
 | ||||
|             // Inbox insertion | ||||
|             packetInbox.Enqueue(new IncomingPacket(udpClient, packet)); | ||||
|             packetInbox.Enqueue(new IncomingPacket((LLClientView)client, packet)); | ||||
|         } | ||||
| 
 | ||||
|         #region BinaryStats | ||||
|  | @ -916,7 +985,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|                 UDPPacketBuffer buffer = (UDPPacketBuffer)array[0]; | ||||
|                 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; | ||||
|      | ||||
|  | @ -945,8 +1016,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|                 { | ||||
|                     // Don't create clients for unauthorized requesters. | ||||
|                     m_log.WarnFormat( | ||||
|                         "[LLUDPSERVER]: Connection request for client {0} connecting with unnotified circuit code {1} from {2}", | ||||
|                         uccp.CircuitCode.ID, uccp.CircuitCode.Code, remoteEndPoint); | ||||
|                         "[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}", | ||||
|                         uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, remoteEndPoint); | ||||
|                 } | ||||
|      | ||||
|                 //            m_log.DebugFormat( | ||||
|  | @ -1023,20 +1094,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|         { | ||||
|             IClientAPI client = null; | ||||
| 
 | ||||
|             // In priciple there shouldn't be more than one thread here, ever. | ||||
|             // But in case that happens, we need to synchronize this piece of code | ||||
|             // because it's too important | ||||
|             lock (this)  | ||||
|             // We currently synchronize this code across the whole scene to avoid issues such as | ||||
|             // http://opensimulator.org/mantis/view.php?id=5365  However, once locking per agent circuit can be done | ||||
|             // consistently, this lock could probably be removed. | ||||
|             lock (this) | ||||
|             { | ||||
|                 if (!m_scene.TryGetClient(agentID, out client)) | ||||
|                 { | ||||
|                     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; | ||||
| 
 | ||||
|      | ||||
|                     ((LLClientView)client).DisableFacelights = m_disableFacelights; | ||||
| 
 | ||||
|      | ||||
|                     client.Start(); | ||||
|                 } | ||||
|             } | ||||
|  | @ -1044,14 +1115,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|             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 | ||||
|             IClientAPI client; | ||||
|             if (m_scene.TryGetClient(udpClient.AgentID, out client)) | ||||
|             lock (client.CloseSyncLock) | ||||
|             { | ||||
|                 client.IsLoggingOut = true; | ||||
|                 client.Close(); | ||||
|                 m_log.WarnFormat( | ||||
|                     "[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 | ||||
|                     m_scene.ForEachClient(clientPacketHandler); | ||||
| 
 | ||||
|                     m_currentOutgoingClient = null; | ||||
| 
 | ||||
|                     // If nothing was sent, sleep for the minimum amount of time before a | ||||
|                     // token bucket could get more tokens | ||||
|                     if (!m_packetSent) | ||||
|  | @ -1175,18 +1262,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|             Watchdog.RemoveThread(); | ||||
|         } | ||||
| 
 | ||||
|         private void ClientOutgoingPacketHandler(IClientAPI client) | ||||
|         protected void ClientOutgoingPacketHandler(IClientAPI client) | ||||
|         { | ||||
|             m_currentOutgoingClient = client; | ||||
| 
 | ||||
|             try | ||||
|             { | ||||
|                 if (client is LLClientView) | ||||
|                 { | ||||
|                     LLUDPClient udpClient = ((LLClientView)client).UDPClient; | ||||
|                     LLClientView llClient = (LLClientView)client; | ||||
|                     LLUDPClient udpClient = llClient.UDPClient; | ||||
| 
 | ||||
|                     if (udpClient.IsConnected) | ||||
|                     { | ||||
|                         if (m_resendUnacked) | ||||
|                             HandleUnacked(udpClient); | ||||
|                             HandleUnacked(llClient); | ||||
| 
 | ||||
|                         if (m_sendAcks) | ||||
|                             SendAcks(udpClient); | ||||
|  | @ -1202,8 +1292,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|             } | ||||
|             catch (Exception ex) | ||||
|             { | ||||
|                 m_log.Error("[LLUDPSERVER]: OutgoingPacketHandler iteration for " + client.Name + | ||||
|                     " threw an exception: " + ex.Message, ex); | ||||
|                 m_log.Error( | ||||
|                     string.Format("[LLUDPSERVER]: OutgoingPacketHandler iteration for {0} threw ", client.Name), ex); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|  | @ -1229,11 +1319,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|         { | ||||
|             nticks++; | ||||
|             watch1.Start(); | ||||
|             m_currentOutgoingClient = client; | ||||
| 
 | ||||
|             try | ||||
|             { | ||||
|                 if (client is LLClientView) | ||||
|                 { | ||||
|                     LLUDPClient udpClient = ((LLClientView)client).UDPClient; | ||||
|                     LLClientView llClient = (LLClientView)client; | ||||
|                     LLUDPClient udpClient = llClient.UDPClient; | ||||
| 
 | ||||
|                     if (udpClient.IsConnected) | ||||
|                     { | ||||
|  | @ -1242,7 +1335,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|                             nticksUnack++; | ||||
|                             watch2.Start(); | ||||
| 
 | ||||
|                             HandleUnacked(udpClient); | ||||
|                             HandleUnacked(llClient); | ||||
| 
 | ||||
|                             watch2.Stop(); | ||||
|                             avgResendUnackedTicks = (nticksUnack - 1)/(float)nticksUnack * avgResendUnackedTicks + (watch2.ElapsedTicks / (float)nticksUnack); | ||||
|  | @ -1313,23 +1406,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
| 
 | ||||
|         #endregion  | ||||
| 
 | ||||
|         private void ProcessInPacket(object state) | ||||
|         private void ProcessInPacket(IncomingPacket incomingPacket) | ||||
|         { | ||||
|             IncomingPacket incomingPacket = (IncomingPacket)state; | ||||
|             Packet packet = incomingPacket.Packet; | ||||
|             LLUDPClient udpClient = incomingPacket.Client; | ||||
|             IClientAPI client; | ||||
|             LLClientView client = incomingPacket.Client; | ||||
| 
 | ||||
|             // Sanity check | ||||
|             if (packet == null || udpClient == null) | ||||
|             if (client.IsActive) | ||||
|             { | ||||
|                 m_log.WarnFormat("[LLUDPSERVER]: Processing a packet with incomplete state. Packet=\"{0}\", UDPClient=\"{1}\"", | ||||
|                     packet, udpClient); | ||||
|             } | ||||
|                 m_currentIncomingClient = client; | ||||
| 
 | ||||
|             // Make sure this client is still alive | ||||
|             if (m_scene.TryGetClient(udpClient.AgentID, out client)) | ||||
|             { | ||||
|                 try | ||||
|                 { | ||||
|                     // Process this packet | ||||
|  | @ -1344,21 +1429,34 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
|                 catch (Exception e) | ||||
|                 { | ||||
|                     // 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(e.Message, e); | ||||
|                     m_log.Error( | ||||
|                         string.Format( | ||||
|                             "[LLUDPSERVER]: Client packet handler for {0} for packet {1} threw ", | ||||
|                             client.Name, packet.Type), | ||||
|                         e); | ||||
|                 } | ||||
|                 finally | ||||
|                 { | ||||
|                     m_currentIncomingClient = null; | ||||
|                 } | ||||
|             } | ||||
|             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) | ||||
|         { | ||||
|             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] | ||||
|     public class BasicCircuitTests | ||||
|     { | ||||
|         private Scene m_scene; | ||||
|         private TestLLUDPServer m_udpServer; | ||||
| 
 | ||||
|         [TestFixtureSetUp] | ||||
|         public void FixtureInit() | ||||
|         { | ||||
|  | @ -61,83 +64,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests | |||
|             Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod; | ||||
|         } | ||||
| 
 | ||||
| //        /// <summary> | ||||
| //        /// Add a client for testing | ||||
| //        /// </summary> | ||||
| //        /// <param name="scene"></param> | ||||
| //        /// <param name="testLLUDPServer"></param> | ||||
| //        /// <param name="testPacketServer"></param> | ||||
| //        /// <param name="acm">Agent circuit manager used in setting up the stack</param> | ||||
| //        protected void SetupStack( | ||||
| //            IScene scene, out TestLLUDPServer testLLUDPServer, out TestLLPacketServer testPacketServer,  | ||||
| //            out AgentCircuitManager acm) | ||||
| //        { | ||||
| //            IConfigSource configSource = new IniConfigSource(); | ||||
| //            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); | ||||
| //        } | ||||
|         [SetUp] | ||||
|         public void SetUp() | ||||
|         { | ||||
|             m_scene = new SceneHelpers().SetupScene(); | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|         /// Build an object name packet for test purposes | ||||
|         /// </summary> | ||||
|         /// <param name="objectLocalId"></param> | ||||
|         /// <param name="objectName"></param> | ||||
|         protected ObjectNamePacket BuildTestObjectNamePacket(uint objectLocalId, string objectName) | ||||
|         private ObjectNamePacket BuildTestObjectNamePacket(uint objectLocalId, string objectName) | ||||
|         { | ||||
|             ObjectNamePacket onp = new ObjectNamePacket(); | ||||
|             ObjectNamePacket.ObjectDataBlock odb = new ObjectNamePacket.ObjectDataBlock(); | ||||
|  | @ -148,29 +86,31 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests | |||
|              | ||||
|             return onp; | ||||
|         } | ||||
|          | ||||
|         /// <summary> | ||||
|         /// Test adding a client to the stack | ||||
|         /// </summary> | ||||
|         [Test] | ||||
|         public void TestAddClient() | ||||
|         { | ||||
|             TestHelpers.InMethod(); | ||||
| //            XmlConfigurator.Configure(); | ||||
| 
 | ||||
|             TestScene scene = SceneHelpers.SetupScene(); | ||||
|             uint myCircuitCode = 123456; | ||||
|         private void AddUdpServer() | ||||
|         { | ||||
|             AddUdpServer(new IniConfigSource()); | ||||
|         } | ||||
| 
 | ||||
|         private void AddUdpServer(IniConfigSource configSource) | ||||
|         { | ||||
|             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 mySessionUuid = TestHelpers.ParseTail(0x2); | ||||
|             uint myCircuitCode = 123456; | ||||
|             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.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. | ||||
|             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 | ||||
|             Assert.That(scene.GetScenePresence(myAgentUuid), Is.Null); | ||||
|             Assert.That(m_scene.GetScenePresence(myAgentUuid), Is.Null); | ||||
| 
 | ||||
|             AgentCircuitData acd = new AgentCircuitData(); | ||||
|             acd.AgentID = myAgentUuid; | ||||
|             acd.SessionID = mySessionUuid; | ||||
| 
 | ||||
|             acm.AddNewCircuit(myCircuitCode, acd); | ||||
|             m_scene.AuthenticateHandler.AddNewCircuit(myCircuitCode, acd); | ||||
| 
 | ||||
|             llUdpServer.PacketReceived(upb); | ||||
|             m_udpServer.PacketReceived(upb); | ||||
| 
 | ||||
|             // Should succeed now | ||||
|             ScenePresence sp = scene.GetScenePresence(myAgentUuid); | ||||
|             ScenePresence sp = m_scene.GetScenePresence(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))); | ||||
| 
 | ||||
|             PacketAckPacket ackPacket = packet as PacketAckPacket; | ||||
|  | @ -212,6 +193,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests | |||
|             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> | ||||
| //        /// Test removing a client from the stack | ||||
| //        /// </summary> | ||||
|  |  | |||
|  | @ -79,7 +79,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests | |||
| 
 | ||||
|             J2KDecoderModule j2kdm = new J2KDecoderModule(); | ||||
| 
 | ||||
|             scene = SceneHelpers.SetupScene(); | ||||
|             SceneHelpers sceneHelpers = new SceneHelpers(); | ||||
|             scene = sceneHelpers.SetupScene(); | ||||
|             SceneHelpers.SetupSceneModules(scene, j2kdm); | ||||
| 
 | ||||
|             tc = new TestClient(SceneHelpers.GenerateAgentData(userId), scene); | ||||
|  |  | |||
|  | @ -44,13 +44,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests | |||
|         } | ||||
|         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; | ||||
|         } | ||||
|          | ||||
|         public override void Update() {} | ||||
|         public override void Update(int frames) {} | ||||
|         public override void LoadWorldMap() {} | ||||
|          | ||||
|         public override ISceneAgent AddNewClient(IClientAPI client, PresenceType type) | ||||
|  |  | |||
|  | @ -59,6 +59,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests | |||
|             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> | ||||
| ////        /// The chunks of data to pass to the LLUDPServer when it calls EndReceive | ||||
| ////        /// </summary> | ||||
|  |  | |||
|  | @ -53,9 +53,8 @@ namespace OpenSim.Region.ClientStack | |||
|         protected ISimulationDataService m_simulationDataService; | ||||
|         protected IEstateDataService m_estateDataService; | ||||
|         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 ISimulationDataService SimulationDataService { get { return m_simulationDataService; } } | ||||
|         public IEstateDataService EstateDataService { get { return m_estateDataService; } } | ||||
|  | @ -77,6 +76,7 @@ namespace OpenSim.Region.ClientStack | |||
| 
 | ||||
|         protected override void StartupSpecific() | ||||
|         { | ||||
|             SceneManager = new SceneManager(); | ||||
|             m_clientStackManager = CreateClientStackManager(); | ||||
| 
 | ||||
|             Initialize(); | ||||
|  | @ -94,24 +94,21 @@ namespace OpenSim.Region.ClientStack | |||
|             m_log.InfoFormat("[REGION SERVER]: Starting HTTP server on port {0}", m_httpServerPort); | ||||
|             m_httpServer.Start(); | ||||
| 
 | ||||
|             MainServer.AddHttpServer(m_httpServer); | ||||
|             MainServer.Instance = m_httpServer; | ||||
| 
 | ||||
|             // "OOB" Server | ||||
|             if (m_networkServersInfo.ssl_listener) | ||||
|             { | ||||
|                 BaseHttpServer server = null; | ||||
|                 server = new BaseHttpServer( | ||||
|                 BaseHttpServer server = new BaseHttpServer( | ||||
|                     m_networkServersInfo.https_port, m_networkServersInfo.ssl_listener, m_networkServersInfo.cert_path, | ||||
|                     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); | ||||
|                     MainServer.AddHttpServer(server); | ||||
|                     server.Start(); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|                 m_log.InfoFormat("[REGION SERVER]: Starting HTTPS server on port {0}", server.Port); | ||||
|                 MainServer.AddHttpServer(server); | ||||
|                 server.Start(); | ||||
|             } | ||||
|              | ||||
|             base.StartupSpecific(); | ||||
|         } | ||||
| 
 | ||||
|  |  | |||
|  | @ -42,8 +42,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
|     public class AssetTransactionModule : INonSharedRegionModule, | ||||
|             IAgentAssetTransactions | ||||
|     { | ||||
| //        private static readonly ILog m_log = LogManager.GetLogger( | ||||
| //                MethodBase.GetCurrentMethod().DeclaringType); | ||||
|         private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||||
|          | ||||
|         protected Scene m_Scene; | ||||
|         private bool m_dumpAssetsToFile = false; | ||||
|  | @ -203,15 +202,15 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
|         /// and comes through this method. | ||||
|         /// </summary> | ||||
|         /// <param name="remoteClient"></param> | ||||
|         /// <param name="part"></param> | ||||
|         /// <param name="transactionID"></param> | ||||
|         /// <param name="item"></param> | ||||
|         public void HandleTaskItemUpdateFromTransaction(IClientAPI remoteClient, | ||||
|                 SceneObjectPart part, UUID transactionID, | ||||
|                 TaskInventoryItem item) | ||||
|         public void HandleTaskItemUpdateFromTransaction( | ||||
|             IClientAPI remoteClient, SceneObjectPart part, UUID transactionID, TaskInventoryItem item) | ||||
|         { | ||||
| //            m_log.DebugFormat( | ||||
| //                "[TRANSACTIONS MANAGER] Called HandleTaskItemUpdateFromTransaction with item {0}", | ||||
| //                item.Name); | ||||
|             m_log.DebugFormat( | ||||
|                 "[TRANSACTIONS MANAGER] Called HandleTaskItemUpdateFromTransaction with item {0} in {1} for {2} in {3}", | ||||
|                 item.Name, part.Name, remoteClient.Name, m_Scene.RegionInfo.RegionName); | ||||
| 
 | ||||
|             AgentAssetTransactions transactions = | ||||
|                     GetUserTransactions(remoteClient.AgentId); | ||||
|  |  | |||
|  | @ -143,7 +143,7 @@ namespace Flotsam.RegionModules.AssetCache | |||
|                     IConfig assetConfig = source.Configs["AssetCache"]; | ||||
|                     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."); | ||||
|                     } | ||||
|                     else | ||||
|  | @ -203,10 +203,10 @@ namespace Flotsam.RegionModules.AssetCache | |||
|                         m_CacheDirectoryTierLen = 4; | ||||
|                     } | ||||
| 
 | ||||
|                     MainConsole.Instance.Commands.AddCommand(Name, true, "fcache status", "fcache status", "Display cache status", HandleConsoleCommand); | ||||
|                     MainConsole.Instance.Commands.AddCommand(Name, true, "fcache clear",  "fcache clear [file] [memory]", "Remove all assets in the cache.  If file or memory is specified then only this cache is cleared.", HandleConsoleCommand); | ||||
|                     MainConsole.Instance.Commands.AddCommand(Name, true, "fcache assets", "fcache assets", "Attempt a deep scan and cache of all assets in all scenes", HandleConsoleCommand); | ||||
|                     MainConsole.Instance.Commands.AddCommand(Name, true, "fcache expire", "fcache expire <datetime>", "Purge cached assets older then the specified date/time", HandleConsoleCommand); | ||||
|                     MainConsole.Instance.Commands.AddCommand("Assets", true, "fcache status", "fcache status", "Display cache status", HandleConsoleCommand); | ||||
|                     MainConsole.Instance.Commands.AddCommand("Assets", true, "fcache clear",  "fcache clear [file] [memory]", "Remove all assets in the cache.  If file or memory is specified then only this cache is cleared.", HandleConsoleCommand); | ||||
|                     MainConsole.Instance.Commands.AddCommand("Assets", true, "fcache assets", "fcache assets", "Attempt a deep scan and cache of all assets in all scenes", HandleConsoleCommand); | ||||
|                     MainConsole.Instance.Commands.AddCommand("Assets", true, "fcache expire", "fcache expire <datetime>", "Purge cached assets older then the specified date/time", HandleConsoleCommand); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  |  | |||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
		Reference in New Issue