Compare commits
593 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f6aa262585 | ||
|
|
2cc7a89012 | ||
|
|
108e77fe1a | ||
|
|
97b1b309ce | ||
|
|
53839ac779 | ||
|
|
4efcf38e17 | ||
|
|
639d147231 | ||
|
|
a53f90cf7a | ||
|
|
e0a3a8d47b | ||
|
|
7ce30cc49e | ||
|
|
6c36471f0c | ||
|
|
a100723aaf | ||
|
|
69dc9b89a2 | ||
|
|
c0d68d0aa4 | ||
|
|
ce89bc38e1 | ||
|
|
a21ee11fe8 | ||
|
|
06df03d98a | ||
|
|
2f4181623d | ||
|
|
bbfb501b02 | ||
|
|
a70baa95d1 | ||
|
|
ed99017271 | ||
|
|
061c748b75 | ||
|
|
c4645a899f | ||
|
|
c223ac6929 | ||
|
|
7e287227a4 | ||
|
|
d4470c6147 | ||
|
|
c14f983cca | ||
|
|
8a78d0f974 | ||
|
|
f35e94f168 | ||
|
|
0e9e60d55a | ||
|
|
f6a7325961 | ||
|
|
ed63cafa65 | ||
|
|
092e94035b | ||
|
|
fa3ebd85c9 | ||
|
|
08a9b01123 | ||
|
|
5772d23ff6 | ||
|
|
1d0ff7da2a | ||
|
|
ec063b9088 | ||
|
|
12fbfb6125 | ||
|
|
272cd9886d | ||
|
|
627cfe6678 | ||
|
|
aac4d9d682 | ||
|
|
25d39a19e1 | ||
|
|
55d383e4be | ||
|
|
b180fdd0fd | ||
|
|
cc6b2fdb9f | ||
|
|
9d6ea27df0 | ||
|
|
2d66fcd4cd | ||
|
|
91ae1908fe | ||
|
|
ed962bb3d3 | ||
|
|
9ea09d785c | ||
|
|
e3db5fb603 | ||
|
|
58aa51218e | ||
|
|
0fff0e1fad | ||
|
|
4457ec667a | ||
|
|
7f2e6a55c4 | ||
|
|
92a01a7e70 | ||
|
|
4debc67b48 | ||
|
|
c8f60acc30 | ||
|
|
272c3c1069 | ||
|
|
5aa9c21e7d | ||
|
|
454c3fc913 | ||
|
|
3cd7c59696 | ||
|
|
1f8ac33ecb | ||
|
|
47e2922a40 | ||
|
|
4deb25da87 | ||
|
|
587c8017ab | ||
|
|
d5d801f218 | ||
|
|
2f865da5c7 | ||
|
|
cf2f6843c6 | ||
|
|
97d084c9f5 | ||
|
|
14f72a9a43 | ||
|
|
89efccaa71 | ||
|
|
8f61da0759 | ||
|
|
e88e87ff63 | ||
|
|
4f10d1aa0c | ||
|
|
1912215c40 | ||
|
|
ffbca99b57 | ||
|
|
f660a25fa7 | ||
|
|
523d03fb76 | ||
|
|
85985a8c3e | ||
|
|
013e002b00 | ||
|
|
5269d77cf9 | ||
|
|
8c8e6220fb | ||
|
|
150860c964 | ||
|
|
0cb1b0bb4a | ||
|
|
56d894ae24 | ||
|
|
b34fd50155 | ||
|
|
74486e767d | ||
|
|
1b8814878d | ||
|
|
095375d63d | ||
|
|
cb4e074a8c | ||
|
|
222f844d65 | ||
|
|
bb2a9060f1 | ||
|
|
e21dd88ed5 | ||
|
|
35457448ca | ||
|
|
596caf41db | ||
|
|
c62b46a167 | ||
|
|
2b3098f011 | ||
|
|
74b4efd7f9 | ||
|
|
298c4c0eb5 | ||
|
|
068917bc29 | ||
|
|
d8f1d2892c | ||
|
|
ccf8e89193 | ||
|
|
f17f58ac2a | ||
|
|
6bcb5baab6 | ||
|
|
0aaf935333 | ||
|
|
b30806822e | ||
|
|
a2c3dfc422 | ||
|
|
4050a6f8bb | ||
|
|
0d0d04c484 | ||
|
|
952b3448a6 | ||
|
|
d53ef3b302 | ||
|
|
48e88397a0 | ||
|
|
976190fe96 | ||
|
|
1e025d6074 | ||
|
|
fffd2fe10d | ||
|
|
cf8adbe007 | ||
|
|
890f617e58 | ||
|
|
6ff0e58db7 | ||
|
|
795443cff1 | ||
|
|
8c7f511e55 | ||
|
|
0acac2f890 | ||
|
|
72554fc5b8 | ||
|
|
aa1442b07e | ||
|
|
e8a0ec1287 | ||
|
|
3436be2046 | ||
|
|
9a0bcb7750 | ||
|
|
218fe36f84 | ||
|
|
07298c8b4f | ||
|
|
d9f40d1ebc | ||
|
|
eddff428ed | ||
|
|
61aaa10460 | ||
|
|
e1d6929e61 | ||
|
|
6b87873aa7 | ||
|
|
f690acbfb6 | ||
|
|
f49c850269 | ||
|
|
70f85af75b | ||
|
|
663b0cc681 | ||
|
|
733a8c9f89 | ||
|
|
25109c8e4d | ||
|
|
51724128bf | ||
|
|
461831a65e | ||
|
|
c6fa09c3af | ||
|
|
9ccf56eaae | ||
|
|
ea9b0794e0 | ||
|
|
96191241be | ||
|
|
779f0ede49 | ||
|
|
e511106d8d | ||
|
|
37f22e2946 | ||
|
|
b802906827 | ||
|
|
c6fb5f0fe4 | ||
|
|
8909e70fc3 | ||
|
|
78fcee1f4b | ||
|
|
3106a0f25e | ||
|
|
19c2f08a8b | ||
|
|
005ca12a99 | ||
|
|
02fe1a676e | ||
|
|
03fc8cf155 | ||
|
|
8dedd91961 | ||
|
|
0ac040d9ca | ||
|
|
c5e5308120 | ||
|
|
1cfaacb88b | ||
|
|
689cafec63 | ||
|
|
d4cd9e050b | ||
|
|
472785a5e8 | ||
|
|
da28fcd357 | ||
|
|
1999338773 | ||
|
|
95670d2086 | ||
|
|
af2c48449c | ||
|
|
ffc6110edf | ||
|
|
1edd1f93c1 | ||
|
|
b6e42da21a | ||
|
|
2e0402433d | ||
|
|
d19600e257 | ||
|
|
a6d97e6353 | ||
|
|
8eb39eb3ac | ||
|
|
553ac6335d | ||
|
|
32a2515817 | ||
|
|
a0482bccc7 | ||
|
|
3291e256ba | ||
|
|
fb7573f713 | ||
|
|
4684207d6e | ||
|
|
499b778391 | ||
|
|
9779ceded5 | ||
|
|
512d0ac411 | ||
|
|
981c7d63a0 | ||
|
|
7bd1601a3f | ||
|
|
3aef006e78 | ||
|
|
9a6aa528db | ||
|
|
02a163848c | ||
|
|
b9f122be07 | ||
|
|
e64ca361df | ||
|
|
8a11c4e7d4 | ||
|
|
584a076bec | ||
|
|
88596d6097 | ||
|
|
84d97b3bc0 | ||
|
|
2b4e97eeaf | ||
|
|
a544280ef2 | ||
|
|
3a0f9836f3 | ||
|
|
4bfac5688d | ||
|
|
0fb93042c6 | ||
|
|
a3586a7c4b | ||
|
|
d4ff56710b | ||
|
|
6219c137e1 | ||
|
|
da3877a77d | ||
|
|
10ed7e3bbc | ||
|
|
f248f8bf31 | ||
|
|
6f2031001b | ||
|
|
1c5ad8e9ab | ||
|
|
d8d8b8fc9b | ||
|
|
719efdaf1f | ||
|
|
6a8e3907ca | ||
|
|
5a1b8fc6f7 | ||
|
|
00ac962db7 | ||
|
|
cb518ad68c | ||
|
|
4859bc8c49 | ||
|
|
196e014782 | ||
|
|
c6ffaaa959 | ||
|
|
c3104f4bd2 | ||
|
|
d8c40ca462 | ||
|
|
48f47bb4c7 | ||
|
|
8db6edbe87 | ||
|
|
a57b78b44b | ||
|
|
280d005d55 | ||
|
|
61e7d4a0e2 | ||
|
|
3e75083d2d | ||
|
|
3d400dd677 | ||
|
|
1fbb0f97bf | ||
|
|
4968191c1e | ||
|
|
8889309324 | ||
|
|
27a7ba3e6a | ||
|
|
2d16d14ef1 | ||
|
|
f2f8dcd65c | ||
|
|
332f8b6623 | ||
|
|
4eda679e12 | ||
|
|
498154af80 | ||
|
|
ba0ebe6d75 | ||
|
|
28f93512bc | ||
|
|
78c2ef2346 | ||
|
|
d30d68657e | ||
|
|
3a27f656b3 | ||
|
|
cc27a6cb84 | ||
|
|
ed21576ce0 | ||
|
|
9d9e042b4c | ||
|
|
4fb8d5cfba | ||
|
|
896c4b6248 | ||
|
|
f6730da13a | ||
|
|
41d98916df | ||
|
|
771539a4e0 | ||
|
|
27c62bba99 | ||
|
|
93e053a122 | ||
|
|
eb022f4cc1 | ||
|
|
83542034dd | ||
|
|
627382f702 | ||
|
|
2eb563b3bb | ||
|
|
54a23f14d5 | ||
|
|
e8059b74f8 | ||
|
|
075909520a | ||
|
|
808bf12cd5 | ||
|
|
0f39f41317 | ||
|
|
f23b7ae3e9 | ||
|
|
5e4b09fc22 | ||
|
|
25ab7841b7 | ||
|
|
0c0e575379 | ||
|
|
68946bffae | ||
|
|
2fc461d9ab | ||
|
|
59a48d9ebb | ||
|
|
533d1ea20c | ||
|
|
dca1ca1d07 | ||
|
|
20a3907e86 | ||
|
|
7358e5748d | ||
|
|
a1b64db942 | ||
|
|
4d44f2d248 | ||
|
|
67abbcf269 | ||
|
|
6b819a9032 | ||
|
|
2021a8aedb | ||
|
|
58dc175ae3 | ||
|
|
4ad6763956 | ||
|
|
702826b850 | ||
|
|
8d30a1f74b | ||
|
|
1a988ba835 | ||
|
|
c422f852a6 | ||
|
|
bcacdb3352 | ||
|
|
cd61567de8 | ||
|
|
5c48c3c57a | ||
|
|
7692ccc0cc | ||
|
|
17cc7e85e2 | ||
|
|
96b3e1d0fa | ||
|
|
dc3cfcbe69 | ||
|
|
1ca1f80eac | ||
|
|
afe2b437bc | ||
|
|
dff71c1aa9 | ||
|
|
7f9a025e30 | ||
|
|
a0ac284a11 | ||
|
|
5341036261 | ||
|
|
46a6cab307 | ||
|
|
edb17d1aac | ||
|
|
dd05e96066 | ||
|
|
ed0878ca23 | ||
|
|
54c222be26 | ||
|
|
80d139297a | ||
|
|
8e6459f616 | ||
|
|
ba909cb692 | ||
|
|
96b964f7fa | ||
|
|
7bbab2f1d5 | ||
|
|
e5f3af4abe | ||
|
|
452538c6b0 | ||
|
|
5c828724f3 | ||
|
|
6538dd24bb | ||
|
|
996abe1ea5 | ||
|
|
f421e0c3d1 | ||
|
|
e4eaca5f9b | ||
|
|
ef5925fa18 | ||
|
|
bae48a9394 | ||
|
|
c813ed44d8 | ||
|
|
885bec68bd | ||
|
|
b553a05db3 | ||
|
|
5473c4f8cc | ||
|
|
0d73f81fb5 | ||
|
|
66c204b983 | ||
|
|
afb0600621 | ||
|
|
a13f2c6985 | ||
|
|
17c7ef06ba | ||
|
|
4933ce49b6 | ||
|
|
5cec1fa50a | ||
|
|
debd83b06a | ||
|
|
f01618ad1a | ||
|
|
cfc1dba99b | ||
|
|
529a3f2400 | ||
|
|
7c1abc5225 | ||
|
|
ca22b5e2f0 | ||
|
|
9ec74f2098 | ||
|
|
cb4ae39cb9 | ||
|
|
802488814f | ||
|
|
53aa48b42c | ||
|
|
b33801f854 | ||
|
|
fc88ce0615 | ||
|
|
28daec7f4e | ||
|
|
f25efa291d | ||
|
|
5ed0559cf2 | ||
|
|
8c1e549c12 | ||
|
|
796334c5ff | ||
|
|
2e1c2e1261 | ||
|
|
a896aac4bd | ||
|
|
80030d3f15 | ||
|
|
4eba4a37ed | ||
|
|
dd0858e204 | ||
|
|
25fa6ee699 | ||
|
|
84dfffe0aa | ||
|
|
aba803c447 | ||
|
|
79aae63aff | ||
|
|
59e93b8ee3 | ||
|
|
e0e63f312f | ||
|
|
d453372f4e | ||
|
|
0f5a77c5bd | ||
|
|
0c96d7ea5c | ||
|
|
4b947cd6d3 | ||
|
|
ca586ca809 | ||
|
|
880358f46b | ||
|
|
3393babb7d | ||
|
|
c3ae90c067 | ||
|
|
25983f20a0 | ||
|
|
1441758bc6 | ||
|
|
c7bbeb4490 | ||
|
|
6145f90423 | ||
|
|
2e397d1514 | ||
|
|
a5d0a29dd9 | ||
|
|
de843fd0a8 | ||
|
|
ced4eeddcf | ||
|
|
093910e90e | ||
|
|
37685ec1b4 | ||
|
|
ccd7d35b3f | ||
|
|
de7e0d7e52 | ||
|
|
89ee03a24d | ||
|
|
79d1d3ca55 | ||
|
|
675c208c7e | ||
|
|
b3307850ab | ||
|
|
eaa840dbd9 | ||
|
|
f64089fa6c | ||
|
|
5157d2023d | ||
|
|
2cd927bb14 | ||
|
|
2889961622 | ||
|
|
232f59749e | ||
|
|
d368a10cc7 | ||
|
|
139b848774 | ||
|
|
74a5226af5 | ||
|
|
c7ddc7a633 | ||
|
|
265707d21c | ||
|
|
eb39d1c4d4 | ||
|
|
1197d48fc7 | ||
|
|
23e1a55ed5 | ||
|
|
ba2a539603 | ||
|
|
8a8093d8dd | ||
|
|
3fb0103452 | ||
|
|
aeefdaedc7 | ||
|
|
756d1f917f | ||
|
|
6fa3dffad2 | ||
|
|
123e781cb3 | ||
|
|
ed9bf5b0c6 | ||
|
|
dd4e39ca1d | ||
|
|
5a551b074b | ||
|
|
c1a9355865 | ||
|
|
3ea6c25fb6 | ||
|
|
2d3135448c | ||
|
|
36a99af37c | ||
|
|
2aefd15913 | ||
|
|
6bc55b1086 | ||
|
|
7058ce2c70 | ||
|
|
8e111e9018 | ||
|
|
d8bd7ca436 | ||
|
|
392f73a000 | ||
|
|
67efbaf33b | ||
|
|
0d06740148 | ||
|
|
eda6947a22 | ||
|
|
f331173145 | ||
|
|
a666cd9e1f | ||
|
|
2657aa6987 | ||
|
|
6610cd2332 | ||
|
|
0c8b44d514 | ||
|
|
ec46ff4445 | ||
|
|
db891880e6 | ||
|
|
9c433e8c50 | ||
|
|
5141863ae3 | ||
|
|
d23550dea5 | ||
|
|
c3b12510ae | ||
|
|
b2685e3671 | ||
|
|
601d2ddbf3 | ||
|
|
a5e8fe70af | ||
|
|
9b3a96aa81 | ||
|
|
d674e815bd | ||
|
|
c2e696d686 | ||
|
|
411dbb8df4 | ||
|
|
b22dfbbf15 | ||
|
|
4c39a3fdbf | ||
|
|
f3eb366f24 | ||
|
|
a20d1b8f6b | ||
|
|
0a51289332 | ||
|
|
97ebfb00b4 | ||
|
|
c7d664f9d0 | ||
|
|
c2fbaaa95d | ||
|
|
84d4b390f1 | ||
|
|
54e59099b7 | ||
|
|
d9585ba37e | ||
|
|
45c617b5c3 | ||
|
|
4b0c78c64f | ||
|
|
dd36e23a62 | ||
|
|
e2dade05d9 | ||
|
|
fbd61106cb | ||
|
|
67e66a2d34 | ||
|
|
59911963ca | ||
|
|
dc2a4a6ccd | ||
|
|
81fb0b4f07 | ||
|
|
a06c8fb7b2 | ||
|
|
05e70f76a9 | ||
|
|
b9f4836d3e | ||
|
|
ef77dc932b | ||
|
|
bd5b1d4d48 | ||
|
|
5c2ffa260c | ||
|
|
23d04fa25c | ||
|
|
67dbce4512 | ||
|
|
46170fd0d8 | ||
|
|
f85a453dc8 | ||
|
|
bcfe48e05b | ||
|
|
722ca250ea | ||
|
|
f4df128e52 | ||
|
|
8cc5322b39 | ||
|
|
1480845597 | ||
|
|
c877e73463 | ||
|
|
3ce5e8eb6c | ||
|
|
e6b12e1f9d | ||
|
|
bfbbd4ccba | ||
|
|
fec7016665 | ||
|
|
47fe6170b2 | ||
|
|
24b5fb8523 | ||
|
|
e8cd9688ce | ||
|
|
fa952f6d35 | ||
|
|
df55fd69af | ||
|
|
019fc4c1f2 | ||
|
|
22ea441feb | ||
|
|
9f5b33e52e | ||
|
|
92837c4f89 | ||
|
|
68ce06f40f | ||
|
|
279b31c75b | ||
|
|
3117b3cd88 | ||
|
|
9b547f76e7 | ||
|
|
3d6675784a | ||
|
|
26f50eadd1 | ||
|
|
6e8496ffc5 | ||
|
|
88d6c4ec0e | ||
|
|
135eeb45d6 | ||
|
|
54ee59c0bb | ||
|
|
4a5c61a33d | ||
|
|
179c0f5f56 | ||
|
|
4dbf937707 | ||
|
|
9edb57e5e9 | ||
|
|
4d15ad63bf | ||
|
|
4021709371 | ||
|
|
3c13f5c3aa | ||
|
|
381517b451 | ||
|
|
6ecf36d49c | ||
|
|
64eb4b8408 | ||
|
|
318da3fdcd | ||
|
|
50c99fcda6 | ||
|
|
321de1f263 | ||
|
|
fa30ace67d | ||
|
|
92baa79253 | ||
|
|
e861b45313 | ||
|
|
cf91ac68b6 | ||
|
|
d4aba13526 | ||
|
|
d36c7c3782 | ||
|
|
4385fcdeae | ||
|
|
04eb170624 | ||
|
|
4803686078 | ||
|
|
20b0fda3bb | ||
|
|
4e5f823595 | ||
|
|
a74408d1d2 | ||
|
|
8206537efd | ||
|
|
a9a77bb3ab | ||
|
|
6390de689d | ||
|
|
41ce19836b | ||
|
|
883a4f6fff | ||
|
|
5f1da80fc1 | ||
|
|
64217d67f6 | ||
|
|
b01c79354c | ||
|
|
9ecbcb787c | ||
|
|
e17e376b04 | ||
|
|
1b4ea4f178 | ||
|
|
1de29fb362 | ||
|
|
7e4bd492fd | ||
|
|
588d56503d | ||
|
|
e9602656f8 | ||
|
|
0116d418f0 | ||
|
|
9992974c66 | ||
|
|
ba27d8a389 | ||
|
|
f96e985763 | ||
|
|
5b9eaae50d | ||
|
|
74a13f7e3b | ||
|
|
3e88fc8aad | ||
|
|
881740d702 | ||
|
|
9a643a1bb9 | ||
|
|
a5488650ff | ||
|
|
a275127a65 | ||
|
|
02db31db6a | ||
|
|
8bd813e6fc | ||
|
|
09ff121654 | ||
|
|
0434758a0d | ||
|
|
8bb0a71083 | ||
|
|
d7651a389e | ||
|
|
824318a0c1 | ||
|
|
5e9ed22e84 | ||
|
|
a6c611e7c9 | ||
|
|
72b325f8b5 | ||
|
|
54d0514b13 | ||
|
|
58b1c3cec0 | ||
|
|
71641523a3 | ||
|
|
94c5e25c3b | ||
|
|
20bad0aa6c | ||
|
|
e7f23a6218 | ||
|
|
25c29db8b6 | ||
|
|
1750fba9ce | ||
|
|
b18e410586 | ||
|
|
38d5e1fab3 | ||
|
|
4180c32eb1 | ||
|
|
5115229fdf | ||
|
|
e8f2d814e7 | ||
|
|
1fda8c5a86 | ||
|
|
6b77b55d40 | ||
|
|
82cdb08c1f | ||
|
|
dafcb3bcd7 | ||
|
|
3259b1d1e0 | ||
|
|
512910a51f | ||
|
|
fdda57cf10 | ||
|
|
ec8e34950d | ||
|
|
93964ef3a4 | ||
|
|
5c8af6a136 | ||
|
|
4d0c8aca05 | ||
|
|
8fc16ece96 | ||
|
|
fcbb375e8f | ||
|
|
49c65279fa | ||
|
|
86e8a56fe1 | ||
|
|
b199330682 | ||
|
|
7a7ebaebd1 | ||
|
|
164ae0b24b | ||
|
|
7156545fca | ||
|
|
73a5abf4d9 | ||
|
|
630c8dc828 | ||
|
|
6de89246c2 | ||
|
|
96973a5778 | ||
|
|
96843f2b17 | ||
|
|
8a36f54cf4 | ||
|
|
1a14e660d2 | ||
|
|
2502aae5db |
15
.gitignore
vendored
15
.gitignore
vendored
@@ -10,12 +10,6 @@
|
||||
*.pidb
|
||||
*.dll.build
|
||||
*.dll
|
||||
|
||||
# Ignore .user and .suo files as these are user preference specific
|
||||
# http://stackoverflow.com/questions/72298/should-i-add-the-visual-studio-suo-and-user-files-to-source-control
|
||||
*.suo
|
||||
*.user
|
||||
|
||||
*.VisualState.xml
|
||||
*/*/obj
|
||||
*/*/*/obj
|
||||
@@ -32,14 +26,9 @@
|
||||
bin/Debug/*.dll
|
||||
bin/*.dll.mdb
|
||||
bin/*.db
|
||||
bin/*.db-journal
|
||||
bin/addin-db-*
|
||||
bin/*.dll
|
||||
bin/OpenSim.vshost.exe.config
|
||||
bin/OpenSim.32BitLaunch.vshost.exe.config
|
||||
bin/OpenSim.32BitLaunch.log
|
||||
UpgradeLog.XML
|
||||
_UpgradeReport_Files/
|
||||
bin/ScriptEngines/*-*-*-*-*
|
||||
bin/ScriptEngines/*.dll
|
||||
bin/ScriptEngines/*/*.dll
|
||||
@@ -71,7 +60,7 @@ bin/crashes/
|
||||
Examples/*.dll
|
||||
OpenSim.build
|
||||
OpenSim.sln
|
||||
OpenSim.userprefs
|
||||
OpenSim.suo
|
||||
Prebuild/Prebuild.build
|
||||
Prebuild/Prebuild.sln
|
||||
TestResult.xml
|
||||
@@ -100,5 +89,3 @@ OpenSim/Region/ScriptEngine/test-results/
|
||||
OpenSim/Tests/Common/test-results/
|
||||
OpenSim/Tests/test-results/
|
||||
test-results/
|
||||
doc/html
|
||||
doc/doxygen.error.log
|
||||
|
||||
@@ -43,11 +43,10 @@
|
||||
<delete dir="${distbindir}/Prebuild"/>
|
||||
<delete dir="${distbindir}/%temp%"/>
|
||||
<delete dir="${distbindir}/.nant"/>
|
||||
<delete dir="${distbindir}/ThirdParty"/>
|
||||
<delete>
|
||||
<fileset basedir="${distbindir}">
|
||||
<include name="compile.bat"/>
|
||||
<include name="BUILDING.md"/>
|
||||
<include name="BUILDING.txt"/>
|
||||
<include name="Makefile"/>
|
||||
<include name="nant-color"/>
|
||||
<include name="OpenSim.*"/>
|
||||
@@ -133,16 +132,6 @@
|
||||
</exec>
|
||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.capabilities.handlers.tests)==0}" />
|
||||
|
||||
<exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.server.handlers.tests">
|
||||
<arg value="./bin/OpenSim.Server.Handlers.Tests.dll" />
|
||||
</exec>
|
||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.server.handlers.tests)==0}" />
|
||||
|
||||
<exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.services.inventoryservice.tests">
|
||||
<arg value="./bin/OpenSim.Services.InventoryService.Tests.dll" />
|
||||
</exec>
|
||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.services.inventoryservice.tests)==0}" />
|
||||
|
||||
<delete dir="%temp%"/>
|
||||
</target>
|
||||
|
||||
@@ -246,16 +235,6 @@
|
||||
<arg value="-xml=test-results/OpenSim.Capabilities.Handlers.Tests.dll-Results.xml" />
|
||||
</exec>
|
||||
|
||||
<exec program="${nunitcmd}" failonerror="false" resultproperty="testresult.opensim.server.handlers.tests">
|
||||
<arg value="./bin/OpenSim.Server.Handlers.Tests.dll" />
|
||||
<arg value="-xml=test-results/OpenSim.Server.Handlers.Tests.dll-Results.xml" />
|
||||
</exec>
|
||||
|
||||
<exec program="${nunitcmd}" failonerror="false" resultproperty="testresult.opensim.services.inventoryservice.tests">
|
||||
<arg value="./bin/OpenSim.Services.InventoryService.Tests.dll" />
|
||||
<arg value="-xml=test-results/OpenSim.Services.InventoryService.Tests.dll-Results.xml" />
|
||||
</exec>
|
||||
|
||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.tests)==0}" />
|
||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.framework.tests)==0}" />
|
||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.framework.servers.tests)==0}" />
|
||||
@@ -266,7 +245,6 @@
|
||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.framework.tests)==0}" />
|
||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.data.tests)==0}" />
|
||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.capabilities.handlers.tests)==0}" />
|
||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.services.inventoryservice.tests)==0}" />
|
||||
</target>
|
||||
|
||||
<target name="doxygen">
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
# Building on Windows
|
||||
==== Building OpenSim ====
|
||||
|
||||
=== Building on Windows ===
|
||||
|
||||
Steps:
|
||||
* runprebuild.bat
|
||||
@@ -7,15 +9,16 @@ Steps:
|
||||
* copy OpenSim.ini.example to OpenSim.ini and other appropriate files in bin/config-include
|
||||
* run OpenSim.exe
|
||||
|
||||
# Building on Linux
|
||||
=== Building on Linux ===
|
||||
|
||||
Prereqs:
|
||||
* Mono >= 2.4.3
|
||||
* Nant >= 0.85
|
||||
* On some Linux distributions you may need to install additional packages.
|
||||
See http://opensimulator.org/wiki/Dependencies for more information.
|
||||
* May also use xbuild (included in mono distributions)
|
||||
* May use Monodevelop, a cross-platform IDE
|
||||
* Mono >= 2.4.3
|
||||
* Nant >= 0.85
|
||||
* On some Linux distributions you may need to install additional packages.
|
||||
See http://opensimulator.org/wiki/Dependencies for more information.
|
||||
|
||||
* May also use xbuild (included in mono distributions)
|
||||
* May use Monodevelop, a cross-platform IDE
|
||||
|
||||
From the distribution type:
|
||||
* ./runprebuild.sh
|
||||
@@ -24,13 +27,13 @@ From the distribution type:
|
||||
* copy OpenSim.ini.example to OpenSim.ini and other appropriate files in bin/config-include
|
||||
* run mono OpenSim.exe
|
||||
|
||||
# Using Monodevelop
|
||||
=== Using Monodevelop ===
|
||||
|
||||
From the distribution type:
|
||||
* ./runprebuild.sh
|
||||
* type monodevelop OpenSim.sln
|
||||
|
||||
# References
|
||||
=== References ===
|
||||
|
||||
Helpful resources:
|
||||
* http://opensimulator.org/wiki/Build_Instructions
|
||||
@@ -1,4 +1,5 @@
|
||||
The following people have contributed to OpenSim (Thank you for your effort!)
|
||||
<<<>>>>The following people have contributed to OpenSim (Thank you
|
||||
for your effort!)
|
||||
|
||||
= Current OpenSim Developers (in very rough order of appearance) =
|
||||
These folks represent the current core team for OpenSim, and are the
|
||||
@@ -6,7 +7,7 @@ people that make the day to day of OpenSim happen.
|
||||
|
||||
* justincc (OSVW Consulting, justincc.org)
|
||||
* chi11ken (Genkii)
|
||||
* dahlia
|
||||
* dahlia
|
||||
* Melanie Thielker
|
||||
* Diva (Crista Lopes, University of California, Irvine)
|
||||
* Dan Lake (Intel)
|
||||
@@ -15,7 +16,7 @@ people that make the day to day of OpenSim happen.
|
||||
* BlueWall (James Hughes)
|
||||
* Nebadon Izumi (Michael Cerquoni, OSgrid)
|
||||
* Snoopy Pfeffer
|
||||
* Robert Adams (Intel)
|
||||
* Richard Adams (Intel)
|
||||
|
||||
= Core Developers Following the White Rabbit =
|
||||
Core developers who have temporarily (we hope) gone chasing the white rabbit.
|
||||
@@ -57,60 +58,46 @@ where we are today.
|
||||
|
||||
|
||||
= Additional OpenSim Contributors =
|
||||
These folks have contributed code patches or content to OpenSimulator to help make it
|
||||
These folks have contributed code patches to OpenSim to help make it
|
||||
what it is today.
|
||||
|
||||
* A_Biondi
|
||||
* aduffy70
|
||||
* Ai Austin
|
||||
* A_Biondi
|
||||
* alex_carnell
|
||||
* Alan Webb (IBM)
|
||||
* Aleric
|
||||
* Allen Kerensky
|
||||
* BigFootAg
|
||||
* BlueWall Slade
|
||||
* brianw/Sir_Ahzz
|
||||
* CharlieO
|
||||
* ChrisDown
|
||||
* Chris Yeoh (IBM)
|
||||
* controlbreak
|
||||
* coyled
|
||||
* ctrlaltdavid (David Rowe)
|
||||
* Daedius
|
||||
* Dong Jun Lan (IBM)
|
||||
* DoranZemlja
|
||||
* daTwitch
|
||||
* devalnor-#708
|
||||
* dmiles (Daxtron Labs)
|
||||
* Dong Jun Lan (IBM)
|
||||
* DoranZemlja
|
||||
* dr0b3rts
|
||||
* dslake (Intel)
|
||||
* FredoChaplin
|
||||
* Garmin Kawaguichi
|
||||
* Gerhard
|
||||
* Godfrey
|
||||
* Greg C.
|
||||
* Grumly57
|
||||
* GuduleLapointe
|
||||
* Ewe Loon
|
||||
* Fernando Oliveira
|
||||
* Fly-Man
|
||||
* Flyte Xevious
|
||||
* Garmin Kawaguichi
|
||||
* Gryc Ueusp
|
||||
* Hiro Lecker
|
||||
* Iain Oliver
|
||||
* Imaze Rhiano
|
||||
* Intimidated
|
||||
* Jeremy Bongio (IBM)
|
||||
* jhurliman
|
||||
* John R Sohn (XenReborn)
|
||||
* jonc
|
||||
* Jon Cundill
|
||||
* Junta Kohime
|
||||
* Kayne
|
||||
* Kevin Cozens
|
||||
* kinoc (Daxtron Labs)
|
||||
* Kira
|
||||
* Kitto Flora
|
||||
* KittyLiu
|
||||
* Kurt Taylor (IBM)
|
||||
@@ -119,7 +106,6 @@ what it is today.
|
||||
* M.Igarashi
|
||||
* maimedleech
|
||||
* Mana Janus
|
||||
* MarcelEdward
|
||||
* Mic Bowman
|
||||
* Michelle Argus
|
||||
* Michael Cortez (The Flotsam Project, http://osflotsam.org/)
|
||||
@@ -145,16 +131,13 @@ what it is today.
|
||||
* Richard Alimi (IBM)
|
||||
* Rick Alther (IBM)
|
||||
* Rob Smart (IBM)
|
||||
* Roger Kirkman (zadark)
|
||||
* rtomita
|
||||
* Ruud Lathorp
|
||||
* SachaMagne
|
||||
* Salahzar Stenvaag
|
||||
* satguru p srivastava
|
||||
* sempuki
|
||||
* SignpostMarv
|
||||
* SpotOn3D
|
||||
* Stefan_Boom / stoehr
|
||||
* Strawberry Fride
|
||||
* Talun
|
||||
* TechplexEngineer (Blake Bourque)
|
||||
@@ -162,40 +145,41 @@ what it is today.
|
||||
* tglion
|
||||
* tlaukkan/Tommil (Tommi S. E. Laukkanen, Bubble Cloud)
|
||||
* tyre
|
||||
* Vegaslon <vegaslon@gmail.com>
|
||||
* VikingErik
|
||||
* Vytek
|
||||
* webmage (IBM)
|
||||
* Xantor
|
||||
* Y. Nitta
|
||||
* YoshikoFazuku
|
||||
* YZh
|
||||
* Zackary Geers aka Kunnis Basiat
|
||||
* Zha Ewry
|
||||
* ziah
|
||||
|
||||
|
||||
= LSL Devs =
|
||||
|
||||
* Alondria
|
||||
* CharlieO
|
||||
* Tedd
|
||||
* Melanie Thielker
|
||||
|
||||
|
||||
= Testers =
|
||||
|
||||
* Ai Austin
|
||||
* CharlieO (LSL)
|
||||
* Ckrinke
|
||||
* openlifegrid.com
|
||||
|
||||
|
||||
This software uses components from the following developers:
|
||||
* Sleepycat Software (Berkeley DB)
|
||||
* Aurora-Sim (http://aurora-sim.org)
|
||||
* SQLite (Public Domain)
|
||||
* XmlRpcCS (http://xmlrpccs.sf.net/)
|
||||
* MySQL, Inc. (MySQL Connector/NET)
|
||||
* NUnit (http://www.nunit.org)
|
||||
* AGEIA Inc. (PhysX)
|
||||
* Russel L. Smith (ODE)
|
||||
* Erwin Coumans (Bullet)
|
||||
* Prebuild (http://sourceforge.net/projects/dnpb/)
|
||||
* LibOpenMetaverse (http://lib.openmetaverse.org/)
|
||||
* DotNetOpenMail v0.5.8b (http://dotnetopenmail.sourceforge.net)
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
|
||||
namespace OpenSim.Groups
|
||||
{
|
||||
public class ForeignImporter
|
||||
{
|
||||
IUserManagement m_UserManagement;
|
||||
public ForeignImporter(IUserManagement uman)
|
||||
{
|
||||
m_UserManagement = uman;
|
||||
}
|
||||
|
||||
public GroupMembersData ConvertGroupMembersData(ExtendedGroupMembersData _m)
|
||||
{
|
||||
GroupMembersData m = new GroupMembersData();
|
||||
m.AcceptNotices = _m.AcceptNotices;
|
||||
m.AgentPowers = _m.AgentPowers;
|
||||
m.Contribution = _m.Contribution;
|
||||
m.IsOwner = _m.IsOwner;
|
||||
m.ListInProfile = _m.ListInProfile;
|
||||
m.OnlineStatus = _m.OnlineStatus;
|
||||
m.Title = _m.Title;
|
||||
|
||||
string url = string.Empty, first = string.Empty, last = string.Empty, tmp = string.Empty;
|
||||
Util.ParseUniversalUserIdentifier(_m.AgentID, out m.AgentID, out url, out first, out last, out tmp);
|
||||
if (url != string.Empty)
|
||||
m_UserManagement.AddUser(m.AgentID, first, last, url);
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
public GroupRoleMembersData ConvertGroupRoleMembersData(ExtendedGroupRoleMembersData _rm)
|
||||
{
|
||||
GroupRoleMembersData rm = new GroupRoleMembersData();
|
||||
rm.RoleID = _rm.RoleID;
|
||||
|
||||
string url = string.Empty, first = string.Empty, last = string.Empty, tmp = string.Empty;
|
||||
Util.ParseUniversalUserIdentifier(_rm.MemberID, out rm.MemberID, out url, out first, out last, out tmp);
|
||||
if (url != string.Empty)
|
||||
m_UserManagement.AddUser(rm.MemberID, first, last, url);
|
||||
|
||||
return rm;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,533 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using OpenSim.Framework;
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace OpenSim.Groups
|
||||
{
|
||||
public class ExtendedGroupRecord : GroupRecord
|
||||
{
|
||||
public int MemberCount;
|
||||
public int RoleCount;
|
||||
public string ServiceLocation;
|
||||
public string FounderUUI;
|
||||
}
|
||||
|
||||
public class ExtendedGroupMembershipData : GroupMembershipData
|
||||
{
|
||||
public string AccessToken;
|
||||
}
|
||||
|
||||
public class ExtendedGroupMembersData
|
||||
{
|
||||
// This is the only difference: this is a string
|
||||
public string AgentID;
|
||||
public int Contribution;
|
||||
public string OnlineStatus;
|
||||
public ulong AgentPowers;
|
||||
public string Title;
|
||||
public bool IsOwner;
|
||||
public bool ListInProfile;
|
||||
public bool AcceptNotices;
|
||||
public string AccessToken;
|
||||
}
|
||||
|
||||
public class ExtendedGroupRoleMembersData
|
||||
{
|
||||
public UUID RoleID;
|
||||
// This is the only difference: this is a string
|
||||
public string MemberID;
|
||||
|
||||
}
|
||||
|
||||
public struct ExtendedGroupNoticeData
|
||||
{
|
||||
public UUID NoticeID;
|
||||
public uint Timestamp;
|
||||
public string FromName;
|
||||
public string Subject;
|
||||
public bool HasAttachment;
|
||||
public byte AttachmentType;
|
||||
public string AttachmentName;
|
||||
public UUID AttachmentItemID;
|
||||
public string AttachmentOwnerID;
|
||||
|
||||
public GroupNoticeData ToGroupNoticeData()
|
||||
{
|
||||
GroupNoticeData n = new GroupNoticeData();
|
||||
n.FromName = this.FromName;
|
||||
n.AssetType = this.AttachmentType;
|
||||
n.HasAttachment = this.HasAttachment;
|
||||
n.NoticeID = this.NoticeID;
|
||||
n.Subject = this.Subject;
|
||||
n.Timestamp = this.Timestamp;
|
||||
|
||||
return n;
|
||||
}
|
||||
}
|
||||
|
||||
public class GroupsDataUtils
|
||||
{
|
||||
public static string Sanitize(string s)
|
||||
{
|
||||
return s == null ? string.Empty : s;
|
||||
}
|
||||
|
||||
public static Dictionary<string, object> GroupRecord(ExtendedGroupRecord grec)
|
||||
{
|
||||
Dictionary<string, object> dict = new Dictionary<string, object>();
|
||||
if (grec == null)
|
||||
return dict;
|
||||
|
||||
dict["AllowPublish"] = grec.AllowPublish.ToString();
|
||||
dict["Charter"] = Sanitize(grec.Charter);
|
||||
dict["FounderID"] = grec.FounderID.ToString();
|
||||
dict["FounderUUI"] = Sanitize(grec.FounderUUI);
|
||||
dict["GroupID"] = grec.GroupID.ToString();
|
||||
dict["GroupName"] = Sanitize(grec.GroupName);
|
||||
dict["InsigniaID"] = grec.GroupPicture.ToString();
|
||||
dict["MaturePublish"] = grec.MaturePublish.ToString();
|
||||
dict["MembershipFee"] = grec.MembershipFee.ToString();
|
||||
dict["OpenEnrollment"] = grec.OpenEnrollment.ToString();
|
||||
dict["OwnerRoleID"] = grec.OwnerRoleID.ToString();
|
||||
dict["ServiceLocation"] = Sanitize(grec.ServiceLocation);
|
||||
dict["ShownInList"] = grec.ShowInList.ToString();
|
||||
dict["MemberCount"] = grec.MemberCount.ToString();
|
||||
dict["RoleCount"] = grec.RoleCount.ToString();
|
||||
|
||||
return dict;
|
||||
}
|
||||
|
||||
public static ExtendedGroupRecord GroupRecord(Dictionary<string, object> dict)
|
||||
{
|
||||
if (dict == null)
|
||||
return null;
|
||||
|
||||
ExtendedGroupRecord grec = new ExtendedGroupRecord();
|
||||
if (dict.ContainsKey("AllowPublish") && dict["AllowPublish"] != null)
|
||||
grec.AllowPublish = bool.Parse(dict["AllowPublish"].ToString());
|
||||
|
||||
if (dict.ContainsKey("Charter") && dict["Charter"] != null)
|
||||
grec.Charter = dict["Charter"].ToString();
|
||||
else
|
||||
grec.Charter = string.Empty;
|
||||
|
||||
if (dict.ContainsKey("FounderID") && dict["FounderID"] != null)
|
||||
grec.FounderID = UUID.Parse(dict["FounderID"].ToString());
|
||||
|
||||
if (dict.ContainsKey("FounderUUI") && dict["FounderUUI"] != null)
|
||||
grec.FounderUUI = dict["FounderUUI"].ToString();
|
||||
else
|
||||
grec.FounderUUI = string.Empty;
|
||||
|
||||
if (dict.ContainsKey("GroupID") && dict["GroupID"] != null)
|
||||
grec.GroupID = UUID.Parse(dict["GroupID"].ToString());
|
||||
|
||||
if (dict.ContainsKey("GroupName") && dict["GroupName"] != null)
|
||||
grec.GroupName = dict["GroupName"].ToString();
|
||||
else
|
||||
grec.GroupName = string.Empty;
|
||||
|
||||
if (dict.ContainsKey("InsigniaID") && dict["InsigniaID"] != null)
|
||||
grec.GroupPicture = UUID.Parse(dict["InsigniaID"].ToString());
|
||||
|
||||
if (dict.ContainsKey("MaturePublish") && dict["MaturePublish"] != null)
|
||||
grec.MaturePublish = bool.Parse(dict["MaturePublish"].ToString());
|
||||
|
||||
if (dict.ContainsKey("MembershipFee") && dict["MembershipFee"] != null)
|
||||
grec.MembershipFee = Int32.Parse(dict["MembershipFee"].ToString());
|
||||
|
||||
if (dict.ContainsKey("OpenEnrollment") && dict["OpenEnrollment"] != null)
|
||||
grec.OpenEnrollment = bool.Parse(dict["OpenEnrollment"].ToString());
|
||||
|
||||
if (dict.ContainsKey("OwnerRoleID") && dict["OwnerRoleID"] != null)
|
||||
grec.OwnerRoleID = UUID.Parse(dict["OwnerRoleID"].ToString());
|
||||
|
||||
if (dict.ContainsKey("ServiceLocation") && dict["ServiceLocation"] != null)
|
||||
grec.ServiceLocation = dict["ServiceLocation"].ToString();
|
||||
else
|
||||
grec.GroupName = string.Empty;
|
||||
|
||||
if (dict.ContainsKey("ShownInList") && dict["ShownInList"] != null)
|
||||
grec.ShowInList = bool.Parse(dict["ShownInList"].ToString());
|
||||
|
||||
if (dict.ContainsKey("MemberCount") && dict["MemberCount"] != null)
|
||||
grec.MemberCount = Int32.Parse(dict["MemberCount"].ToString());
|
||||
|
||||
if (dict.ContainsKey("RoleCount") && dict["RoleCount"] != null)
|
||||
grec.RoleCount = Int32.Parse(dict["RoleCount"].ToString());
|
||||
|
||||
return grec;
|
||||
}
|
||||
|
||||
public static Dictionary<string, object> GroupMembershipData(ExtendedGroupMembershipData membership)
|
||||
{
|
||||
Dictionary<string, object> dict = new Dictionary<string, object>();
|
||||
if (membership == null)
|
||||
return dict;
|
||||
|
||||
dict["AcceptNotices"] = membership.AcceptNotices.ToString();
|
||||
dict["AccessToken"] = Sanitize(membership.AccessToken);
|
||||
dict["Active"] = membership.Active.ToString();
|
||||
dict["ActiveRole"] = membership.ActiveRole.ToString();
|
||||
dict["AllowPublish"] = membership.AllowPublish.ToString();
|
||||
dict["Charter"] = Sanitize(membership.Charter);
|
||||
dict["Contribution"] = membership.Contribution.ToString();
|
||||
dict["FounderID"] = membership.FounderID.ToString();
|
||||
dict["GroupID"] = membership.GroupID.ToString();
|
||||
dict["GroupName"] = Sanitize(membership.GroupName);
|
||||
dict["GroupPicture"] = membership.GroupPicture.ToString();
|
||||
dict["GroupPowers"] = membership.GroupPowers.ToString();
|
||||
dict["GroupTitle"] = Sanitize(membership.GroupTitle);
|
||||
dict["ListInProfile"] = membership.ListInProfile.ToString();
|
||||
dict["MaturePublish"] = membership.MaturePublish.ToString();
|
||||
dict["MembershipFee"] = membership.MembershipFee.ToString();
|
||||
dict["OpenEnrollment"] = membership.OpenEnrollment.ToString();
|
||||
dict["ShowInList"] = membership.ShowInList.ToString();
|
||||
|
||||
return dict;
|
||||
}
|
||||
|
||||
public static ExtendedGroupMembershipData GroupMembershipData(Dictionary<string, object> dict)
|
||||
{
|
||||
if (dict == null)
|
||||
return null;
|
||||
|
||||
ExtendedGroupMembershipData membership = new ExtendedGroupMembershipData();
|
||||
|
||||
if (dict.ContainsKey("AcceptNotices") && dict["AcceptNotices"] != null)
|
||||
membership.AcceptNotices = bool.Parse(dict["AcceptNotices"].ToString());
|
||||
|
||||
if (dict.ContainsKey("AccessToken") && dict["AccessToken"] != null)
|
||||
membership.AccessToken = dict["AccessToken"].ToString();
|
||||
else
|
||||
membership.AccessToken = string.Empty;
|
||||
|
||||
if (dict.ContainsKey("Active") && dict["Active"] != null)
|
||||
membership.Active = bool.Parse(dict["Active"].ToString());
|
||||
|
||||
if (dict.ContainsKey("ActiveRole") && dict["ActiveRole"] != null)
|
||||
membership.ActiveRole = UUID.Parse(dict["ActiveRole"].ToString());
|
||||
|
||||
if (dict.ContainsKey("AllowPublish") && dict["AllowPublish"] != null)
|
||||
membership.AllowPublish = bool.Parse(dict["AllowPublish"].ToString());
|
||||
|
||||
if (dict.ContainsKey("Charter") && dict["Charter"] != null)
|
||||
membership.Charter = dict["Charter"].ToString();
|
||||
else
|
||||
membership.Charter = string.Empty;
|
||||
|
||||
if (dict.ContainsKey("Contribution") && dict["Contribution"] != null)
|
||||
membership.Contribution = Int32.Parse(dict["Contribution"].ToString());
|
||||
|
||||
if (dict.ContainsKey("FounderID") && dict["FounderID"] != null)
|
||||
membership.FounderID = UUID.Parse(dict["FounderID"].ToString());
|
||||
|
||||
if (dict.ContainsKey("GroupID") && dict["GroupID"] != null)
|
||||
membership.GroupID = UUID.Parse(dict["GroupID"].ToString());
|
||||
|
||||
if (dict.ContainsKey("GroupName") && dict["GroupName"] != null)
|
||||
membership.GroupName = dict["GroupName"].ToString();
|
||||
else
|
||||
membership.GroupName = string.Empty;
|
||||
|
||||
if (dict.ContainsKey("GroupPicture") && dict["GroupPicture"] != null)
|
||||
membership.GroupPicture = UUID.Parse(dict["GroupPicture"].ToString());
|
||||
|
||||
if (dict.ContainsKey("GroupPowers") && dict["GroupPowers"] != null)
|
||||
membership.GroupPowers = UInt64.Parse(dict["GroupPowers"].ToString());
|
||||
|
||||
if (dict.ContainsKey("GroupTitle") && dict["GroupTitle"] != null)
|
||||
membership.GroupTitle = dict["GroupTitle"].ToString();
|
||||
else
|
||||
membership.GroupTitle = string.Empty;
|
||||
|
||||
if (dict.ContainsKey("ListInProfile") && dict["ListInProfile"] != null)
|
||||
membership.ListInProfile = bool.Parse(dict["ListInProfile"].ToString());
|
||||
|
||||
if (dict.ContainsKey("MaturePublish") && dict["MaturePublish"] != null)
|
||||
membership.MaturePublish = bool.Parse(dict["MaturePublish"].ToString());
|
||||
|
||||
if (dict.ContainsKey("MembershipFee") && dict["MembershipFee"] != null)
|
||||
membership.MembershipFee = Int32.Parse(dict["MembershipFee"].ToString());
|
||||
|
||||
if (dict.ContainsKey("OpenEnrollment") && dict["OpenEnrollment"] != null)
|
||||
membership.OpenEnrollment = bool.Parse(dict["OpenEnrollment"].ToString());
|
||||
|
||||
if (dict.ContainsKey("ShowInList") && dict["ShowInList"] != null)
|
||||
membership.ShowInList = bool.Parse(dict["ShowInList"].ToString());
|
||||
|
||||
return membership;
|
||||
}
|
||||
|
||||
public static Dictionary<string, object> GroupMembersData(ExtendedGroupMembersData member)
|
||||
{
|
||||
Dictionary<string, object> dict = new Dictionary<string, object>();
|
||||
|
||||
dict["AcceptNotices"] = member.AcceptNotices.ToString();
|
||||
dict["AccessToken"] = Sanitize(member.AccessToken);
|
||||
dict["AgentID"] = Sanitize(member.AgentID);
|
||||
dict["AgentPowers"] = member.AgentPowers.ToString();
|
||||
dict["Contribution"] = member.Contribution.ToString();
|
||||
dict["IsOwner"] = member.IsOwner.ToString();
|
||||
dict["ListInProfile"] = member.ListInProfile.ToString();
|
||||
dict["OnlineStatus"] = Sanitize(member.OnlineStatus);
|
||||
dict["Title"] = Sanitize(member.Title);
|
||||
|
||||
return dict;
|
||||
}
|
||||
|
||||
public static ExtendedGroupMembersData GroupMembersData(Dictionary<string, object> dict)
|
||||
{
|
||||
ExtendedGroupMembersData member = new ExtendedGroupMembersData();
|
||||
|
||||
if (dict == null)
|
||||
return member;
|
||||
|
||||
if (dict.ContainsKey("AcceptNotices") && dict["AcceptNotices"] != null)
|
||||
member.AcceptNotices = bool.Parse(dict["AcceptNotices"].ToString());
|
||||
|
||||
if (dict.ContainsKey("AccessToken") && dict["AccessToken"] != null)
|
||||
member.AccessToken = Sanitize(dict["AccessToken"].ToString());
|
||||
else
|
||||
member.AccessToken = string.Empty;
|
||||
|
||||
if (dict.ContainsKey("AgentID") && dict["AgentID"] != null)
|
||||
member.AgentID = Sanitize(dict["AgentID"].ToString());
|
||||
else
|
||||
member.AgentID = UUID.Zero.ToString();
|
||||
|
||||
if (dict.ContainsKey("AgentPowers") && dict["AgentPowers"] != null)
|
||||
member.AgentPowers = UInt64.Parse(dict["AgentPowers"].ToString());
|
||||
|
||||
if (dict.ContainsKey("Contribution") && dict["Contribution"] != null)
|
||||
member.Contribution = Int32.Parse(dict["Contribution"].ToString());
|
||||
|
||||
if (dict.ContainsKey("IsOwner") && dict["IsOwner"] != null)
|
||||
member.IsOwner = bool.Parse(dict["IsOwner"].ToString());
|
||||
|
||||
if (dict.ContainsKey("ListInProfile") && dict["ListInProfile"] != null)
|
||||
member.ListInProfile = bool.Parse(dict["ListInProfile"].ToString());
|
||||
|
||||
if (dict.ContainsKey("OnlineStatus") && dict["OnlineStatus"] != null)
|
||||
member.OnlineStatus = Sanitize(dict["OnlineStatus"].ToString());
|
||||
else
|
||||
member.OnlineStatus = string.Empty;
|
||||
|
||||
if (dict.ContainsKey("Title") && dict["Title"] != null)
|
||||
member.Title = Sanitize(dict["Title"].ToString());
|
||||
else
|
||||
member.Title = string.Empty;
|
||||
|
||||
return member;
|
||||
}
|
||||
|
||||
public static Dictionary<string, object> GroupRolesData(GroupRolesData role)
|
||||
{
|
||||
Dictionary<string, object> dict = new Dictionary<string, object>();
|
||||
|
||||
dict["Description"] = Sanitize(role.Description);
|
||||
dict["Members"] = role.Members.ToString();
|
||||
dict["Name"] = Sanitize(role.Name);
|
||||
dict["Powers"] = role.Powers.ToString();
|
||||
dict["RoleID"] = role.RoleID.ToString();
|
||||
dict["Title"] = Sanitize(role.Title);
|
||||
|
||||
return dict;
|
||||
}
|
||||
|
||||
public static GroupRolesData GroupRolesData(Dictionary<string, object> dict)
|
||||
{
|
||||
GroupRolesData role = new GroupRolesData();
|
||||
|
||||
if (dict == null)
|
||||
return role;
|
||||
|
||||
if (dict.ContainsKey("Description") && dict["Description"] != null)
|
||||
role.Description = Sanitize(dict["Description"].ToString());
|
||||
else
|
||||
role.Description = string.Empty;
|
||||
|
||||
if (dict.ContainsKey("Members") && dict["Members"] != null)
|
||||
role.Members = Int32.Parse(dict["Members"].ToString());
|
||||
|
||||
if (dict.ContainsKey("Name") && dict["Name"] != null)
|
||||
role.Name = Sanitize(dict["Name"].ToString());
|
||||
else
|
||||
role.Name = string.Empty;
|
||||
|
||||
if (dict.ContainsKey("Powers") && dict["Powers"] != null)
|
||||
role.Powers = UInt64.Parse(dict["Powers"].ToString());
|
||||
|
||||
if (dict.ContainsKey("Title") && dict["Title"] != null)
|
||||
role.Title = Sanitize(dict["Title"].ToString());
|
||||
else
|
||||
role.Title = string.Empty;
|
||||
|
||||
if (dict.ContainsKey("RoleID") && dict["RoleID"] != null)
|
||||
role.RoleID = UUID.Parse(dict["RoleID"].ToString());
|
||||
|
||||
return role;
|
||||
}
|
||||
|
||||
public static Dictionary<string, object> GroupRoleMembersData(ExtendedGroupRoleMembersData rmember)
|
||||
{
|
||||
Dictionary<string, object> dict = new Dictionary<string, object>();
|
||||
|
||||
dict["RoleID"] = rmember.RoleID.ToString();
|
||||
dict["MemberID"] = rmember.MemberID;
|
||||
return dict;
|
||||
}
|
||||
|
||||
public static ExtendedGroupRoleMembersData GroupRoleMembersData(Dictionary<string, object> dict)
|
||||
{
|
||||
ExtendedGroupRoleMembersData rmember = new ExtendedGroupRoleMembersData();
|
||||
|
||||
if (dict.ContainsKey("RoleID") && dict["RoleID"] != null)
|
||||
rmember.RoleID = new UUID(dict["RoleID"].ToString());
|
||||
|
||||
if (dict.ContainsKey("MemberID") && dict["MemberID"] != null)
|
||||
rmember.MemberID = dict["MemberID"].ToString();
|
||||
|
||||
return rmember;
|
||||
}
|
||||
|
||||
public static Dictionary<string, object> GroupInviteInfo(GroupInviteInfo invite)
|
||||
{
|
||||
Dictionary<string, object> dict = new Dictionary<string, object>();
|
||||
|
||||
dict["InviteID"] = invite.InviteID.ToString();
|
||||
dict["GroupID"] = invite.GroupID.ToString();
|
||||
dict["RoleID"] = invite.RoleID.ToString();
|
||||
dict["AgentID"] = invite.AgentID;
|
||||
|
||||
return dict;
|
||||
}
|
||||
|
||||
public static GroupInviteInfo GroupInviteInfo(Dictionary<string, object> dict)
|
||||
{
|
||||
if (dict == null)
|
||||
return null;
|
||||
|
||||
GroupInviteInfo invite = new GroupInviteInfo();
|
||||
|
||||
invite.InviteID = new UUID(dict["InviteID"].ToString());
|
||||
invite.GroupID = new UUID(dict["GroupID"].ToString());
|
||||
invite.RoleID = new UUID(dict["RoleID"].ToString());
|
||||
invite.AgentID = Sanitize(dict["AgentID"].ToString());
|
||||
|
||||
return invite;
|
||||
}
|
||||
|
||||
public static Dictionary<string, object> GroupNoticeData(ExtendedGroupNoticeData notice)
|
||||
{
|
||||
Dictionary<string, object> dict = new Dictionary<string, object>();
|
||||
|
||||
dict["NoticeID"] = notice.NoticeID.ToString();
|
||||
dict["Timestamp"] = notice.Timestamp.ToString();
|
||||
dict["FromName"] = Sanitize(notice.FromName);
|
||||
dict["Subject"] = Sanitize(notice.Subject);
|
||||
dict["HasAttachment"] = notice.HasAttachment.ToString();
|
||||
dict["AttachmentItemID"] = notice.AttachmentItemID.ToString();
|
||||
dict["AttachmentName"] = Sanitize(notice.AttachmentName);
|
||||
dict["AttachmentType"] = notice.AttachmentType.ToString();
|
||||
dict["AttachmentOwnerID"] = Sanitize(notice.AttachmentOwnerID);
|
||||
|
||||
return dict;
|
||||
}
|
||||
|
||||
public static ExtendedGroupNoticeData GroupNoticeData(Dictionary<string, object> dict)
|
||||
{
|
||||
ExtendedGroupNoticeData notice = new ExtendedGroupNoticeData();
|
||||
|
||||
if (dict == null)
|
||||
return notice;
|
||||
|
||||
notice.NoticeID = new UUID(dict["NoticeID"].ToString());
|
||||
notice.Timestamp = UInt32.Parse(dict["Timestamp"].ToString());
|
||||
notice.FromName = Sanitize(dict["FromName"].ToString());
|
||||
notice.Subject = Sanitize(dict["Subject"].ToString());
|
||||
notice.HasAttachment = bool.Parse(dict["HasAttachment"].ToString());
|
||||
notice.AttachmentItemID = new UUID(dict["AttachmentItemID"].ToString());
|
||||
notice.AttachmentName = dict["AttachmentName"].ToString();
|
||||
notice.AttachmentType = byte.Parse(dict["AttachmentType"].ToString());
|
||||
notice.AttachmentOwnerID = dict["AttachmentOwnerID"].ToString();
|
||||
|
||||
return notice;
|
||||
}
|
||||
|
||||
public static Dictionary<string, object> GroupNoticeInfo(GroupNoticeInfo notice)
|
||||
{
|
||||
Dictionary<string, object> dict = GroupNoticeData(notice.noticeData);
|
||||
|
||||
dict["GroupID"] = notice.GroupID.ToString();
|
||||
dict["Message"] = Sanitize(notice.Message);
|
||||
|
||||
return dict;
|
||||
}
|
||||
|
||||
public static GroupNoticeInfo GroupNoticeInfo(Dictionary<string, object> dict)
|
||||
{
|
||||
GroupNoticeInfo notice = new GroupNoticeInfo();
|
||||
|
||||
notice.noticeData = GroupNoticeData(dict);
|
||||
notice.GroupID = new UUID(dict["GroupID"].ToString());
|
||||
notice.Message = Sanitize(dict["Message"].ToString());
|
||||
|
||||
return notice;
|
||||
}
|
||||
|
||||
public static Dictionary<string, object> DirGroupsReplyData(DirGroupsReplyData g)
|
||||
{
|
||||
Dictionary<string, object> dict = new Dictionary<string, object>();
|
||||
|
||||
dict["GroupID"] = g.groupID;
|
||||
dict["Name"] = g.groupName;
|
||||
dict["NMembers"] = g.members;
|
||||
dict["SearchOrder"] = g.searchOrder;
|
||||
|
||||
return dict;
|
||||
}
|
||||
|
||||
public static DirGroupsReplyData DirGroupsReplyData(Dictionary<string, object> dict)
|
||||
{
|
||||
DirGroupsReplyData g;
|
||||
|
||||
g.groupID = new UUID(dict["GroupID"].ToString());
|
||||
g.groupName = dict["Name"].ToString();
|
||||
Int32.TryParse(dict["NMembers"].ToString(), out g.members);
|
||||
float.TryParse(dict["SearchOrder"].ToString(), out g.searchOrder);
|
||||
|
||||
return g;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,784 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using log4net;
|
||||
using Mono.Addins;
|
||||
using Nini.Config;
|
||||
using OpenMetaverse;
|
||||
using OpenMetaverse.StructuredData;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo;
|
||||
using GridRegion = OpenSim.Services.Interfaces.GridRegion;
|
||||
|
||||
namespace OpenSim.Groups
|
||||
{
|
||||
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GroupsMessagingModule")]
|
||||
public class GroupsMessagingModule : ISharedRegionModule, IGroupsMessagingModule
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private List<Scene> m_sceneList = new List<Scene>();
|
||||
private IPresenceService m_presenceService;
|
||||
|
||||
private IMessageTransferModule m_msgTransferModule = null;
|
||||
private IUserManagement m_UserManagement = null;
|
||||
private IGroupsServicesConnector m_groupData = null;
|
||||
|
||||
// Config Options
|
||||
private bool m_groupMessagingEnabled = false;
|
||||
private bool m_debugEnabled = true;
|
||||
|
||||
/// <summary>
|
||||
/// If enabled, module only tries to send group IMs to online users by querying cached presence information.
|
||||
/// </summary>
|
||||
private bool m_messageOnlineAgentsOnly;
|
||||
|
||||
/// <summary>
|
||||
/// Cache for online users.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Group ID is key, presence information for online members is value.
|
||||
/// Will only be non-null if m_messageOnlineAgentsOnly = true
|
||||
/// We cache here so that group messages don't constantly have to re-request the online user list to avoid
|
||||
/// attempted expensive sending of messages to offline users.
|
||||
/// The tradeoff is that a user that comes online will not receive messages consistently from all other users
|
||||
/// until caches have updated.
|
||||
/// Therefore, we set the cache expiry to just 20 seconds.
|
||||
/// </remarks>
|
||||
private ExpiringCache<UUID, PresenceInfo[]> m_usersOnlineCache;
|
||||
|
||||
private int m_usersOnlineCacheExpirySeconds = 20;
|
||||
|
||||
private Dictionary<UUID, List<string>> m_groupsAgentsDroppedFromChatSession = new Dictionary<UUID, List<string>>();
|
||||
private Dictionary<UUID, List<string>> m_groupsAgentsInvitedToChatSession = new Dictionary<UUID, List<string>>();
|
||||
|
||||
|
||||
#region Region Module interfaceBase Members
|
||||
|
||||
public void Initialise(IConfigSource config)
|
||||
{
|
||||
IConfig groupsConfig = config.Configs["Groups"];
|
||||
|
||||
if (groupsConfig == null)
|
||||
// Do not run this module by default.
|
||||
return;
|
||||
|
||||
// if groups aren't enabled, we're not needed.
|
||||
// if we're not specified as the connector to use, then we're not wanted
|
||||
if ((groupsConfig.GetBoolean("Enabled", false) == false)
|
||||
|| (groupsConfig.GetString("MessagingModule", "") != Name))
|
||||
{
|
||||
m_groupMessagingEnabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
m_groupMessagingEnabled = groupsConfig.GetBoolean("MessagingEnabled", true);
|
||||
|
||||
if (!m_groupMessagingEnabled)
|
||||
return;
|
||||
|
||||
m_messageOnlineAgentsOnly = groupsConfig.GetBoolean("MessageOnlineUsersOnly", false);
|
||||
|
||||
if (m_messageOnlineAgentsOnly)
|
||||
m_usersOnlineCache = new ExpiringCache<UUID, PresenceInfo[]>();
|
||||
|
||||
m_debugEnabled = groupsConfig.GetBoolean("DebugEnabled", true);
|
||||
|
||||
m_log.InfoFormat(
|
||||
"[Groups.Messaging]: GroupsMessagingModule enabled with MessageOnlineOnly = {0}, DebugEnabled = {1}",
|
||||
m_messageOnlineAgentsOnly, m_debugEnabled);
|
||||
}
|
||||
|
||||
public void AddRegion(Scene scene)
|
||||
{
|
||||
if (!m_groupMessagingEnabled)
|
||||
return;
|
||||
|
||||
scene.RegisterModuleInterface<IGroupsMessagingModule>(this);
|
||||
m_sceneList.Add(scene);
|
||||
|
||||
scene.EventManager.OnNewClient += OnNewClient;
|
||||
scene.EventManager.OnMakeRootAgent += OnMakeRootAgent;
|
||||
scene.EventManager.OnMakeChildAgent += OnMakeChildAgent;
|
||||
scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage;
|
||||
scene.EventManager.OnClientLogin += OnClientLogin;
|
||||
}
|
||||
|
||||
public void RegionLoaded(Scene scene)
|
||||
{
|
||||
if (!m_groupMessagingEnabled)
|
||||
return;
|
||||
|
||||
if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
|
||||
|
||||
m_groupData = scene.RequestModuleInterface<IGroupsServicesConnector>();
|
||||
|
||||
// No groups module, no groups messaging
|
||||
if (m_groupData == null)
|
||||
{
|
||||
m_log.Error("[Groups.Messaging]: Could not get IGroupsServicesConnector, GroupsMessagingModule is now disabled.");
|
||||
RemoveRegion(scene);
|
||||
return;
|
||||
}
|
||||
|
||||
m_msgTransferModule = scene.RequestModuleInterface<IMessageTransferModule>();
|
||||
|
||||
// No message transfer module, no groups messaging
|
||||
if (m_msgTransferModule == null)
|
||||
{
|
||||
m_log.Error("[Groups.Messaging]: Could not get MessageTransferModule");
|
||||
RemoveRegion(scene);
|
||||
return;
|
||||
}
|
||||
|
||||
m_UserManagement = scene.RequestModuleInterface<IUserManagement>();
|
||||
|
||||
// No groups module, no groups messaging
|
||||
if (m_UserManagement == null)
|
||||
{
|
||||
m_log.Error("[Groups.Messaging]: Could not get IUserManagement, GroupsMessagingModule is now disabled.");
|
||||
RemoveRegion(scene);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (m_presenceService == null)
|
||||
m_presenceService = scene.PresenceService;
|
||||
|
||||
}
|
||||
|
||||
public void RemoveRegion(Scene scene)
|
||||
{
|
||||
if (!m_groupMessagingEnabled)
|
||||
return;
|
||||
|
||||
if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
|
||||
|
||||
m_sceneList.Remove(scene);
|
||||
scene.EventManager.OnNewClient -= OnNewClient;
|
||||
scene.EventManager.OnIncomingInstantMessage -= OnGridInstantMessage;
|
||||
scene.EventManager.OnClientLogin -= OnClientLogin;
|
||||
scene.UnregisterModuleInterface<IGroupsMessagingModule>(this);
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
if (!m_groupMessagingEnabled)
|
||||
return;
|
||||
|
||||
if (m_debugEnabled) m_log.Debug("[Groups.Messaging]: Shutting down GroupsMessagingModule module.");
|
||||
|
||||
m_sceneList.Clear();
|
||||
|
||||
m_groupData = null;
|
||||
m_msgTransferModule = null;
|
||||
}
|
||||
|
||||
public Type ReplaceableInterface
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return "Groups Messaging Module V2"; }
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
// NoOp
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Not really needed, but does confirm that the group exists.
|
||||
/// </summary>
|
||||
public bool StartGroupChatSession(UUID agentID, UUID groupID)
|
||||
{
|
||||
if (m_debugEnabled)
|
||||
m_log.DebugFormat("[Groups.Messaging]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
|
||||
|
||||
GroupRecord groupInfo = m_groupData.GetGroupRecord(agentID.ToString(), groupID, null);
|
||||
|
||||
if (groupInfo != null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void SendMessageToGroup(GridInstantMessage im, UUID groupID)
|
||||
{
|
||||
UUID fromAgentID = new UUID(im.fromAgentID);
|
||||
List<GroupMembersData> groupMembers = m_groupData.GetGroupMembers(UUID.Zero.ToString(), groupID);
|
||||
int groupMembersCount = groupMembers.Count;
|
||||
PresenceInfo[] onlineAgents = null;
|
||||
|
||||
// In V2 we always only send to online members.
|
||||
// Sending to offline members is not an option.
|
||||
string[] t1 = groupMembers.ConvertAll<string>(gmd => gmd.AgentID.ToString()).ToArray();
|
||||
|
||||
// We cache in order not to overwhlem the presence service on large grids with many groups. This does
|
||||
// mean that members coming online will not see all group members until after m_usersOnlineCacheExpirySeconds has elapsed.
|
||||
// (assuming this is the same across all grid simulators).
|
||||
if (!m_usersOnlineCache.TryGetValue(groupID, out onlineAgents))
|
||||
{
|
||||
onlineAgents = m_presenceService.GetAgents(t1);
|
||||
m_usersOnlineCache.Add(groupID, onlineAgents, m_usersOnlineCacheExpirySeconds);
|
||||
}
|
||||
|
||||
HashSet<string> onlineAgentsUuidSet = new HashSet<string>();
|
||||
Array.ForEach<PresenceInfo>(onlineAgents, pi => onlineAgentsUuidSet.Add(pi.UserID));
|
||||
|
||||
groupMembers = groupMembers.Where(gmd => onlineAgentsUuidSet.Contains(gmd.AgentID.ToString())).ToList();
|
||||
|
||||
// if (m_debugEnabled)
|
||||
// m_log.DebugFormat(
|
||||
// "[Groups.Messaging]: SendMessageToGroup called for group {0} with {1} visible members, {2} online",
|
||||
// groupID, groupMembersCount, groupMembers.Count());
|
||||
|
||||
int requestStartTick = Environment.TickCount;
|
||||
|
||||
im.imSessionID = groupID.Guid;
|
||||
im.fromGroup = true;
|
||||
IClientAPI thisClient = GetActiveClient(fromAgentID);
|
||||
if (thisClient != null)
|
||||
{
|
||||
im.RegionID = thisClient.Scene.RegionInfo.RegionID.Guid;
|
||||
}
|
||||
|
||||
// Send to self first of all
|
||||
im.toAgentID = im.fromAgentID;
|
||||
im.fromGroup = true;
|
||||
ProcessMessageFromGroupSession(im);
|
||||
|
||||
List<UUID> regions = new List<UUID>();
|
||||
List<UUID> clientsAlreadySent = new List<UUID>();
|
||||
|
||||
// Then send to everybody else
|
||||
foreach (GroupMembersData member in groupMembers)
|
||||
{
|
||||
if (member.AgentID.Guid == im.fromAgentID)
|
||||
continue;
|
||||
|
||||
if (clientsAlreadySent.Contains(member.AgentID))
|
||||
continue;
|
||||
clientsAlreadySent.Add(member.AgentID);
|
||||
|
||||
if (hasAgentDroppedGroupChatSession(member.AgentID.ToString(), groupID))
|
||||
{
|
||||
// Don't deliver messages to people who have dropped this session
|
||||
if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: {0} has dropped session, not delivering to them", member.AgentID);
|
||||
continue;
|
||||
}
|
||||
|
||||
im.toAgentID = member.AgentID.Guid;
|
||||
|
||||
IClientAPI client = GetActiveClient(member.AgentID);
|
||||
if (client == null)
|
||||
{
|
||||
// If they're not local, forward across the grid
|
||||
// BUT do it only once per region, please! Sim would be even better!
|
||||
if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Delivering to {0} via Grid", member.AgentID);
|
||||
|
||||
bool reallySend = true;
|
||||
if (onlineAgents != null)
|
||||
{
|
||||
PresenceInfo presence = onlineAgents.First(p => p.UserID == member.AgentID.ToString());
|
||||
if (regions.Contains(presence.RegionID))
|
||||
reallySend = false;
|
||||
else
|
||||
regions.Add(presence.RegionID);
|
||||
}
|
||||
|
||||
if (reallySend)
|
||||
{
|
||||
// We have to create a new IM structure because the transfer module
|
||||
// uses async send
|
||||
GridInstantMessage msg = new GridInstantMessage(im, true);
|
||||
m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { });
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Deliver locally, directly
|
||||
if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Passing to ProcessMessageFromGroupSession to deliver to {0} locally", client.Name);
|
||||
|
||||
ProcessMessageFromGroupSession(im);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (m_debugEnabled)
|
||||
m_log.DebugFormat(
|
||||
"[Groups.Messaging]: SendMessageToGroup for group {0} with {1} visible members, {2} online took {3}ms",
|
||||
groupID, groupMembersCount, groupMembers.Count(), Environment.TickCount - requestStartTick);
|
||||
}
|
||||
|
||||
#region SimGridEventHandlers
|
||||
|
||||
void OnClientLogin(IClientAPI client)
|
||||
{
|
||||
if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: OnInstantMessage registered for {0}", client.Name);
|
||||
}
|
||||
|
||||
private void OnNewClient(IClientAPI client)
|
||||
{
|
||||
if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: OnInstantMessage registered for {0}", client.Name);
|
||||
|
||||
ResetAgentGroupChatSessions(client.AgentId.ToString());
|
||||
}
|
||||
|
||||
void OnMakeRootAgent(ScenePresence sp)
|
||||
{
|
||||
sp.ControllingClient.OnInstantMessage += OnInstantMessage;
|
||||
}
|
||||
|
||||
void OnMakeChildAgent(ScenePresence sp)
|
||||
{
|
||||
sp.ControllingClient.OnInstantMessage -= OnInstantMessage;
|
||||
}
|
||||
|
||||
|
||||
private void OnGridInstantMessage(GridInstantMessage msg)
|
||||
{
|
||||
// The instant message module will only deliver messages of dialog types:
|
||||
// MessageFromAgent, StartTyping, StopTyping, MessageFromObject
|
||||
//
|
||||
// Any other message type will not be delivered to a client by the
|
||||
// Instant Message Module
|
||||
|
||||
UUID regionID = new UUID(msg.RegionID);
|
||||
if (m_debugEnabled)
|
||||
{
|
||||
m_log.DebugFormat("[Groups.Messaging]: {0} called, IM from region {1}",
|
||||
System.Reflection.MethodBase.GetCurrentMethod().Name, regionID);
|
||||
|
||||
DebugGridInstantMessage(msg);
|
||||
}
|
||||
|
||||
// Incoming message from a group
|
||||
if ((msg.fromGroup == true) && (msg.dialog == (byte)InstantMessageDialog.SessionSend))
|
||||
{
|
||||
// We have to redistribute the message across all members of the group who are here
|
||||
// on this sim
|
||||
|
||||
UUID GroupID = new UUID(msg.imSessionID);
|
||||
|
||||
Scene aScene = m_sceneList[0];
|
||||
GridRegion regionOfOrigin = aScene.GridService.GetRegionByUUID(aScene.RegionInfo.ScopeID, regionID);
|
||||
|
||||
List<GroupMembersData> groupMembers = m_groupData.GetGroupMembers(UUID.Zero.ToString(), GroupID);
|
||||
|
||||
//if (m_debugEnabled)
|
||||
// foreach (GroupMembersData m in groupMembers)
|
||||
// m_log.DebugFormat("[Groups.Messaging]: member {0}", m.AgentID);
|
||||
|
||||
foreach (Scene s in m_sceneList)
|
||||
{
|
||||
s.ForEachScenePresence(sp =>
|
||||
{
|
||||
// If we got this via grid messaging, it's because the caller thinks
|
||||
// that the root agent is here. We should only send the IM to root agents.
|
||||
if (sp.IsChildAgent)
|
||||
return;
|
||||
|
||||
GroupMembersData m = groupMembers.Find(gmd =>
|
||||
{
|
||||
return gmd.AgentID == sp.UUID;
|
||||
});
|
||||
if (m.AgentID == UUID.Zero)
|
||||
{
|
||||
if (m_debugEnabled)
|
||||
m_log.DebugFormat("[Groups.Messaging]: skipping agent {0} because he is not a member of the group", sp.UUID);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if the user has an agent in the region where
|
||||
// the IM came from, and if so, skip it, because the IM
|
||||
// was already sent via that agent
|
||||
if (regionOfOrigin != null)
|
||||
{
|
||||
AgentCircuitData aCircuit = s.AuthenticateHandler.GetAgentCircuitData(sp.UUID);
|
||||
if (aCircuit != null)
|
||||
{
|
||||
if (aCircuit.ChildrenCapSeeds.Keys.Contains(regionOfOrigin.RegionHandle))
|
||||
{
|
||||
if (m_debugEnabled)
|
||||
m_log.DebugFormat("[Groups.Messaging]: skipping agent {0} because he has an agent in region of origin", sp.UUID);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_debugEnabled)
|
||||
m_log.DebugFormat("[Groups.Messaging]: not skipping agent {0}", sp.UUID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UUID AgentID = sp.UUID;
|
||||
msg.toAgentID = AgentID.Guid;
|
||||
|
||||
if (!hasAgentDroppedGroupChatSession(AgentID.ToString(), GroupID))
|
||||
{
|
||||
if (!hasAgentBeenInvitedToGroupChatSession(AgentID.ToString(), GroupID))
|
||||
AddAgentToSession(AgentID, GroupID, msg);
|
||||
else
|
||||
{
|
||||
if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Passing to ProcessMessageFromGroupSession to deliver to {0} locally", sp.Name);
|
||||
|
||||
ProcessMessageFromGroupSession(msg);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessMessageFromGroupSession(GridInstantMessage msg)
|
||||
{
|
||||
if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Session message from {0} going to agent {1}", msg.fromAgentName, msg.toAgentID);
|
||||
|
||||
UUID AgentID = new UUID(msg.fromAgentID);
|
||||
UUID GroupID = new UUID(msg.imSessionID);
|
||||
UUID toAgentID = new UUID(msg.toAgentID);
|
||||
|
||||
switch (msg.dialog)
|
||||
{
|
||||
case (byte)InstantMessageDialog.SessionAdd:
|
||||
AgentInvitedToGroupChatSession(AgentID.ToString(), GroupID);
|
||||
break;
|
||||
|
||||
case (byte)InstantMessageDialog.SessionDrop:
|
||||
AgentDroppedFromGroupChatSession(AgentID.ToString(), GroupID);
|
||||
break;
|
||||
|
||||
case (byte)InstantMessageDialog.SessionSend:
|
||||
// User hasn't dropped, so they're in the session,
|
||||
// maybe we should deliver it.
|
||||
IClientAPI client = GetActiveClient(new UUID(msg.toAgentID));
|
||||
if (client != null)
|
||||
{
|
||||
// Deliver locally, directly
|
||||
if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Delivering to {0} locally", client.Name);
|
||||
|
||||
if (!hasAgentDroppedGroupChatSession(toAgentID.ToString(), GroupID))
|
||||
{
|
||||
if (!hasAgentBeenInvitedToGroupChatSession(toAgentID.ToString(), GroupID))
|
||||
// This actually sends the message too, so no need to resend it
|
||||
// with client.SendInstantMessage
|
||||
AddAgentToSession(toAgentID, GroupID, msg);
|
||||
else
|
||||
client.SendInstantMessage(msg);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.WarnFormat("[Groups.Messaging]: Received a message over the grid for a client that isn't here: {0}", msg.toAgentID);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
m_log.WarnFormat("[Groups.Messaging]: I don't know how to proccess a {0} message.", ((InstantMessageDialog)msg.dialog).ToString());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void AddAgentToSession(UUID AgentID, UUID GroupID, GridInstantMessage msg)
|
||||
{
|
||||
// Agent not in session and hasn't dropped from session
|
||||
// Add them to the session for now, and Invite them
|
||||
AgentInvitedToGroupChatSession(AgentID.ToString(), GroupID);
|
||||
|
||||
IClientAPI activeClient = GetActiveClient(AgentID);
|
||||
if (activeClient != null)
|
||||
{
|
||||
GroupRecord groupInfo = m_groupData.GetGroupRecord(UUID.Zero.ToString(), GroupID, null);
|
||||
if (groupInfo != null)
|
||||
{
|
||||
if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Sending chatterbox invite instant message");
|
||||
|
||||
// Force? open the group session dialog???
|
||||
// and simultanously deliver the message, so we don't need to do a seperate client.SendInstantMessage(msg);
|
||||
IEventQueue eq = activeClient.Scene.RequestModuleInterface<IEventQueue>();
|
||||
eq.ChatterboxInvitation(
|
||||
GroupID
|
||||
, groupInfo.GroupName
|
||||
, new UUID(msg.fromAgentID)
|
||||
, msg.message
|
||||
, AgentID
|
||||
, msg.fromAgentName
|
||||
, msg.dialog
|
||||
, msg.timestamp
|
||||
, msg.offline == 1
|
||||
, (int)msg.ParentEstateID
|
||||
, msg.Position
|
||||
, 1
|
||||
, new UUID(msg.imSessionID)
|
||||
, msg.fromGroup
|
||||
, OpenMetaverse.Utils.StringToBytes(groupInfo.GroupName)
|
||||
);
|
||||
|
||||
eq.ChatterBoxSessionAgentListUpdates(
|
||||
new UUID(GroupID)
|
||||
, AgentID
|
||||
, new UUID(msg.toAgentID)
|
||||
, false //canVoiceChat
|
||||
, false //isModerator
|
||||
, false //text mute
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region ClientEvents
|
||||
private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im)
|
||||
{
|
||||
if (m_debugEnabled)
|
||||
{
|
||||
m_log.DebugFormat("[Groups.Messaging]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
|
||||
|
||||
DebugGridInstantMessage(im);
|
||||
}
|
||||
|
||||
// Start group IM session
|
||||
if ((im.dialog == (byte)InstantMessageDialog.SessionGroupStart))
|
||||
{
|
||||
if (m_debugEnabled) m_log.InfoFormat("[Groups.Messaging]: imSessionID({0}) toAgentID({1})", im.imSessionID, im.toAgentID);
|
||||
|
||||
UUID GroupID = new UUID(im.imSessionID);
|
||||
UUID AgentID = new UUID(im.fromAgentID);
|
||||
|
||||
GroupRecord groupInfo = m_groupData.GetGroupRecord(UUID.Zero.ToString(), GroupID, null);
|
||||
|
||||
if (groupInfo != null)
|
||||
{
|
||||
AgentInvitedToGroupChatSession(AgentID.ToString(), GroupID);
|
||||
|
||||
ChatterBoxSessionStartReplyViaCaps(remoteClient, groupInfo.GroupName, GroupID);
|
||||
|
||||
IEventQueue queue = remoteClient.Scene.RequestModuleInterface<IEventQueue>();
|
||||
queue.ChatterBoxSessionAgentListUpdates(
|
||||
GroupID
|
||||
, AgentID
|
||||
, new UUID(im.toAgentID)
|
||||
, false //canVoiceChat
|
||||
, false //isModerator
|
||||
, false //text mute
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Send a message from locally connected client to a group
|
||||
if ((im.dialog == (byte)InstantMessageDialog.SessionSend))
|
||||
{
|
||||
UUID GroupID = new UUID(im.imSessionID);
|
||||
UUID AgentID = new UUID(im.fromAgentID);
|
||||
|
||||
if (m_debugEnabled)
|
||||
m_log.DebugFormat("[Groups.Messaging]: Send message to session for group {0} with session ID {1}", GroupID, im.imSessionID.ToString());
|
||||
|
||||
//If this agent is sending a message, then they want to be in the session
|
||||
AgentInvitedToGroupChatSession(AgentID.ToString(), GroupID);
|
||||
|
||||
SendMessageToGroup(im, GroupID);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
void ChatterBoxSessionStartReplyViaCaps(IClientAPI remoteClient, string groupName, UUID groupID)
|
||||
{
|
||||
if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
|
||||
|
||||
OSDMap moderatedMap = new OSDMap(4);
|
||||
moderatedMap.Add("voice", OSD.FromBoolean(false));
|
||||
|
||||
OSDMap sessionMap = new OSDMap(4);
|
||||
sessionMap.Add("moderated_mode", moderatedMap);
|
||||
sessionMap.Add("session_name", OSD.FromString(groupName));
|
||||
sessionMap.Add("type", OSD.FromInteger(0));
|
||||
sessionMap.Add("voice_enabled", OSD.FromBoolean(false));
|
||||
|
||||
OSDMap bodyMap = new OSDMap(4);
|
||||
bodyMap.Add("session_id", OSD.FromUUID(groupID));
|
||||
bodyMap.Add("temp_session_id", OSD.FromUUID(groupID));
|
||||
bodyMap.Add("success", OSD.FromBoolean(true));
|
||||
bodyMap.Add("session_info", sessionMap);
|
||||
|
||||
IEventQueue queue = remoteClient.Scene.RequestModuleInterface<IEventQueue>();
|
||||
|
||||
if (queue != null)
|
||||
{
|
||||
queue.Enqueue(queue.BuildEvent("ChatterBoxSessionStartReply", bodyMap), remoteClient.AgentId);
|
||||
}
|
||||
}
|
||||
|
||||
private void DebugGridInstantMessage(GridInstantMessage im)
|
||||
{
|
||||
// Don't log any normal IMs (privacy!)
|
||||
if (m_debugEnabled && im.dialog != (byte)InstantMessageDialog.MessageFromAgent)
|
||||
{
|
||||
m_log.WarnFormat("[Groups.Messaging]: IM: fromGroup({0})", im.fromGroup ? "True" : "False");
|
||||
m_log.WarnFormat("[Groups.Messaging]: IM: Dialog({0})", ((InstantMessageDialog)im.dialog).ToString());
|
||||
m_log.WarnFormat("[Groups.Messaging]: IM: fromAgentID({0})", im.fromAgentID.ToString());
|
||||
m_log.WarnFormat("[Groups.Messaging]: IM: fromAgentName({0})", im.fromAgentName.ToString());
|
||||
m_log.WarnFormat("[Groups.Messaging]: IM: imSessionID({0})", im.imSessionID.ToString());
|
||||
m_log.WarnFormat("[Groups.Messaging]: IM: message({0})", im.message.ToString());
|
||||
m_log.WarnFormat("[Groups.Messaging]: IM: offline({0})", im.offline.ToString());
|
||||
m_log.WarnFormat("[Groups.Messaging]: IM: toAgentID({0})", im.toAgentID.ToString());
|
||||
m_log.WarnFormat("[Groups.Messaging]: IM: binaryBucket({0})", OpenMetaverse.Utils.BytesToHexString(im.binaryBucket, "BinaryBucket"));
|
||||
}
|
||||
}
|
||||
|
||||
#region Client Tools
|
||||
|
||||
/// <summary>
|
||||
/// Try to find an active IClientAPI reference for agentID giving preference to root connections
|
||||
/// </summary>
|
||||
private IClientAPI GetActiveClient(UUID agentID)
|
||||
{
|
||||
if (m_debugEnabled) m_log.WarnFormat("[Groups.Messaging]: Looking for local client {0}", agentID);
|
||||
|
||||
IClientAPI child = null;
|
||||
|
||||
// Try root avatar first
|
||||
foreach (Scene scene in m_sceneList)
|
||||
{
|
||||
ScenePresence sp = scene.GetScenePresence(agentID);
|
||||
if (sp != null)
|
||||
{
|
||||
if (!sp.IsChildAgent)
|
||||
{
|
||||
if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Found root agent for client : {0}", sp.ControllingClient.Name);
|
||||
return sp.ControllingClient;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Found child agent for client : {0}", sp.ControllingClient.Name);
|
||||
child = sp.ControllingClient;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we didn't find a root, then just return whichever child we found, or null if none
|
||||
if (child == null)
|
||||
{
|
||||
if (m_debugEnabled) m_log.WarnFormat("[Groups.Messaging]: Could not find local client for agent : {0}", agentID);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_debugEnabled) m_log.WarnFormat("[Groups.Messaging]: Returning child agent for client : {0}", child.Name);
|
||||
}
|
||||
return child;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region GroupSessionTracking
|
||||
|
||||
public void ResetAgentGroupChatSessions(string agentID)
|
||||
{
|
||||
foreach (List<string> agentList in m_groupsAgentsDroppedFromChatSession.Values)
|
||||
agentList.Remove(agentID);
|
||||
|
||||
foreach (List<string> agentList in m_groupsAgentsInvitedToChatSession.Values)
|
||||
agentList.Remove(agentID);
|
||||
}
|
||||
|
||||
public bool hasAgentBeenInvitedToGroupChatSession(string agentID, UUID groupID)
|
||||
{
|
||||
// If we're tracking this group, and we can find them in the tracking, then they've been invited
|
||||
return m_groupsAgentsInvitedToChatSession.ContainsKey(groupID)
|
||||
&& m_groupsAgentsInvitedToChatSession[groupID].Contains(agentID);
|
||||
}
|
||||
|
||||
public bool hasAgentDroppedGroupChatSession(string agentID, UUID groupID)
|
||||
{
|
||||
// If we're tracking drops for this group,
|
||||
// and we find them, well... then they've dropped
|
||||
return m_groupsAgentsDroppedFromChatSession.ContainsKey(groupID)
|
||||
&& m_groupsAgentsDroppedFromChatSession[groupID].Contains(agentID);
|
||||
}
|
||||
|
||||
public void AgentDroppedFromGroupChatSession(string agentID, UUID groupID)
|
||||
{
|
||||
if (m_groupsAgentsDroppedFromChatSession.ContainsKey(groupID))
|
||||
{
|
||||
// If not in dropped list, add
|
||||
if (!m_groupsAgentsDroppedFromChatSession[groupID].Contains(agentID))
|
||||
{
|
||||
m_groupsAgentsDroppedFromChatSession[groupID].Add(agentID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void AgentInvitedToGroupChatSession(string agentID, UUID groupID)
|
||||
{
|
||||
// Add Session Status if it doesn't exist for this session
|
||||
CreateGroupChatSessionTracking(groupID);
|
||||
|
||||
// If nessesary, remove from dropped list
|
||||
if (m_groupsAgentsDroppedFromChatSession[groupID].Contains(agentID))
|
||||
{
|
||||
m_groupsAgentsDroppedFromChatSession[groupID].Remove(agentID);
|
||||
}
|
||||
|
||||
// Add to invited
|
||||
if (!m_groupsAgentsInvitedToChatSession[groupID].Contains(agentID))
|
||||
m_groupsAgentsInvitedToChatSession[groupID].Add(agentID);
|
||||
}
|
||||
|
||||
private void CreateGroupChatSessionTracking(UUID groupID)
|
||||
{
|
||||
if (!m_groupsAgentsDroppedFromChatSession.ContainsKey(groupID))
|
||||
{
|
||||
m_groupsAgentsDroppedFromChatSession.Add(groupID, new List<string>());
|
||||
m_groupsAgentsInvitedToChatSession.Add(groupID, new List<string>());
|
||||
}
|
||||
|
||||
}
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,289 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Server.Base;
|
||||
|
||||
using OpenMetaverse;
|
||||
using log4net;
|
||||
|
||||
namespace OpenSim.Groups
|
||||
{
|
||||
public class GroupsServiceHGConnector
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private string m_ServerURI;
|
||||
private object m_Lock = new object();
|
||||
|
||||
public GroupsServiceHGConnector(string url)
|
||||
{
|
||||
m_ServerURI = url;
|
||||
if (!m_ServerURI.EndsWith("/"))
|
||||
m_ServerURI += "/";
|
||||
|
||||
m_log.DebugFormat("[Groups.HGConnector]: Groups server at {0}", m_ServerURI);
|
||||
}
|
||||
|
||||
public bool CreateProxy(string RequestingAgentID, string AgentID, string accessToken, UUID groupID, string url, string name, out string reason)
|
||||
{
|
||||
reason = string.Empty;
|
||||
|
||||
Dictionary<string, object> sendData = new Dictionary<string,object>();
|
||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
||||
sendData["AgentID"] = AgentID.ToString();
|
||||
sendData["AccessToken"] = accessToken;
|
||||
sendData["GroupID"] = groupID.ToString();
|
||||
sendData["Location"] = url;
|
||||
sendData["Name"] = name;
|
||||
Dictionary<string, object> ret = MakeRequest("POSTGROUP", sendData);
|
||||
|
||||
if (ret == null)
|
||||
return false;
|
||||
|
||||
if (!ret.ContainsKey("RESULT"))
|
||||
return false;
|
||||
|
||||
if (ret["RESULT"].ToString().ToLower() != "true")
|
||||
{
|
||||
reason = ret["REASON"].ToString();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
public void RemoveAgentFromGroup(string AgentID, UUID GroupID, string token)
|
||||
{
|
||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
||||
sendData["AgentID"] = AgentID;
|
||||
sendData["GroupID"] = GroupID.ToString();
|
||||
sendData["AccessToken"] = GroupsDataUtils.Sanitize(token);
|
||||
MakeRequest("REMOVEAGENTFROMGROUP", sendData);
|
||||
}
|
||||
|
||||
public ExtendedGroupRecord GetGroupRecord(string RequestingAgentID, UUID GroupID, string GroupName, string token)
|
||||
{
|
||||
if (GroupID == UUID.Zero && (GroupName == null || (GroupName != null && GroupName == string.Empty)))
|
||||
return null;
|
||||
|
||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
||||
if (GroupID != UUID.Zero)
|
||||
sendData["GroupID"] = GroupID.ToString();
|
||||
if (!string.IsNullOrEmpty(GroupName))
|
||||
sendData["Name"] = GroupsDataUtils.Sanitize(GroupName);
|
||||
|
||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
||||
sendData["AccessToken"] = GroupsDataUtils.Sanitize(token);
|
||||
|
||||
Dictionary<string, object> ret = MakeRequest("GETGROUP", sendData);
|
||||
|
||||
if (ret == null)
|
||||
return null;
|
||||
|
||||
if (!ret.ContainsKey("RESULT"))
|
||||
return null;
|
||||
|
||||
if (ret["RESULT"].ToString() == "NULL")
|
||||
return null;
|
||||
|
||||
return GroupsDataUtils.GroupRecord((Dictionary<string, object>)ret["RESULT"]);
|
||||
}
|
||||
|
||||
public List<ExtendedGroupMembersData> GetGroupMembers(string RequestingAgentID, UUID GroupID, string token)
|
||||
{
|
||||
List<ExtendedGroupMembersData> members = new List<ExtendedGroupMembersData>();
|
||||
|
||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
||||
sendData["GroupID"] = GroupID.ToString();
|
||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
||||
sendData["AccessToken"] = GroupsDataUtils.Sanitize(token);
|
||||
Dictionary<string, object> ret = MakeRequest("GETGROUPMEMBERS", sendData);
|
||||
|
||||
if (ret == null)
|
||||
return members;
|
||||
|
||||
if (!ret.ContainsKey("RESULT"))
|
||||
return members;
|
||||
|
||||
if (ret["RESULT"].ToString() == "NULL")
|
||||
return members;
|
||||
foreach (object v in ((Dictionary<string, object>)ret["RESULT"]).Values)
|
||||
{
|
||||
ExtendedGroupMembersData m = GroupsDataUtils.GroupMembersData((Dictionary<string, object>)v);
|
||||
members.Add(m);
|
||||
}
|
||||
|
||||
return members;
|
||||
}
|
||||
|
||||
public List<GroupRolesData> GetGroupRoles(string RequestingAgentID, UUID GroupID, string token)
|
||||
{
|
||||
List<GroupRolesData> roles = new List<GroupRolesData>();
|
||||
|
||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
||||
sendData["GroupID"] = GroupID.ToString();
|
||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
||||
sendData["AccessToken"] = GroupsDataUtils.Sanitize(token);
|
||||
Dictionary<string, object> ret = MakeRequest("GETGROUPROLES", sendData);
|
||||
|
||||
if (ret == null)
|
||||
return roles;
|
||||
|
||||
if (!ret.ContainsKey("RESULT"))
|
||||
return roles;
|
||||
|
||||
if (ret["RESULT"].ToString() == "NULL")
|
||||
return roles;
|
||||
foreach (object v in ((Dictionary<string, object>)ret["RESULT"]).Values)
|
||||
{
|
||||
GroupRolesData m = GroupsDataUtils.GroupRolesData((Dictionary<string, object>)v);
|
||||
roles.Add(m);
|
||||
}
|
||||
|
||||
return roles;
|
||||
}
|
||||
|
||||
public List<ExtendedGroupRoleMembersData> GetGroupRoleMembers(string RequestingAgentID, UUID GroupID, string token)
|
||||
{
|
||||
List<ExtendedGroupRoleMembersData> rmembers = new List<ExtendedGroupRoleMembersData>();
|
||||
|
||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
||||
sendData["GroupID"] = GroupID.ToString();
|
||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
||||
sendData["AccessToken"] = GroupsDataUtils.Sanitize(token);
|
||||
Dictionary<string, object> ret = MakeRequest("GETROLEMEMBERS", sendData);
|
||||
|
||||
if (ret == null)
|
||||
return rmembers;
|
||||
|
||||
if (!ret.ContainsKey("RESULT"))
|
||||
return rmembers;
|
||||
|
||||
if (ret["RESULT"].ToString() == "NULL")
|
||||
return rmembers;
|
||||
|
||||
foreach (object v in ((Dictionary<string, object>)ret["RESULT"]).Values)
|
||||
{
|
||||
ExtendedGroupRoleMembersData m = GroupsDataUtils.GroupRoleMembersData((Dictionary<string, object>)v);
|
||||
rmembers.Add(m);
|
||||
}
|
||||
|
||||
return rmembers;
|
||||
}
|
||||
|
||||
public bool AddNotice(string RequestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message,
|
||||
bool hasAttachment, byte attType, string attName, UUID attItemID, string attOwnerID)
|
||||
{
|
||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
||||
sendData["GroupID"] = groupID.ToString();
|
||||
sendData["NoticeID"] = noticeID.ToString();
|
||||
sendData["FromName"] = GroupsDataUtils.Sanitize(fromName);
|
||||
sendData["Subject"] = GroupsDataUtils.Sanitize(subject);
|
||||
sendData["Message"] = GroupsDataUtils.Sanitize(message);
|
||||
sendData["HasAttachment"] = hasAttachment.ToString();
|
||||
if (hasAttachment)
|
||||
{
|
||||
sendData["AttachmentType"] = attType.ToString();
|
||||
sendData["AttachmentName"] = attName.ToString();
|
||||
sendData["AttachmentItemID"] = attItemID.ToString();
|
||||
sendData["AttachmentOwnerID"] = attOwnerID;
|
||||
}
|
||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
||||
|
||||
Dictionary<string, object> ret = MakeRequest("ADDNOTICE", sendData);
|
||||
|
||||
if (ret == null)
|
||||
return false;
|
||||
|
||||
if (!ret.ContainsKey("RESULT"))
|
||||
return false;
|
||||
|
||||
if (ret["RESULT"].ToString().ToLower() != "true")
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool VerifyNotice(UUID noticeID, UUID groupID)
|
||||
{
|
||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
||||
sendData["NoticeID"] = noticeID.ToString();
|
||||
sendData["GroupID"] = groupID.ToString();
|
||||
Dictionary<string, object> ret = MakeRequest("VERIFYNOTICE", sendData);
|
||||
|
||||
if (ret == null)
|
||||
return false;
|
||||
|
||||
if (!ret.ContainsKey("RESULT"))
|
||||
return false;
|
||||
|
||||
if (ret["RESULT"].ToString().ToLower() != "true")
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
#region Make Request
|
||||
|
||||
private Dictionary<string, object> MakeRequest(string method, Dictionary<string, object> sendData)
|
||||
{
|
||||
sendData["METHOD"] = method;
|
||||
|
||||
string reply = string.Empty;
|
||||
lock (m_Lock)
|
||||
reply = SynchronousRestFormsRequester.MakeRequest("POST",
|
||||
m_ServerURI + "hg-groups",
|
||||
ServerUtils.BuildQueryString(sendData));
|
||||
|
||||
//m_log.DebugFormat("[XXX]: reply was {0}", reply);
|
||||
|
||||
if (string.IsNullOrEmpty(reply))
|
||||
return null;
|
||||
|
||||
Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(
|
||||
reply);
|
||||
|
||||
return replyData;
|
||||
}
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,706 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Servers;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Services.Interfaces;
|
||||
|
||||
using OpenMetaverse;
|
||||
using Mono.Addins;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
|
||||
namespace OpenSim.Groups
|
||||
{
|
||||
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GroupsServiceHGConnectorModule")]
|
||||
public class GroupsServiceHGConnectorModule : ISharedRegionModule, IGroupsServicesConnector
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private bool m_Enabled = false;
|
||||
private IGroupsServicesConnector m_LocalGroupsConnector;
|
||||
private string m_LocalGroupsServiceLocation;
|
||||
private IUserManagement m_UserManagement;
|
||||
private IOfflineIMService m_OfflineIM;
|
||||
private IMessageTransferModule m_Messaging;
|
||||
private List<Scene> m_Scenes;
|
||||
private ForeignImporter m_ForeignImporter;
|
||||
private string m_ServiceLocation;
|
||||
private IConfigSource m_Config;
|
||||
|
||||
private Dictionary<string, GroupsServiceHGConnector> m_NetworkConnectors = new Dictionary<string, GroupsServiceHGConnector>();
|
||||
private RemoteConnectorCacheWrapper m_CacheWrapper; // for caching info of external group services
|
||||
|
||||
#region ISharedRegionModule
|
||||
|
||||
public void Initialise(IConfigSource config)
|
||||
{
|
||||
IConfig groupsConfig = config.Configs["Groups"];
|
||||
if (groupsConfig == null)
|
||||
return;
|
||||
|
||||
if ((groupsConfig.GetBoolean("Enabled", false) == false)
|
||||
|| (groupsConfig.GetString("ServicesConnectorModule", string.Empty) != Name))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_Config = config;
|
||||
m_ServiceLocation = groupsConfig.GetString("LocalService", "local"); // local or remote
|
||||
m_LocalGroupsServiceLocation = groupsConfig.GetString("GroupsExternalURI", "http://127.0.0.1");
|
||||
m_Scenes = new List<Scene>();
|
||||
|
||||
m_Enabled = true;
|
||||
|
||||
m_log.DebugFormat("[Groups]: Initializing {0} with LocalService {1}", this.Name, m_ServiceLocation);
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return "Groups HG Service Connector"; }
|
||||
}
|
||||
|
||||
public Type ReplaceableInterface
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
public void AddRegion(Scene scene)
|
||||
{
|
||||
if (!m_Enabled)
|
||||
return;
|
||||
|
||||
m_log.DebugFormat("[Groups]: Registering {0} with {1}", this.Name, scene.RegionInfo.RegionName);
|
||||
scene.RegisterModuleInterface<IGroupsServicesConnector>(this);
|
||||
m_Scenes.Add(scene);
|
||||
|
||||
scene.EventManager.OnNewClient += OnNewClient;
|
||||
}
|
||||
|
||||
public void RemoveRegion(Scene scene)
|
||||
{
|
||||
if (!m_Enabled)
|
||||
return;
|
||||
|
||||
scene.UnregisterModuleInterface<IGroupsServicesConnector>(this);
|
||||
m_Scenes.Remove(scene);
|
||||
}
|
||||
|
||||
public void RegionLoaded(Scene scene)
|
||||
{
|
||||
if (!m_Enabled)
|
||||
return;
|
||||
|
||||
if (m_UserManagement == null)
|
||||
{
|
||||
m_UserManagement = scene.RequestModuleInterface<IUserManagement>();
|
||||
m_OfflineIM = scene.RequestModuleInterface<IOfflineIMService>();
|
||||
m_Messaging = scene.RequestModuleInterface<IMessageTransferModule>();
|
||||
m_ForeignImporter = new ForeignImporter(m_UserManagement);
|
||||
|
||||
if (m_ServiceLocation.Equals("local"))
|
||||
{
|
||||
m_LocalGroupsConnector = new GroupsServiceLocalConnectorModule(m_Config, m_UserManagement);
|
||||
// Also, if local, create the endpoint for the HGGroupsService
|
||||
new HGGroupsServiceRobustConnector(m_Config, MainServer.Instance, string.Empty,
|
||||
scene.RequestModuleInterface<IOfflineIMService>(), scene.RequestModuleInterface<IUserAccountService>());
|
||||
|
||||
}
|
||||
else
|
||||
m_LocalGroupsConnector = new GroupsServiceRemoteConnectorModule(m_Config, m_UserManagement);
|
||||
|
||||
m_CacheWrapper = new RemoteConnectorCacheWrapper(m_UserManagement);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void OnNewClient(IClientAPI client)
|
||||
{
|
||||
client.OnCompleteMovementToRegion += OnCompleteMovementToRegion;
|
||||
}
|
||||
|
||||
void OnCompleteMovementToRegion(IClientAPI client, bool arg2)
|
||||
{
|
||||
object sp = null;
|
||||
if (client.Scene.TryGetScenePresence(client.AgentId, out sp))
|
||||
{
|
||||
if (sp is ScenePresence && ((ScenePresence)sp).PresenceType != PresenceType.Npc)
|
||||
{
|
||||
AgentCircuitData aCircuit = ((ScenePresence)sp).Scene.AuthenticateHandler.GetAgentCircuitData(client.AgentId);
|
||||
if (aCircuit != null && (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0 &&
|
||||
m_OfflineIM != null && m_Messaging != null)
|
||||
{
|
||||
List<GridInstantMessage> ims = m_OfflineIM.GetMessages(aCircuit.AgentID);
|
||||
if (ims != null && ims.Count > 0)
|
||||
foreach (GridInstantMessage im in ims)
|
||||
m_Messaging.SendInstantMessage(im, delegate(bool success) { });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region IGroupsServicesConnector
|
||||
|
||||
public UUID CreateGroup(UUID RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment,
|
||||
bool allowPublish, bool maturePublish, UUID founderID, out string reason)
|
||||
{
|
||||
reason = string.Empty;
|
||||
if (m_UserManagement.IsLocalGridUser(RequestingAgentID))
|
||||
return m_LocalGroupsConnector.CreateGroup(RequestingAgentID, name, charter, showInList, insigniaID,
|
||||
membershipFee, openEnrollment, allowPublish, maturePublish, founderID, out reason);
|
||||
else
|
||||
{
|
||||
reason = "Only local grid users are allowed to create a new group";
|
||||
return UUID.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
public bool UpdateGroup(string RequestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee,
|
||||
bool openEnrollment, bool allowPublish, bool maturePublish, out string reason)
|
||||
{
|
||||
reason = string.Empty;
|
||||
string url = string.Empty;
|
||||
string name = string.Empty;
|
||||
if (IsLocal(groupID, out url, out name))
|
||||
return m_LocalGroupsConnector.UpdateGroup(AgentUUI(RequestingAgentID), groupID, charter, showInList, insigniaID, membershipFee,
|
||||
openEnrollment, allowPublish, maturePublish, out reason);
|
||||
else
|
||||
{
|
||||
reason = "Changes to remote group not allowed. Please go to the group's original world.";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public ExtendedGroupRecord GetGroupRecord(string RequestingAgentID, UUID GroupID, string GroupName)
|
||||
{
|
||||
string url = string.Empty;
|
||||
string name = string.Empty;
|
||||
if (IsLocal(GroupID, out url, out name))
|
||||
return m_LocalGroupsConnector.GetGroupRecord(AgentUUI(RequestingAgentID), GroupID, GroupName);
|
||||
else if (url != string.Empty)
|
||||
{
|
||||
ExtendedGroupMembershipData membership = m_LocalGroupsConnector.GetAgentGroupMembership(RequestingAgentID, RequestingAgentID, GroupID);
|
||||
string accessToken = string.Empty;
|
||||
if (membership != null)
|
||||
accessToken = membership.AccessToken;
|
||||
else
|
||||
return null;
|
||||
|
||||
GroupsServiceHGConnector c = GetConnector(url);
|
||||
if (c != null)
|
||||
{
|
||||
ExtendedGroupRecord grec = m_CacheWrapper.GetGroupRecord(RequestingAgentID, GroupID, GroupName, delegate
|
||||
{
|
||||
return c.GetGroupRecord(AgentUUIForOutside(RequestingAgentID), GroupID, GroupName, accessToken);
|
||||
});
|
||||
|
||||
if (grec != null)
|
||||
ImportForeigner(grec.FounderUUI);
|
||||
return grec;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<DirGroupsReplyData> FindGroups(string RequestingAgentID, string search)
|
||||
{
|
||||
return m_LocalGroupsConnector.FindGroups(AgentUUI(RequestingAgentID), search);
|
||||
}
|
||||
|
||||
public List<GroupMembersData> GetGroupMembers(string RequestingAgentID, UUID GroupID)
|
||||
{
|
||||
string url = string.Empty, gname = string.Empty;
|
||||
if (IsLocal(GroupID, out url, out gname))
|
||||
{
|
||||
string agentID = AgentUUI(RequestingAgentID);
|
||||
return m_LocalGroupsConnector.GetGroupMembers(agentID, GroupID);
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(url))
|
||||
{
|
||||
ExtendedGroupMembershipData membership = m_LocalGroupsConnector.GetAgentGroupMembership(RequestingAgentID, RequestingAgentID, GroupID);
|
||||
string accessToken = string.Empty;
|
||||
if (membership != null)
|
||||
accessToken = membership.AccessToken;
|
||||
else
|
||||
return null;
|
||||
|
||||
GroupsServiceHGConnector c = GetConnector(url);
|
||||
if (c != null)
|
||||
{
|
||||
return m_CacheWrapper.GetGroupMembers(RequestingAgentID, GroupID, delegate
|
||||
{
|
||||
return c.GetGroupMembers(AgentUUIForOutside(RequestingAgentID), GroupID, accessToken);
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
return new List<GroupMembersData>();
|
||||
}
|
||||
|
||||
public bool AddGroupRole(string RequestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers, out string reason)
|
||||
{
|
||||
reason = string.Empty;
|
||||
string url = string.Empty, gname = string.Empty;
|
||||
|
||||
if (IsLocal(groupID, out url, out gname))
|
||||
return m_LocalGroupsConnector.AddGroupRole(AgentUUI(RequestingAgentID), groupID, roleID, name, description, title, powers, out reason);
|
||||
else
|
||||
{
|
||||
reason = "Operation not allowed outside this group's origin world.";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool UpdateGroupRole(string RequestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers)
|
||||
{
|
||||
string url = string.Empty, gname = string.Empty;
|
||||
|
||||
if (IsLocal(groupID, out url, out gname))
|
||||
return m_LocalGroupsConnector.UpdateGroupRole(AgentUUI(RequestingAgentID), groupID, roleID, name, description, title, powers);
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void RemoveGroupRole(string RequestingAgentID, UUID groupID, UUID roleID)
|
||||
{
|
||||
string url = string.Empty, gname = string.Empty;
|
||||
|
||||
if (IsLocal(groupID, out url, out gname))
|
||||
m_LocalGroupsConnector.RemoveGroupRole(AgentUUI(RequestingAgentID), groupID, roleID);
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public List<GroupRolesData> GetGroupRoles(string RequestingAgentID, UUID groupID)
|
||||
{
|
||||
string url = string.Empty, gname = string.Empty;
|
||||
|
||||
if (IsLocal(groupID, out url, out gname))
|
||||
return m_LocalGroupsConnector.GetGroupRoles(AgentUUI(RequestingAgentID), groupID);
|
||||
else if (!string.IsNullOrEmpty(url))
|
||||
{
|
||||
ExtendedGroupMembershipData membership = m_LocalGroupsConnector.GetAgentGroupMembership(RequestingAgentID, RequestingAgentID, groupID);
|
||||
string accessToken = string.Empty;
|
||||
if (membership != null)
|
||||
accessToken = membership.AccessToken;
|
||||
else
|
||||
return null;
|
||||
|
||||
GroupsServiceHGConnector c = GetConnector(url);
|
||||
if (c != null)
|
||||
{
|
||||
return m_CacheWrapper.GetGroupRoles(RequestingAgentID, groupID, delegate
|
||||
{
|
||||
return c.GetGroupRoles(AgentUUIForOutside(RequestingAgentID), groupID, accessToken);
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return new List<GroupRolesData>();
|
||||
}
|
||||
|
||||
public List<GroupRoleMembersData> GetGroupRoleMembers(string RequestingAgentID, UUID groupID)
|
||||
{
|
||||
string url = string.Empty, gname = string.Empty;
|
||||
|
||||
if (IsLocal(groupID, out url, out gname))
|
||||
return m_LocalGroupsConnector.GetGroupRoleMembers(AgentUUI(RequestingAgentID), groupID);
|
||||
else if (!string.IsNullOrEmpty(url))
|
||||
{
|
||||
ExtendedGroupMembershipData membership = m_LocalGroupsConnector.GetAgentGroupMembership(RequestingAgentID, RequestingAgentID, groupID);
|
||||
string accessToken = string.Empty;
|
||||
if (membership != null)
|
||||
accessToken = membership.AccessToken;
|
||||
else
|
||||
return null;
|
||||
|
||||
GroupsServiceHGConnector c = GetConnector(url);
|
||||
if (c != null)
|
||||
{
|
||||
return m_CacheWrapper.GetGroupRoleMembers(RequestingAgentID, groupID, delegate
|
||||
{
|
||||
return c.GetGroupRoleMembers(AgentUUIForOutside(RequestingAgentID), groupID, accessToken);
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return new List<GroupRoleMembersData>();
|
||||
}
|
||||
|
||||
public bool AddAgentToGroup(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID, string token, out string reason)
|
||||
{
|
||||
string url = string.Empty;
|
||||
string name = string.Empty;
|
||||
reason = string.Empty;
|
||||
|
||||
UUID uid = new UUID(AgentID);
|
||||
if (IsLocal(GroupID, out url, out name))
|
||||
{
|
||||
if (m_UserManagement.IsLocalGridUser(uid)) // local user
|
||||
{
|
||||
// normal case: local group, local user
|
||||
return m_LocalGroupsConnector.AddAgentToGroup(AgentUUI(RequestingAgentID), AgentUUI(AgentID), GroupID, RoleID, token, out reason);
|
||||
}
|
||||
else // local group, foreign user
|
||||
{
|
||||
// the user is accepting the invitation, or joining, where the group resides
|
||||
token = UUID.Random().ToString();
|
||||
bool success = m_LocalGroupsConnector.AddAgentToGroup(AgentUUI(RequestingAgentID), AgentUUI(AgentID), GroupID, RoleID, token, out reason);
|
||||
|
||||
if (success)
|
||||
{
|
||||
// Here we always return true. The user has been added to the local group,
|
||||
// independent of whether the remote operation succeeds or not
|
||||
url = m_UserManagement.GetUserServerURL(uid, "GroupsServerURI");
|
||||
if (url == string.Empty)
|
||||
{
|
||||
reason = "You don't have an accessible groups server in your home world. You membership to this group in only within this grid.";
|
||||
return true;
|
||||
}
|
||||
|
||||
GroupsServiceHGConnector c = GetConnector(url);
|
||||
if (c != null)
|
||||
c.CreateProxy(AgentUUI(RequestingAgentID), AgentID, token, GroupID, m_LocalGroupsServiceLocation, name, out reason);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (m_UserManagement.IsLocalGridUser(uid)) // local user
|
||||
{
|
||||
// foreign group, local user. She's been added already by the HG service.
|
||||
// Let's just check
|
||||
if (m_LocalGroupsConnector.GetAgentGroupMembership(AgentUUI(RequestingAgentID), AgentUUI(AgentID), GroupID) != null)
|
||||
return true;
|
||||
}
|
||||
|
||||
reason = "Operation not allowed outside this group's origin world";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public void RemoveAgentFromGroup(string RequestingAgentID, string AgentID, UUID GroupID)
|
||||
{
|
||||
string url = string.Empty, name = string.Empty;
|
||||
if (!IsLocal(GroupID, out url, out name) && url != string.Empty)
|
||||
{
|
||||
ExtendedGroupMembershipData membership = m_LocalGroupsConnector.GetAgentGroupMembership(AgentUUI(RequestingAgentID), AgentUUI(AgentID), GroupID);
|
||||
if (membership != null)
|
||||
{
|
||||
GroupsServiceHGConnector c = GetConnector(url);
|
||||
if (c != null)
|
||||
c.RemoveAgentFromGroup(AgentUUIForOutside(AgentID), GroupID, membership.AccessToken);
|
||||
}
|
||||
}
|
||||
|
||||
// remove from local service
|
||||
m_LocalGroupsConnector.RemoveAgentFromGroup(AgentUUI(RequestingAgentID), AgentUUI(AgentID), GroupID);
|
||||
}
|
||||
|
||||
public bool AddAgentToGroupInvite(string RequestingAgentID, UUID inviteID, UUID groupID, UUID roleID, string agentID)
|
||||
{
|
||||
string url = string.Empty, gname = string.Empty;
|
||||
|
||||
if (IsLocal(groupID, out url, out gname))
|
||||
return m_LocalGroupsConnector.AddAgentToGroupInvite(AgentUUI(RequestingAgentID), inviteID, groupID, roleID, AgentUUI(agentID));
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
public GroupInviteInfo GetAgentToGroupInvite(string RequestingAgentID, UUID inviteID)
|
||||
{
|
||||
return m_LocalGroupsConnector.GetAgentToGroupInvite(AgentUUI(RequestingAgentID), inviteID); ;
|
||||
}
|
||||
|
||||
public void RemoveAgentToGroupInvite(string RequestingAgentID, UUID inviteID)
|
||||
{
|
||||
m_LocalGroupsConnector.RemoveAgentToGroupInvite(AgentUUI(RequestingAgentID), inviteID);
|
||||
}
|
||||
|
||||
public void AddAgentToGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID)
|
||||
{
|
||||
string url = string.Empty, gname = string.Empty;
|
||||
|
||||
if (IsLocal(GroupID, out url, out gname))
|
||||
m_LocalGroupsConnector.AddAgentToGroupRole(AgentUUI(RequestingAgentID), AgentUUI(AgentID), GroupID, RoleID);
|
||||
|
||||
}
|
||||
|
||||
public void RemoveAgentFromGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID)
|
||||
{
|
||||
string url = string.Empty, gname = string.Empty;
|
||||
|
||||
if (IsLocal(GroupID, out url, out gname))
|
||||
m_LocalGroupsConnector.RemoveAgentFromGroupRole(AgentUUI(RequestingAgentID), AgentUUI(AgentID), GroupID, RoleID);
|
||||
}
|
||||
|
||||
public List<GroupRolesData> GetAgentGroupRoles(string RequestingAgentID, string AgentID, UUID GroupID)
|
||||
{
|
||||
string url = string.Empty, gname = string.Empty;
|
||||
|
||||
if (IsLocal(GroupID, out url, out gname))
|
||||
return m_LocalGroupsConnector.GetAgentGroupRoles(AgentUUI(RequestingAgentID), AgentUUI(AgentID), GroupID);
|
||||
else
|
||||
return new List<GroupRolesData>();
|
||||
}
|
||||
|
||||
public void SetAgentActiveGroup(string RequestingAgentID, string AgentID, UUID GroupID)
|
||||
{
|
||||
string url = string.Empty, gname = string.Empty;
|
||||
|
||||
if (IsLocal(GroupID, out url, out gname))
|
||||
m_LocalGroupsConnector.SetAgentActiveGroup(AgentUUI(RequestingAgentID), AgentUUI(AgentID), GroupID);
|
||||
}
|
||||
|
||||
public ExtendedGroupMembershipData GetAgentActiveMembership(string RequestingAgentID, string AgentID)
|
||||
{
|
||||
return m_LocalGroupsConnector.GetAgentActiveMembership(AgentUUI(RequestingAgentID), AgentUUI(AgentID));
|
||||
}
|
||||
|
||||
public void SetAgentActiveGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID)
|
||||
{
|
||||
string url = string.Empty, gname = string.Empty;
|
||||
|
||||
if (IsLocal(GroupID, out url, out gname))
|
||||
m_LocalGroupsConnector.SetAgentActiveGroupRole(AgentUUI(RequestingAgentID), AgentUUI(AgentID), GroupID, RoleID);
|
||||
}
|
||||
|
||||
public void UpdateMembership(string RequestingAgentID, string AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile)
|
||||
{
|
||||
m_LocalGroupsConnector.UpdateMembership(AgentUUI(RequestingAgentID), AgentUUI(AgentID), GroupID, AcceptNotices, ListInProfile);
|
||||
}
|
||||
|
||||
public ExtendedGroupMembershipData GetAgentGroupMembership(string RequestingAgentID, string AgentID, UUID GroupID)
|
||||
{
|
||||
string url = string.Empty, gname = string.Empty;
|
||||
|
||||
if (IsLocal(GroupID, out url, out gname))
|
||||
return m_LocalGroupsConnector.GetAgentGroupMembership(AgentUUI(RequestingAgentID), AgentUUI(AgentID), GroupID);
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<GroupMembershipData> GetAgentGroupMemberships(string RequestingAgentID, string AgentID)
|
||||
{
|
||||
return m_LocalGroupsConnector.GetAgentGroupMemberships(AgentUUI(RequestingAgentID), AgentUUI(AgentID));
|
||||
}
|
||||
|
||||
public bool AddGroupNotice(string RequestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message,
|
||||
bool hasAttachment, byte attType, string attName, UUID attItemID, string attOwnerID)
|
||||
{
|
||||
string url = string.Empty, gname = string.Empty;
|
||||
|
||||
if (IsLocal(groupID, out url, out gname))
|
||||
{
|
||||
if (m_LocalGroupsConnector.AddGroupNotice(AgentUUI(RequestingAgentID), groupID, noticeID, fromName, subject, message,
|
||||
hasAttachment, attType, attName, attItemID, AgentUUI(attOwnerID)))
|
||||
{
|
||||
// then send the notice to every grid for which there are members in this group
|
||||
List<GroupMembersData> members = m_LocalGroupsConnector.GetGroupMembers(AgentUUI(RequestingAgentID), groupID);
|
||||
List<string> urls = new List<string>();
|
||||
foreach (GroupMembersData m in members)
|
||||
{
|
||||
if (!m_UserManagement.IsLocalGridUser(m.AgentID))
|
||||
{
|
||||
string gURL = m_UserManagement.GetUserServerURL(m.AgentID, "GroupsServerURI");
|
||||
if (!urls.Contains(gURL))
|
||||
urls.Add(gURL);
|
||||
}
|
||||
}
|
||||
|
||||
// so we have the list of urls to send the notice to
|
||||
// this may take a long time...
|
||||
Util.FireAndForget(delegate
|
||||
{
|
||||
foreach (string u in urls)
|
||||
{
|
||||
GroupsServiceHGConnector c = GetConnector(u);
|
||||
if (c != null)
|
||||
{
|
||||
c.AddNotice(AgentUUIForOutside(RequestingAgentID), groupID, noticeID, fromName, subject, message,
|
||||
hasAttachment, attType, attName, attItemID, AgentUUIForOutside(attOwnerID));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
public GroupNoticeInfo GetGroupNotice(string RequestingAgentID, UUID noticeID)
|
||||
{
|
||||
GroupNoticeInfo notice = m_LocalGroupsConnector.GetGroupNotice(AgentUUI(RequestingAgentID), noticeID);
|
||||
|
||||
if (notice != null && notice.noticeData.HasAttachment && notice.noticeData.AttachmentOwnerID != null)
|
||||
ImportForeigner(notice.noticeData.AttachmentOwnerID);
|
||||
|
||||
return notice;
|
||||
}
|
||||
|
||||
public List<ExtendedGroupNoticeData> GetGroupNotices(string RequestingAgentID, UUID GroupID)
|
||||
{
|
||||
return m_LocalGroupsConnector.GetGroupNotices(AgentUUI(RequestingAgentID), GroupID);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region hypergrid groups
|
||||
|
||||
private string AgentUUI(string AgentIDStr)
|
||||
{
|
||||
UUID AgentID = UUID.Zero;
|
||||
try
|
||||
{
|
||||
AgentID = new UUID(AgentIDStr);
|
||||
}
|
||||
catch (FormatException)
|
||||
{
|
||||
return AgentID.ToString();
|
||||
}
|
||||
|
||||
if (m_UserManagement.IsLocalGridUser(AgentID))
|
||||
return AgentID.ToString();
|
||||
|
||||
AgentCircuitData agent = null;
|
||||
foreach (Scene scene in m_Scenes)
|
||||
{
|
||||
agent = scene.AuthenticateHandler.GetAgentCircuitData(AgentID);
|
||||
if (agent != null)
|
||||
break;
|
||||
}
|
||||
if (agent != null)
|
||||
return Util.ProduceUserUniversalIdentifier(agent);
|
||||
|
||||
// we don't know anything about this foreign user
|
||||
// try asking the user management module, which may know more
|
||||
return m_UserManagement.GetUserUUI(AgentID);
|
||||
|
||||
}
|
||||
|
||||
private string AgentUUIForOutside(string AgentIDStr)
|
||||
{
|
||||
UUID AgentID = UUID.Zero;
|
||||
try
|
||||
{
|
||||
AgentID = new UUID(AgentIDStr);
|
||||
}
|
||||
catch (FormatException)
|
||||
{
|
||||
return AgentID.ToString();
|
||||
}
|
||||
|
||||
AgentCircuitData agent = null;
|
||||
foreach (Scene scene in m_Scenes)
|
||||
{
|
||||
agent = scene.AuthenticateHandler.GetAgentCircuitData(AgentID);
|
||||
if (agent != null)
|
||||
break;
|
||||
}
|
||||
if (agent == null) // oops
|
||||
return AgentID.ToString();
|
||||
|
||||
return Util.ProduceUserUniversalIdentifier(agent);
|
||||
}
|
||||
|
||||
private UUID ImportForeigner(string uID)
|
||||
{
|
||||
UUID userID = UUID.Zero;
|
||||
string url = string.Empty, first = string.Empty, last = string.Empty, tmp = string.Empty;
|
||||
if (Util.ParseUniversalUserIdentifier(uID, out userID, out url, out first, out last, out tmp))
|
||||
m_UserManagement.AddUser(userID, first, last, url);
|
||||
|
||||
return userID;
|
||||
}
|
||||
|
||||
private bool IsLocal(UUID groupID, out string serviceLocation, out string name)
|
||||
{
|
||||
serviceLocation = string.Empty;
|
||||
name = string.Empty;
|
||||
if (groupID.Equals(UUID.Zero))
|
||||
return true;
|
||||
|
||||
ExtendedGroupRecord group = m_LocalGroupsConnector.GetGroupRecord(UUID.Zero.ToString(), groupID, string.Empty);
|
||||
if (group == null)
|
||||
{
|
||||
//m_log.DebugFormat("[XXX]: IsLocal? group {0} not found -- no.", groupID);
|
||||
return false;
|
||||
}
|
||||
|
||||
serviceLocation = group.ServiceLocation;
|
||||
name = group.GroupName;
|
||||
bool isLocal = (group.ServiceLocation == string.Empty);
|
||||
//m_log.DebugFormat("[XXX]: IsLocal? {0}", isLocal);
|
||||
return isLocal;
|
||||
}
|
||||
|
||||
private GroupsServiceHGConnector GetConnector(string url)
|
||||
{
|
||||
lock (m_NetworkConnectors)
|
||||
{
|
||||
if (m_NetworkConnectors.ContainsKey(url))
|
||||
return m_NetworkConnectors[url];
|
||||
|
||||
GroupsServiceHGConnector c = new GroupsServiceHGConnector(url);
|
||||
m_NetworkConnectors[url] = c;
|
||||
}
|
||||
|
||||
return m_NetworkConnectors[url];
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,442 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Nini.Config;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Server.Base;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using OpenSim.Framework.Servers.HttpServer;
|
||||
using OpenSim.Server.Handlers.Base;
|
||||
using log4net;
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace OpenSim.Groups
|
||||
{
|
||||
public class HGGroupsServiceRobustConnector : ServiceConnector
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private HGGroupsService m_GroupsService;
|
||||
private string m_ConfigName = "Groups";
|
||||
|
||||
// Called by Robust shell
|
||||
public HGGroupsServiceRobustConnector(IConfigSource config, IHttpServer server, string configName) :
|
||||
this(config, server, configName, null, null)
|
||||
{
|
||||
}
|
||||
|
||||
// Called by the sim-bound module
|
||||
public HGGroupsServiceRobustConnector(IConfigSource config, IHttpServer server, string configName, IOfflineIMService im, IUserAccountService users) :
|
||||
base(config, server, configName)
|
||||
{
|
||||
if (configName != String.Empty)
|
||||
m_ConfigName = configName;
|
||||
|
||||
m_log.DebugFormat("[Groups.RobustHGConnector]: Starting with config name {0}", m_ConfigName);
|
||||
|
||||
string homeURI = Util.GetConfigVarFromSections<string>(config, "HomeURI",
|
||||
new string[] { "Startup", "Hypergrid", m_ConfigName}, string.Empty);
|
||||
if (homeURI == string.Empty)
|
||||
throw new Exception(String.Format("[Groups.RobustHGConnector]: please provide the HomeURI [Startup] or in section {0}", m_ConfigName));
|
||||
|
||||
IConfig cnf = config.Configs[m_ConfigName];
|
||||
if (cnf == null)
|
||||
throw new Exception(String.Format("[Groups.RobustHGConnector]: {0} section does not exist", m_ConfigName));
|
||||
|
||||
if (im == null)
|
||||
{
|
||||
string imDll = cnf.GetString("OfflineIMService", string.Empty);
|
||||
if (imDll == string.Empty)
|
||||
throw new Exception(String.Format("[Groups.RobustHGConnector]: please provide OfflineIMService in section {0}", m_ConfigName));
|
||||
|
||||
Object[] args = new Object[] { config };
|
||||
im = ServerUtils.LoadPlugin<IOfflineIMService>(imDll, args);
|
||||
}
|
||||
|
||||
if (users == null)
|
||||
{
|
||||
string usersDll = cnf.GetString("UserAccountService", string.Empty);
|
||||
if (usersDll == string.Empty)
|
||||
throw new Exception(String.Format("[Groups.RobustHGConnector]: please provide UserAccountService in section {0}", m_ConfigName));
|
||||
|
||||
Object[] args = new Object[] { config };
|
||||
users = ServerUtils.LoadPlugin<IUserAccountService>(usersDll, args);
|
||||
}
|
||||
|
||||
m_GroupsService = new HGGroupsService(config, im, users, homeURI);
|
||||
|
||||
server.AddStreamHandler(new HGGroupsServicePostHandler(m_GroupsService));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class HGGroupsServicePostHandler : BaseStreamHandler
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private HGGroupsService m_GroupsService;
|
||||
|
||||
public HGGroupsServicePostHandler(HGGroupsService service) :
|
||||
base("POST", "/hg-groups")
|
||||
{
|
||||
m_GroupsService = service;
|
||||
}
|
||||
|
||||
protected override byte[] ProcessRequest(string path, Stream requestData,
|
||||
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
||||
{
|
||||
StreamReader sr = new StreamReader(requestData);
|
||||
string body = sr.ReadToEnd();
|
||||
sr.Close();
|
||||
body = body.Trim();
|
||||
|
||||
//m_log.DebugFormat("[XXX]: query String: {0}", body);
|
||||
|
||||
try
|
||||
{
|
||||
Dictionary<string, object> request =
|
||||
ServerUtils.ParseQueryString(body);
|
||||
|
||||
if (!request.ContainsKey("METHOD"))
|
||||
return FailureResult();
|
||||
|
||||
string method = request["METHOD"].ToString();
|
||||
request.Remove("METHOD");
|
||||
|
||||
m_log.DebugFormat("[Groups.RobustHGConnector]: {0}", method);
|
||||
switch (method)
|
||||
{
|
||||
case "POSTGROUP":
|
||||
return HandleAddGroupProxy(request);
|
||||
case "REMOVEAGENTFROMGROUP":
|
||||
return HandleRemoveAgentFromGroup(request);
|
||||
case "GETGROUP":
|
||||
return HandleGetGroup(request);
|
||||
case "ADDNOTICE":
|
||||
return HandleAddNotice(request);
|
||||
case "VERIFYNOTICE":
|
||||
return HandleVerifyNotice(request);
|
||||
case "GETGROUPMEMBERS":
|
||||
return HandleGetGroupMembers(request);
|
||||
case "GETGROUPROLES":
|
||||
return HandleGetGroupRoles(request);
|
||||
case "GETROLEMEMBERS":
|
||||
return HandleGetRoleMembers(request);
|
||||
|
||||
}
|
||||
m_log.DebugFormat("[Groups.RobustHGConnector]: unknown method request: {0}", method);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[Groups.RobustHGConnector]: Exception {0}", e.StackTrace);
|
||||
}
|
||||
|
||||
return FailureResult();
|
||||
}
|
||||
|
||||
byte[] HandleAddGroupProxy(Dictionary<string, object> request)
|
||||
{
|
||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
||||
|
||||
if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("GroupID")
|
||||
|| !request.ContainsKey("AgentID")
|
||||
|| !request.ContainsKey("AccessToken") || !request.ContainsKey("Location"))
|
||||
NullResult(result, "Bad network data");
|
||||
|
||||
else
|
||||
{
|
||||
string RequestingAgentID = request["RequestingAgentID"].ToString();
|
||||
string agentID = request["AgentID"].ToString();
|
||||
UUID groupID = new UUID(request["GroupID"].ToString());
|
||||
string accessToken = request["AccessToken"].ToString();
|
||||
string location = request["Location"].ToString();
|
||||
string name = string.Empty;
|
||||
if (request.ContainsKey("Name"))
|
||||
name = request["Name"].ToString();
|
||||
|
||||
string reason = string.Empty;
|
||||
bool success = m_GroupsService.CreateGroupProxy(RequestingAgentID, agentID, accessToken, groupID, location, name, out reason);
|
||||
result["REASON"] = reason;
|
||||
result["RESULT"] = success.ToString();
|
||||
}
|
||||
|
||||
string xmlString = ServerUtils.BuildXmlResponse(result);
|
||||
|
||||
//m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
|
||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
||||
}
|
||||
|
||||
byte[] HandleRemoveAgentFromGroup(Dictionary<string, object> request)
|
||||
{
|
||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
||||
|
||||
if (!request.ContainsKey("AccessToken") || !request.ContainsKey("AgentID") ||
|
||||
!request.ContainsKey("GroupID"))
|
||||
NullResult(result, "Bad network data");
|
||||
else
|
||||
{
|
||||
UUID groupID = new UUID(request["GroupID"].ToString());
|
||||
string agentID = request["AgentID"].ToString();
|
||||
string token = request["AccessToken"].ToString();
|
||||
|
||||
m_GroupsService.RemoveAgentFromGroup(agentID, agentID, groupID, token);
|
||||
}
|
||||
|
||||
//m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
|
||||
result["RESULT"] = "true";
|
||||
return Util.UTF8NoBomEncoding.GetBytes(ServerUtils.BuildXmlResponse(result));
|
||||
}
|
||||
|
||||
byte[] HandleGetGroup(Dictionary<string, object> request)
|
||||
{
|
||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
||||
|
||||
if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("AccessToken"))
|
||||
NullResult(result, "Bad network data");
|
||||
else
|
||||
{
|
||||
string RequestingAgentID = request["RequestingAgentID"].ToString();
|
||||
string token = request["AccessToken"].ToString();
|
||||
|
||||
UUID groupID = UUID.Zero;
|
||||
string groupName = string.Empty;
|
||||
|
||||
if (request.ContainsKey("GroupID"))
|
||||
groupID = new UUID(request["GroupID"].ToString());
|
||||
if (request.ContainsKey("Name"))
|
||||
groupName = request["Name"].ToString();
|
||||
|
||||
ExtendedGroupRecord grec = m_GroupsService.GetGroupRecord(RequestingAgentID, groupID, groupName, token);
|
||||
if (grec == null)
|
||||
NullResult(result, "Group not found");
|
||||
else
|
||||
result["RESULT"] = GroupsDataUtils.GroupRecord(grec);
|
||||
}
|
||||
|
||||
string xmlString = ServerUtils.BuildXmlResponse(result);
|
||||
|
||||
//m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
|
||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
||||
}
|
||||
|
||||
byte[] HandleGetGroupMembers(Dictionary<string, object> request)
|
||||
{
|
||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
||||
|
||||
if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("GroupID") || !request.ContainsKey("AccessToken"))
|
||||
NullResult(result, "Bad network data");
|
||||
else
|
||||
{
|
||||
UUID groupID = new UUID(request["GroupID"].ToString());
|
||||
string requestingAgentID = request["RequestingAgentID"].ToString();
|
||||
string token = request["AccessToken"].ToString();
|
||||
|
||||
List<ExtendedGroupMembersData> members = m_GroupsService.GetGroupMembers(requestingAgentID, groupID, token);
|
||||
if (members == null || (members != null && members.Count == 0))
|
||||
{
|
||||
NullResult(result, "No members");
|
||||
}
|
||||
else
|
||||
{
|
||||
Dictionary<string, object> dict = new Dictionary<string, object>();
|
||||
int i = 0;
|
||||
foreach (ExtendedGroupMembersData m in members)
|
||||
{
|
||||
dict["m-" + i++] = GroupsDataUtils.GroupMembersData(m);
|
||||
}
|
||||
|
||||
result["RESULT"] = dict;
|
||||
}
|
||||
}
|
||||
|
||||
string xmlString = ServerUtils.BuildXmlResponse(result);
|
||||
|
||||
//m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
|
||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
||||
}
|
||||
|
||||
byte[] HandleGetGroupRoles(Dictionary<string, object> request)
|
||||
{
|
||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
||||
|
||||
if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("GroupID") || !request.ContainsKey("AccessToken"))
|
||||
NullResult(result, "Bad network data");
|
||||
else
|
||||
{
|
||||
UUID groupID = new UUID(request["GroupID"].ToString());
|
||||
string requestingAgentID = request["RequestingAgentID"].ToString();
|
||||
string token = request["AccessToken"].ToString();
|
||||
|
||||
List<GroupRolesData> roles = m_GroupsService.GetGroupRoles(requestingAgentID, groupID, token);
|
||||
if (roles == null || (roles != null && roles.Count == 0))
|
||||
{
|
||||
NullResult(result, "No members");
|
||||
}
|
||||
else
|
||||
{
|
||||
Dictionary<string, object> dict = new Dictionary<string, object>();
|
||||
int i = 0;
|
||||
foreach (GroupRolesData r in roles)
|
||||
dict["r-" + i++] = GroupsDataUtils.GroupRolesData(r);
|
||||
|
||||
result["RESULT"] = dict;
|
||||
}
|
||||
}
|
||||
|
||||
string xmlString = ServerUtils.BuildXmlResponse(result);
|
||||
|
||||
//m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
|
||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
||||
}
|
||||
|
||||
byte[] HandleGetRoleMembers(Dictionary<string, object> request)
|
||||
{
|
||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
||||
|
||||
if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("GroupID") || !request.ContainsKey("AccessToken"))
|
||||
NullResult(result, "Bad network data");
|
||||
else
|
||||
{
|
||||
UUID groupID = new UUID(request["GroupID"].ToString());
|
||||
string requestingAgentID = request["RequestingAgentID"].ToString();
|
||||
string token = request["AccessToken"].ToString();
|
||||
|
||||
List<ExtendedGroupRoleMembersData> rmembers = m_GroupsService.GetGroupRoleMembers(requestingAgentID, groupID, token);
|
||||
if (rmembers == null || (rmembers != null && rmembers.Count == 0))
|
||||
{
|
||||
NullResult(result, "No members");
|
||||
}
|
||||
else
|
||||
{
|
||||
Dictionary<string, object> dict = new Dictionary<string, object>();
|
||||
int i = 0;
|
||||
foreach (ExtendedGroupRoleMembersData rm in rmembers)
|
||||
dict["rm-" + i++] = GroupsDataUtils.GroupRoleMembersData(rm);
|
||||
|
||||
result["RESULT"] = dict;
|
||||
}
|
||||
}
|
||||
|
||||
string xmlString = ServerUtils.BuildXmlResponse(result);
|
||||
|
||||
//m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
|
||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
||||
}
|
||||
|
||||
byte[] HandleAddNotice(Dictionary<string, object> request)
|
||||
{
|
||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
||||
|
||||
if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("GroupID") || !request.ContainsKey("NoticeID") ||
|
||||
!request.ContainsKey("FromName") || !request.ContainsKey("Subject") || !request.ContainsKey("Message") ||
|
||||
!request.ContainsKey("HasAttachment"))
|
||||
NullResult(result, "Bad network data");
|
||||
|
||||
else
|
||||
{
|
||||
|
||||
bool hasAtt = bool.Parse(request["HasAttachment"].ToString());
|
||||
byte attType = 0;
|
||||
string attName = string.Empty;
|
||||
string attOwner = string.Empty;
|
||||
UUID attItem = UUID.Zero;
|
||||
if (request.ContainsKey("AttachmentType"))
|
||||
attType = byte.Parse(request["AttachmentType"].ToString());
|
||||
if (request.ContainsKey("AttachmentName"))
|
||||
attName = request["AttachmentType"].ToString();
|
||||
if (request.ContainsKey("AttachmentItemID"))
|
||||
attItem = new UUID(request["AttachmentItemID"].ToString());
|
||||
if (request.ContainsKey("AttachmentOwnerID"))
|
||||
attOwner = request["AttachmentOwnerID"].ToString();
|
||||
|
||||
bool success = m_GroupsService.AddNotice(request["RequestingAgentID"].ToString(), new UUID(request["GroupID"].ToString()),
|
||||
new UUID(request["NoticeID"].ToString()), request["FromName"].ToString(), request["Subject"].ToString(),
|
||||
request["Message"].ToString(), hasAtt, attType, attName, attItem, attOwner);
|
||||
|
||||
result["RESULT"] = success.ToString();
|
||||
}
|
||||
|
||||
string xmlString = ServerUtils.BuildXmlResponse(result);
|
||||
|
||||
//m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
|
||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
||||
}
|
||||
|
||||
byte[] HandleVerifyNotice(Dictionary<string, object> request)
|
||||
{
|
||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
||||
|
||||
if (!request.ContainsKey("NoticeID") || !request.ContainsKey("GroupID"))
|
||||
NullResult(result, "Bad network data");
|
||||
|
||||
else
|
||||
{
|
||||
UUID noticeID = new UUID(request["NoticeID"].ToString());
|
||||
UUID groupID = new UUID(request["GroupID"].ToString());
|
||||
|
||||
bool success = m_GroupsService.VerifyNotice(noticeID, groupID);
|
||||
//m_log.DebugFormat("[XXX]: VerifyNotice returned {0}", success);
|
||||
result["RESULT"] = success.ToString();
|
||||
}
|
||||
|
||||
string xmlString = ServerUtils.BuildXmlResponse(result);
|
||||
|
||||
//m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
|
||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
#region Helpers
|
||||
|
||||
private void NullResult(Dictionary<string, object> result, string reason)
|
||||
{
|
||||
result["RESULT"] = "NULL";
|
||||
result["REASON"] = reason;
|
||||
}
|
||||
|
||||
private byte[] FailureResult()
|
||||
{
|
||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
||||
NullResult(result, "Unknown method");
|
||||
string xmlString = ServerUtils.BuildXmlResponse(result);
|
||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,112 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
|
||||
namespace OpenSim.Groups
|
||||
{
|
||||
public interface IGroupsServicesConnector
|
||||
{
|
||||
UUID CreateGroup(UUID RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee,
|
||||
bool openEnrollment, bool allowPublish, bool maturePublish, UUID founderID, out string reason);
|
||||
bool UpdateGroup(string RequestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee,
|
||||
bool openEnrollment, bool allowPublish, bool maturePublish, out string reason);
|
||||
ExtendedGroupRecord GetGroupRecord(string RequestingAgentID, UUID GroupID, string GroupName);
|
||||
List<DirGroupsReplyData> FindGroups(string RequestingAgentID, string search);
|
||||
List<GroupMembersData> GetGroupMembers(string RequestingAgentID, UUID GroupID);
|
||||
|
||||
bool AddGroupRole(string RequestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers, out string reason);
|
||||
bool UpdateGroupRole(string RequestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers);
|
||||
void RemoveGroupRole(string RequestingAgentID, UUID groupID, UUID roleID);
|
||||
List<GroupRolesData> GetGroupRoles(string RequestingAgentID, UUID GroupID);
|
||||
List<GroupRoleMembersData> GetGroupRoleMembers(string RequestingAgentID, UUID GroupID);
|
||||
|
||||
bool AddAgentToGroup(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID, string token, out string reason);
|
||||
void RemoveAgentFromGroup(string RequestingAgentID, string AgentID, UUID GroupID);
|
||||
|
||||
bool AddAgentToGroupInvite(string RequestingAgentID, UUID inviteID, UUID groupID, UUID roleID, string agentID);
|
||||
GroupInviteInfo GetAgentToGroupInvite(string RequestingAgentID, UUID inviteID);
|
||||
void RemoveAgentToGroupInvite(string RequestingAgentID, UUID inviteID);
|
||||
|
||||
void AddAgentToGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID);
|
||||
void RemoveAgentFromGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID);
|
||||
List<GroupRolesData> GetAgentGroupRoles(string RequestingAgentID, string AgentID, UUID GroupID);
|
||||
|
||||
void SetAgentActiveGroup(string RequestingAgentID, string AgentID, UUID GroupID);
|
||||
ExtendedGroupMembershipData GetAgentActiveMembership(string RequestingAgentID, string AgentID);
|
||||
|
||||
void SetAgentActiveGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID);
|
||||
void UpdateMembership(string RequestingAgentID, string AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile);
|
||||
|
||||
/// <summary>
|
||||
/// Get information about a specific group to which the user belongs.
|
||||
/// </summary>
|
||||
/// <param name="RequestingAgentID">The agent requesting the information.</param>
|
||||
/// <param name="AgentID">The agent requested.</param>
|
||||
/// <param name="GroupID">The group requested.</param>
|
||||
/// <returns>
|
||||
/// If the user is a member of the group then the data structure is returned. If not, then null is returned.
|
||||
/// </returns>
|
||||
ExtendedGroupMembershipData GetAgentGroupMembership(string RequestingAgentID, string AgentID, UUID GroupID);
|
||||
|
||||
/// <summary>
|
||||
/// Get information about the groups to which a user belongs.
|
||||
/// </summary>
|
||||
/// <param name="RequestingAgentID">The agent requesting the information.</param>
|
||||
/// <param name="AgentID">The agent requested.</param>
|
||||
/// <returns>
|
||||
/// Information about the groups to which the user belongs. If the user belongs to no groups then an empty
|
||||
/// list is returned.
|
||||
/// </returns>
|
||||
List<GroupMembershipData> GetAgentGroupMemberships(string RequestingAgentID, string AgentID);
|
||||
|
||||
bool AddGroupNotice(string RequestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message,
|
||||
bool hasAttachment, byte attType, string attName, UUID attItemID, string attOwnerID);
|
||||
GroupNoticeInfo GetGroupNotice(string RequestingAgentID, UUID noticeID);
|
||||
List<ExtendedGroupNoticeData> GetGroupNotices(string RequestingAgentID, UUID GroupID);
|
||||
|
||||
}
|
||||
|
||||
public class GroupInviteInfo
|
||||
{
|
||||
public UUID GroupID = UUID.Zero;
|
||||
public UUID RoleID = UUID.Zero;
|
||||
public string AgentID = string.Empty;
|
||||
public UUID InviteID = UUID.Zero;
|
||||
}
|
||||
|
||||
public class GroupNoticeInfo
|
||||
{
|
||||
public ExtendedGroupNoticeData noticeData = new ExtendedGroupNoticeData();
|
||||
public UUID GroupID = UUID.Zero;
|
||||
public string Message = string.Empty;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,325 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
|
||||
using OpenMetaverse;
|
||||
using Mono.Addins;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
|
||||
namespace OpenSim.Groups
|
||||
{
|
||||
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GroupsServiceLocalConnectorModule")]
|
||||
public class GroupsServiceLocalConnectorModule : ISharedRegionModule, IGroupsServicesConnector
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private bool m_Enabled = false;
|
||||
private GroupsService m_GroupsService;
|
||||
private IUserManagement m_UserManagement;
|
||||
private List<Scene> m_Scenes;
|
||||
private ForeignImporter m_ForeignImporter;
|
||||
|
||||
#region constructors
|
||||
public GroupsServiceLocalConnectorModule()
|
||||
{
|
||||
}
|
||||
|
||||
public GroupsServiceLocalConnectorModule(IConfigSource config, IUserManagement uman)
|
||||
{
|
||||
Init(config);
|
||||
m_UserManagement = uman;
|
||||
m_ForeignImporter = new ForeignImporter(uman);
|
||||
}
|
||||
#endregion
|
||||
|
||||
private void Init(IConfigSource config)
|
||||
{
|
||||
m_GroupsService = new GroupsService(config);
|
||||
m_Scenes = new List<Scene>();
|
||||
}
|
||||
|
||||
#region ISharedRegionModule
|
||||
|
||||
public void Initialise(IConfigSource config)
|
||||
{
|
||||
IConfig groupsConfig = config.Configs["Groups"];
|
||||
if (groupsConfig == null)
|
||||
return;
|
||||
|
||||
if ((groupsConfig.GetBoolean("Enabled", false) == false)
|
||||
|| (groupsConfig.GetString("ServicesConnectorModule", string.Empty) != Name))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Init(config);
|
||||
m_Enabled = true;
|
||||
|
||||
m_log.DebugFormat("[Groups]: Initializing {0}", this.Name);
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return "Groups Local Service Connector"; }
|
||||
}
|
||||
|
||||
public Type ReplaceableInterface
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
public void AddRegion(Scene scene)
|
||||
{
|
||||
if (!m_Enabled)
|
||||
return;
|
||||
|
||||
m_log.DebugFormat("[Groups]: Registering {0} with {1}", this.Name, scene.RegionInfo.RegionName);
|
||||
scene.RegisterModuleInterface<IGroupsServicesConnector>(this);
|
||||
m_Scenes.Add(scene);
|
||||
}
|
||||
|
||||
public void RemoveRegion(Scene scene)
|
||||
{
|
||||
if (!m_Enabled)
|
||||
return;
|
||||
|
||||
scene.UnregisterModuleInterface<IGroupsServicesConnector>(this);
|
||||
m_Scenes.Remove(scene);
|
||||
}
|
||||
|
||||
public void RegionLoaded(Scene scene)
|
||||
{
|
||||
if (!m_Enabled)
|
||||
return;
|
||||
|
||||
if (m_UserManagement == null)
|
||||
{
|
||||
m_UserManagement = scene.RequestModuleInterface<IUserManagement>();
|
||||
m_ForeignImporter = new ForeignImporter(m_UserManagement);
|
||||
}
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IGroupsServicesConnector
|
||||
|
||||
public UUID CreateGroup(UUID RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment,
|
||||
bool allowPublish, bool maturePublish, UUID founderID, out string reason)
|
||||
{
|
||||
m_log.DebugFormat("[Groups]: Creating group {0}", name);
|
||||
reason = string.Empty;
|
||||
return m_GroupsService.CreateGroup(RequestingAgentID.ToString(), name, charter, showInList, insigniaID,
|
||||
membershipFee, openEnrollment, allowPublish, maturePublish, founderID, out reason);
|
||||
}
|
||||
|
||||
public bool UpdateGroup(string RequestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee,
|
||||
bool openEnrollment, bool allowPublish, bool maturePublish, out string reason)
|
||||
{
|
||||
reason = string.Empty;
|
||||
m_GroupsService.UpdateGroup(RequestingAgentID, groupID, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish);
|
||||
return true;
|
||||
}
|
||||
|
||||
public ExtendedGroupRecord GetGroupRecord(string RequestingAgentID, UUID GroupID, string GroupName)
|
||||
{
|
||||
if (GroupID != UUID.Zero)
|
||||
return m_GroupsService.GetGroupRecord(RequestingAgentID, GroupID);
|
||||
else if (GroupName != null)
|
||||
return m_GroupsService.GetGroupRecord(RequestingAgentID, GroupName);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<DirGroupsReplyData> FindGroups(string RequestingAgentID, string search)
|
||||
{
|
||||
return m_GroupsService.FindGroups(RequestingAgentID, search);
|
||||
}
|
||||
|
||||
public List<GroupMembersData> GetGroupMembers(string RequestingAgentID, UUID GroupID)
|
||||
{
|
||||
List<ExtendedGroupMembersData> _members = m_GroupsService.GetGroupMembers(RequestingAgentID, GroupID);
|
||||
if (_members != null && _members.Count > 0)
|
||||
{
|
||||
List<GroupMembersData> members = _members.ConvertAll<GroupMembersData>(new Converter<ExtendedGroupMembersData, GroupMembersData>(m_ForeignImporter.ConvertGroupMembersData));
|
||||
return members;
|
||||
}
|
||||
|
||||
return new List<GroupMembersData>();
|
||||
}
|
||||
|
||||
public bool AddGroupRole(string RequestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers, out string reason)
|
||||
{
|
||||
return m_GroupsService.AddGroupRole(RequestingAgentID, groupID, roleID, name, description, title, powers, out reason);
|
||||
}
|
||||
|
||||
public bool UpdateGroupRole(string RequestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers)
|
||||
{
|
||||
return m_GroupsService.UpdateGroupRole(RequestingAgentID, groupID, roleID, name, description, title, powers);
|
||||
}
|
||||
|
||||
public void RemoveGroupRole(string RequestingAgentID, UUID groupID, UUID roleID)
|
||||
{
|
||||
m_GroupsService.RemoveGroupRole(RequestingAgentID, groupID, roleID);
|
||||
}
|
||||
|
||||
public List<GroupRolesData> GetGroupRoles(string RequestingAgentID, UUID GroupID)
|
||||
{
|
||||
return m_GroupsService.GetGroupRoles(RequestingAgentID, GroupID);
|
||||
}
|
||||
|
||||
public List<GroupRoleMembersData> GetGroupRoleMembers(string RequestingAgentID, UUID GroupID)
|
||||
{
|
||||
List<ExtendedGroupRoleMembersData> _rm = m_GroupsService.GetGroupRoleMembers(RequestingAgentID, GroupID);
|
||||
if (_rm != null && _rm.Count > 0)
|
||||
{
|
||||
List<GroupRoleMembersData> rm = _rm.ConvertAll<GroupRoleMembersData>(new Converter<ExtendedGroupRoleMembersData, GroupRoleMembersData>(m_ForeignImporter.ConvertGroupRoleMembersData));
|
||||
return rm;
|
||||
}
|
||||
|
||||
return new List<GroupRoleMembersData>();
|
||||
|
||||
}
|
||||
|
||||
public bool AddAgentToGroup(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID, string token, out string reason)
|
||||
{
|
||||
return m_GroupsService.AddAgentToGroup(RequestingAgentID, AgentID, GroupID, RoleID, token, out reason);
|
||||
}
|
||||
|
||||
public void RemoveAgentFromGroup(string RequestingAgentID, string AgentID, UUID GroupID)
|
||||
{
|
||||
m_GroupsService.RemoveAgentFromGroup(RequestingAgentID, AgentID, GroupID);
|
||||
}
|
||||
|
||||
public bool AddAgentToGroupInvite(string RequestingAgentID, UUID inviteID, UUID groupID, UUID roleID, string agentID)
|
||||
{
|
||||
return m_GroupsService.AddAgentToGroupInvite(RequestingAgentID, inviteID, groupID, roleID, agentID);
|
||||
}
|
||||
|
||||
public GroupInviteInfo GetAgentToGroupInvite(string RequestingAgentID, UUID inviteID)
|
||||
{
|
||||
return m_GroupsService.GetAgentToGroupInvite(RequestingAgentID, inviteID); ;
|
||||
}
|
||||
|
||||
public void RemoveAgentToGroupInvite(string RequestingAgentID, UUID inviteID)
|
||||
{
|
||||
m_GroupsService.RemoveAgentToGroupInvite(RequestingAgentID, inviteID);
|
||||
}
|
||||
|
||||
public void AddAgentToGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID)
|
||||
{
|
||||
m_GroupsService.AddAgentToGroupRole(RequestingAgentID, AgentID, GroupID, RoleID);
|
||||
}
|
||||
|
||||
public void RemoveAgentFromGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID)
|
||||
{
|
||||
m_GroupsService.RemoveAgentFromGroupRole(RequestingAgentID, AgentID, GroupID, RoleID);
|
||||
}
|
||||
|
||||
public List<GroupRolesData> GetAgentGroupRoles(string RequestingAgentID, string AgentID, UUID GroupID)
|
||||
{
|
||||
return m_GroupsService.GetAgentGroupRoles(RequestingAgentID, AgentID, GroupID);
|
||||
}
|
||||
|
||||
public void SetAgentActiveGroup(string RequestingAgentID, string AgentID, UUID GroupID)
|
||||
{
|
||||
m_GroupsService.SetAgentActiveGroup(RequestingAgentID, AgentID, GroupID);
|
||||
}
|
||||
|
||||
public ExtendedGroupMembershipData GetAgentActiveMembership(string RequestingAgentID, string AgentID)
|
||||
{
|
||||
return m_GroupsService.GetAgentActiveMembership(RequestingAgentID, AgentID);
|
||||
}
|
||||
|
||||
public void SetAgentActiveGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID)
|
||||
{
|
||||
m_GroupsService.SetAgentActiveGroupRole(RequestingAgentID, AgentID, GroupID, RoleID);
|
||||
}
|
||||
|
||||
public void UpdateMembership(string RequestingAgentID, string AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile)
|
||||
{
|
||||
m_GroupsService.UpdateMembership(RequestingAgentID, AgentID, GroupID, AcceptNotices, ListInProfile);
|
||||
}
|
||||
|
||||
public ExtendedGroupMembershipData GetAgentGroupMembership(string RequestingAgentID, string AgentID, UUID GroupID)
|
||||
{
|
||||
return m_GroupsService.GetAgentGroupMembership(RequestingAgentID, AgentID, GroupID); ;
|
||||
}
|
||||
|
||||
public List<GroupMembershipData> GetAgentGroupMemberships(string RequestingAgentID, string AgentID)
|
||||
{
|
||||
return m_GroupsService.GetAgentGroupMemberships(RequestingAgentID, AgentID);
|
||||
}
|
||||
|
||||
public bool AddGroupNotice(string RequestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message,
|
||||
bool hasAttachment, byte attType, string attName, UUID attItemID, string attOwnerID)
|
||||
{
|
||||
return m_GroupsService.AddGroupNotice(RequestingAgentID, groupID, noticeID, fromName, subject, message,
|
||||
hasAttachment, attType, attName, attItemID, attOwnerID);
|
||||
}
|
||||
|
||||
public GroupNoticeInfo GetGroupNotice(string RequestingAgentID, UUID noticeID)
|
||||
{
|
||||
GroupNoticeInfo notice = m_GroupsService.GetGroupNotice(RequestingAgentID, noticeID);
|
||||
|
||||
//if (notice != null && notice.noticeData.HasAttachment && notice.noticeData.AttachmentOwnerID != null)
|
||||
//{
|
||||
// UUID userID = UUID.Zero;
|
||||
// string url = string.Empty, first = string.Empty, last = string.Empty, tmp = string.Empty;
|
||||
// Util.ParseUniversalUserIdentifier(notice.noticeData.AttachmentOwnerID, out userID, out url, out first, out last, out tmp);
|
||||
// if (url != string.Empty)
|
||||
// m_UserManagement.AddUser(userID, first, last, url);
|
||||
//}
|
||||
|
||||
return notice;
|
||||
}
|
||||
|
||||
public List<ExtendedGroupNoticeData> GetGroupNotices(string RequestingAgentID, UUID GroupID)
|
||||
{
|
||||
return m_GroupsService.GetGroupNotices(RequestingAgentID, GroupID);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using Mono.Addins;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("OpenSim.Addons.Groups")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("http://opensimulator.org")]
|
||||
[assembly: AssemblyProduct("OpenSim.Addons.Groups")]
|
||||
[assembly: AssemblyCopyright("Copyright (c) OpenSimulator.org Developers")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("313d4865-d179-4735-9b5a-fe74885878b2")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
[assembly: AssemblyVersion("0.8.0.*")]
|
||||
|
||||
[assembly: Addin("OpenSim.Groups", "0.1")]
|
||||
[assembly: AddinDependency("OpenSim", "0.5")]
|
||||
@@ -1,673 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Server.Base;
|
||||
|
||||
using OpenMetaverse;
|
||||
using log4net;
|
||||
|
||||
namespace OpenSim.Groups
|
||||
{
|
||||
public class GroupsServiceRemoteConnector
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private string m_ServerURI;
|
||||
private object m_Lock = new object();
|
||||
|
||||
public GroupsServiceRemoteConnector(string url)
|
||||
{
|
||||
m_ServerURI = url;
|
||||
if (!m_ServerURI.EndsWith("/"))
|
||||
m_ServerURI += "/";
|
||||
|
||||
m_log.DebugFormat("[Groups.RemoteConnector]: Groups server at {0}", m_ServerURI);
|
||||
}
|
||||
|
||||
public ExtendedGroupRecord CreateGroup(string RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment,
|
||||
bool allowPublish, bool maturePublish, UUID founderID, out string reason)
|
||||
{
|
||||
reason = string.Empty;
|
||||
|
||||
ExtendedGroupRecord rec = new ExtendedGroupRecord();
|
||||
rec.AllowPublish = allowPublish;
|
||||
rec.Charter = charter;
|
||||
rec.FounderID = founderID;
|
||||
rec.GroupName = name;
|
||||
rec.GroupPicture = insigniaID;
|
||||
rec.MaturePublish = maturePublish;
|
||||
rec.MembershipFee = membershipFee;
|
||||
rec.OpenEnrollment = openEnrollment;
|
||||
rec.ShowInList = showInList;
|
||||
|
||||
Dictionary<string, object> sendData = GroupsDataUtils.GroupRecord(rec);
|
||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
||||
sendData["OP"] = "ADD";
|
||||
Dictionary<string, object> ret = MakeRequest("PUTGROUP", sendData);
|
||||
|
||||
if (ret == null)
|
||||
return null;
|
||||
|
||||
if (ret["RESULT"].ToString() == "NULL")
|
||||
{
|
||||
reason = ret["REASON"].ToString();
|
||||
return null;
|
||||
}
|
||||
|
||||
return GroupsDataUtils.GroupRecord((Dictionary<string, object>)ret["RESULT"]);
|
||||
|
||||
}
|
||||
|
||||
public ExtendedGroupRecord UpdateGroup(string RequestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish)
|
||||
{
|
||||
ExtendedGroupRecord rec = new ExtendedGroupRecord();
|
||||
rec.AllowPublish = allowPublish;
|
||||
rec.Charter = charter;
|
||||
rec.GroupPicture = insigniaID;
|
||||
rec.MaturePublish = maturePublish;
|
||||
rec.GroupID = groupID;
|
||||
rec.MembershipFee = membershipFee;
|
||||
rec.OpenEnrollment = openEnrollment;
|
||||
rec.ShowInList = showInList;
|
||||
|
||||
Dictionary<string, object> sendData = GroupsDataUtils.GroupRecord(rec);
|
||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
||||
sendData["OP"] = "UPDATE";
|
||||
Dictionary<string, object> ret = MakeRequest("PUTGROUP", sendData);
|
||||
|
||||
if (ret == null || (ret != null && ret["RESULT"].ToString() == "NULL"))
|
||||
return null;
|
||||
|
||||
return GroupsDataUtils.GroupRecord((Dictionary<string, object>)ret["RESULT"]);
|
||||
}
|
||||
|
||||
public ExtendedGroupRecord GetGroupRecord(string RequestingAgentID, UUID GroupID, string GroupName)
|
||||
{
|
||||
if (GroupID == UUID.Zero && (GroupName == null || (GroupName != null && GroupName == string.Empty)))
|
||||
return null;
|
||||
|
||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
||||
if (GroupID != UUID.Zero)
|
||||
sendData["GroupID"] = GroupID.ToString();
|
||||
if (!string.IsNullOrEmpty(GroupName))
|
||||
sendData["Name"] = GroupsDataUtils.Sanitize(GroupName);
|
||||
|
||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
||||
|
||||
Dictionary<string, object> ret = MakeRequest("GETGROUP", sendData);
|
||||
|
||||
if (ret == null || (ret != null && ret["RESULT"].ToString() == "NULL"))
|
||||
return null;
|
||||
|
||||
return GroupsDataUtils.GroupRecord((Dictionary<string, object>)ret["RESULT"]);
|
||||
}
|
||||
|
||||
public List<DirGroupsReplyData> FindGroups(string RequestingAgentID, string query)
|
||||
{
|
||||
List<DirGroupsReplyData> hits = new List<DirGroupsReplyData>();
|
||||
if (string.IsNullOrEmpty(query))
|
||||
return hits;
|
||||
|
||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
||||
sendData["Query"] = query;
|
||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
||||
|
||||
Dictionary<string, object> ret = MakeRequest("FINDGROUPS", sendData);
|
||||
|
||||
if (ret == null)
|
||||
return hits;
|
||||
|
||||
if (!ret.ContainsKey("RESULT"))
|
||||
return hits;
|
||||
|
||||
if (ret["RESULT"].ToString() == "NULL")
|
||||
return hits;
|
||||
|
||||
foreach (object v in ((Dictionary<string, object>)ret["RESULT"]).Values)
|
||||
{
|
||||
DirGroupsReplyData m = GroupsDataUtils.DirGroupsReplyData((Dictionary<string, object>)v);
|
||||
hits.Add(m);
|
||||
}
|
||||
|
||||
return hits;
|
||||
}
|
||||
|
||||
public GroupMembershipData AddAgentToGroup(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID, string token, out string reason)
|
||||
{
|
||||
reason = string.Empty;
|
||||
|
||||
Dictionary<string, object> sendData = new Dictionary<string,object>();
|
||||
sendData["AgentID"] = AgentID;
|
||||
sendData["GroupID"] = GroupID.ToString();
|
||||
sendData["RoleID"] = RoleID.ToString();
|
||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
||||
sendData["AccessToken"] = token;
|
||||
Dictionary<string, object> ret = MakeRequest("ADDAGENTTOGROUP", sendData);
|
||||
|
||||
if (ret == null)
|
||||
return null;
|
||||
|
||||
if (!ret.ContainsKey("RESULT"))
|
||||
return null;
|
||||
|
||||
if (ret["RESULT"].ToString() == "NULL")
|
||||
{
|
||||
reason = ret["REASON"].ToString();
|
||||
return null;
|
||||
}
|
||||
|
||||
return GroupsDataUtils.GroupMembershipData((Dictionary<string, object>)ret["RESULT"]);
|
||||
|
||||
}
|
||||
|
||||
public void RemoveAgentFromGroup(string RequestingAgentID, string AgentID, UUID GroupID)
|
||||
{
|
||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
||||
sendData["AgentID"] = AgentID;
|
||||
sendData["GroupID"] = GroupID.ToString();
|
||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
||||
MakeRequest("REMOVEAGENTFROMGROUP", sendData);
|
||||
}
|
||||
|
||||
public ExtendedGroupMembershipData GetMembership(string RequestingAgentID, string AgentID, UUID GroupID)
|
||||
{
|
||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
||||
sendData["AgentID"] = AgentID;
|
||||
if (GroupID != UUID.Zero)
|
||||
sendData["GroupID"] = GroupID.ToString();
|
||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
||||
Dictionary<string, object> ret = MakeRequest("GETMEMBERSHIP", sendData);
|
||||
|
||||
if (ret == null)
|
||||
return null;
|
||||
|
||||
if (!ret.ContainsKey("RESULT"))
|
||||
return null;
|
||||
|
||||
if (ret["RESULT"].ToString() == "NULL")
|
||||
return null;
|
||||
|
||||
return GroupsDataUtils.GroupMembershipData((Dictionary<string, object>)ret["RESULT"]);
|
||||
}
|
||||
|
||||
public List<GroupMembershipData> GetMemberships(string RequestingAgentID, string AgentID)
|
||||
{
|
||||
List<GroupMembershipData> memberships = new List<GroupMembershipData>();
|
||||
|
||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
||||
sendData["AgentID"] = AgentID;
|
||||
sendData["ALL"] = "true";
|
||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
||||
Dictionary<string, object> ret = MakeRequest("GETMEMBERSHIP", sendData);
|
||||
|
||||
if (ret == null)
|
||||
return memberships;
|
||||
|
||||
if (!ret.ContainsKey("RESULT"))
|
||||
return memberships;
|
||||
|
||||
if (ret["RESULT"].ToString() == "NULL")
|
||||
return memberships;
|
||||
|
||||
foreach (object v in ((Dictionary<string, object>)ret["RESULT"]).Values)
|
||||
{
|
||||
GroupMembershipData m = GroupsDataUtils.GroupMembershipData((Dictionary<string, object>)v);
|
||||
memberships.Add(m);
|
||||
}
|
||||
|
||||
return memberships;
|
||||
}
|
||||
|
||||
public List<ExtendedGroupMembersData> GetGroupMembers(string RequestingAgentID, UUID GroupID)
|
||||
{
|
||||
List<ExtendedGroupMembersData> members = new List<ExtendedGroupMembersData>();
|
||||
|
||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
||||
sendData["GroupID"] = GroupID.ToString();
|
||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
||||
|
||||
Dictionary<string, object> ret = MakeRequest("GETGROUPMEMBERS", sendData);
|
||||
|
||||
if (ret == null)
|
||||
return members;
|
||||
|
||||
if (!ret.ContainsKey("RESULT"))
|
||||
return members;
|
||||
|
||||
if (ret["RESULT"].ToString() == "NULL")
|
||||
return members;
|
||||
foreach (object v in ((Dictionary<string, object>)ret["RESULT"]).Values)
|
||||
{
|
||||
ExtendedGroupMembersData m = GroupsDataUtils.GroupMembersData((Dictionary<string, object>)v);
|
||||
members.Add(m);
|
||||
}
|
||||
|
||||
return members;
|
||||
}
|
||||
|
||||
public bool AddGroupRole(string RequestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers, out string reason)
|
||||
{
|
||||
reason = string.Empty;
|
||||
|
||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
||||
sendData["GroupID"] = groupID.ToString();
|
||||
sendData["RoleID"] = roleID.ToString();
|
||||
sendData["Name"] = GroupsDataUtils.Sanitize(name);
|
||||
sendData["Description"] = GroupsDataUtils.Sanitize(description);
|
||||
sendData["Title"] = GroupsDataUtils.Sanitize(title);
|
||||
sendData["Powers"] = powers.ToString();
|
||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
||||
sendData["OP"] = "ADD";
|
||||
Dictionary<string, object> ret = MakeRequest("PUTROLE", sendData);
|
||||
|
||||
if (ret == null)
|
||||
return false;
|
||||
|
||||
if (!ret.ContainsKey("RESULT"))
|
||||
return false;
|
||||
|
||||
if (ret["RESULT"].ToString().ToLower() != "true")
|
||||
{
|
||||
reason = ret["REASON"].ToString();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool UpdateGroupRole(string RequestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers)
|
||||
{
|
||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
||||
sendData["GroupID"] = groupID.ToString();
|
||||
sendData["RoleID"] = roleID.ToString();
|
||||
sendData["Name"] = GroupsDataUtils.Sanitize(name);
|
||||
sendData["Description"] = GroupsDataUtils.Sanitize(description);
|
||||
sendData["Title"] = GroupsDataUtils.Sanitize(title);
|
||||
sendData["Powers"] = powers.ToString();
|
||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
||||
sendData["OP"] = "UPDATE";
|
||||
Dictionary<string, object> ret = MakeRequest("PUTROLE", sendData);
|
||||
|
||||
if (ret == null)
|
||||
return false;
|
||||
|
||||
if (!ret.ContainsKey("RESULT"))
|
||||
return false;
|
||||
|
||||
if (ret["RESULT"].ToString().ToLower() != "true")
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void RemoveGroupRole(string RequestingAgentID, UUID groupID, UUID roleID)
|
||||
{
|
||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
||||
sendData["GroupID"] = groupID.ToString();
|
||||
sendData["RoleID"] = roleID.ToString();
|
||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
||||
MakeRequest("REMOVEROLE", sendData);
|
||||
}
|
||||
|
||||
public List<GroupRolesData> GetGroupRoles(string RequestingAgentID, UUID GroupID)
|
||||
{
|
||||
List<GroupRolesData> roles = new List<GroupRolesData>();
|
||||
|
||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
||||
sendData["GroupID"] = GroupID.ToString();
|
||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
||||
Dictionary<string, object> ret = MakeRequest("GETGROUPROLES", sendData);
|
||||
|
||||
if (ret == null)
|
||||
return roles;
|
||||
|
||||
if (!ret.ContainsKey("RESULT"))
|
||||
return roles;
|
||||
|
||||
if (ret["RESULT"].ToString() == "NULL")
|
||||
return roles;
|
||||
foreach (object v in ((Dictionary<string, object>)ret["RESULT"]).Values)
|
||||
{
|
||||
GroupRolesData m = GroupsDataUtils.GroupRolesData((Dictionary<string, object>)v);
|
||||
roles.Add(m);
|
||||
}
|
||||
|
||||
return roles;
|
||||
}
|
||||
|
||||
public List<ExtendedGroupRoleMembersData> GetGroupRoleMembers(string RequestingAgentID, UUID GroupID)
|
||||
{
|
||||
List<ExtendedGroupRoleMembersData> rmembers = new List<ExtendedGroupRoleMembersData>();
|
||||
|
||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
||||
sendData["GroupID"] = GroupID.ToString();
|
||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
||||
Dictionary<string, object> ret = MakeRequest("GETROLEMEMBERS", sendData);
|
||||
|
||||
if (ret == null)
|
||||
return rmembers;
|
||||
|
||||
if (!ret.ContainsKey("RESULT"))
|
||||
return rmembers;
|
||||
|
||||
if (ret["RESULT"].ToString() == "NULL")
|
||||
return rmembers;
|
||||
|
||||
foreach (object v in ((Dictionary<string, object>)ret["RESULT"]).Values)
|
||||
{
|
||||
ExtendedGroupRoleMembersData m = GroupsDataUtils.GroupRoleMembersData((Dictionary<string, object>)v);
|
||||
rmembers.Add(m);
|
||||
}
|
||||
|
||||
return rmembers;
|
||||
}
|
||||
|
||||
public bool AddAgentToGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID)
|
||||
{
|
||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
||||
sendData["AgentID"] = AgentID.ToString();
|
||||
sendData["GroupID"] = GroupID.ToString();
|
||||
sendData["RoleID"] = RoleID.ToString();
|
||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
||||
sendData["OP"] = "ADD";
|
||||
|
||||
Dictionary<string, object> ret = MakeRequest("AGENTROLE", sendData);
|
||||
|
||||
if (ret == null)
|
||||
return false;
|
||||
|
||||
if (!ret.ContainsKey("RESULT"))
|
||||
return false;
|
||||
|
||||
if (ret["RESULT"].ToString().ToLower() != "true")
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool RemoveAgentFromGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID)
|
||||
{
|
||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
||||
sendData["AgentID"] = AgentID.ToString();
|
||||
sendData["GroupID"] = GroupID.ToString();
|
||||
sendData["RoleID"] = RoleID.ToString();
|
||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
||||
sendData["OP"] = "DELETE";
|
||||
|
||||
Dictionary<string, object> ret = MakeRequest("AGENTROLE", sendData);
|
||||
|
||||
if (ret == null)
|
||||
return false;
|
||||
|
||||
if (!ret.ContainsKey("RESULT"))
|
||||
return false;
|
||||
|
||||
if (ret["RESULT"].ToString().ToLower() != "true")
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public List<GroupRolesData> GetAgentGroupRoles(string RequestingAgentID, string AgentID, UUID GroupID)
|
||||
{
|
||||
List<GroupRolesData> roles = new List<GroupRolesData>();
|
||||
|
||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
||||
sendData["AgentID"] = AgentID.ToString();
|
||||
sendData["GroupID"] = GroupID.ToString();
|
||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
||||
Dictionary<string, object> ret = MakeRequest("GETAGENTROLES", sendData);
|
||||
|
||||
if (ret == null)
|
||||
return roles;
|
||||
|
||||
if (!ret.ContainsKey("RESULT"))
|
||||
return roles;
|
||||
|
||||
if (ret["RESULT"].ToString() == "NULL")
|
||||
return roles;
|
||||
|
||||
foreach (object v in ((Dictionary<string, object>)ret["RESULT"]).Values)
|
||||
{
|
||||
GroupRolesData m = GroupsDataUtils.GroupRolesData((Dictionary<string, object>)v);
|
||||
roles.Add(m);
|
||||
}
|
||||
|
||||
return roles;
|
||||
}
|
||||
|
||||
public GroupMembershipData SetAgentActiveGroup(string RequestingAgentID, string AgentID, UUID GroupID)
|
||||
{
|
||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
||||
sendData["AgentID"] = AgentID.ToString();
|
||||
sendData["GroupID"] = GroupID.ToString();
|
||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
||||
sendData["OP"] = "GROUP";
|
||||
|
||||
Dictionary<string, object> ret = MakeRequest("SETACTIVE", sendData);
|
||||
|
||||
if (ret == null)
|
||||
return null;
|
||||
|
||||
if (!ret.ContainsKey("RESULT"))
|
||||
return null;
|
||||
|
||||
if (ret["RESULT"].ToString() == "NULL")
|
||||
return null;
|
||||
|
||||
return GroupsDataUtils.GroupMembershipData((Dictionary<string, object>)ret["RESULT"]);
|
||||
}
|
||||
|
||||
public void SetAgentActiveGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID)
|
||||
{
|
||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
||||
sendData["AgentID"] = AgentID.ToString();
|
||||
sendData["GroupID"] = GroupID.ToString();
|
||||
sendData["RoleID"] = RoleID.ToString();
|
||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
||||
sendData["OP"] = "ROLE";
|
||||
|
||||
MakeRequest("SETACTIVE", sendData);
|
||||
}
|
||||
|
||||
public void UpdateMembership(string RequestingAgentID, string AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile)
|
||||
{
|
||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
||||
sendData["AgentID"] = AgentID.ToString();
|
||||
sendData["GroupID"] = GroupID.ToString();
|
||||
sendData["AcceptNotices"] = AcceptNotices.ToString();
|
||||
sendData["ListInProfile"] = ListInProfile.ToString();
|
||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
||||
MakeRequest("UPDATEMEMBERSHIP", sendData);
|
||||
}
|
||||
|
||||
public bool AddAgentToGroupInvite(string RequestingAgentID, UUID inviteID, UUID groupID, UUID roleID, string agentID)
|
||||
{
|
||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
||||
sendData["InviteID"] = inviteID.ToString();
|
||||
sendData["GroupID"] = groupID.ToString();
|
||||
sendData["RoleID"] = roleID.ToString();
|
||||
sendData["AgentID"] = agentID.ToString();
|
||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
||||
sendData["OP"] = "ADD";
|
||||
|
||||
Dictionary<string, object> ret = MakeRequest("INVITE", sendData);
|
||||
|
||||
if (ret == null)
|
||||
return false;
|
||||
|
||||
if (!ret.ContainsKey("RESULT"))
|
||||
return false;
|
||||
|
||||
if (ret["RESULT"].ToString().ToLower() != "true") // it may return "NULL"
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public GroupInviteInfo GetAgentToGroupInvite(string RequestingAgentID, UUID inviteID)
|
||||
{
|
||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
||||
sendData["InviteID"] = inviteID.ToString();
|
||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
||||
sendData["OP"] = "GET";
|
||||
|
||||
Dictionary<string, object> ret = MakeRequest("INVITE", sendData);
|
||||
|
||||
if (ret == null)
|
||||
return null;
|
||||
|
||||
if (!ret.ContainsKey("RESULT"))
|
||||
return null;
|
||||
|
||||
if (ret["RESULT"].ToString() == "NULL")
|
||||
return null;
|
||||
|
||||
return GroupsDataUtils.GroupInviteInfo((Dictionary<string, object>)ret["RESULT"]);
|
||||
}
|
||||
|
||||
public void RemoveAgentToGroupInvite(string RequestingAgentID, UUID inviteID)
|
||||
{
|
||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
||||
sendData["InviteID"] = inviteID.ToString();
|
||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
||||
sendData["OP"] = "DELETE";
|
||||
|
||||
MakeRequest("INVITE", sendData);
|
||||
}
|
||||
|
||||
public bool AddGroupNotice(string RequestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message,
|
||||
bool hasAttachment, byte attType, string attName, UUID attItemID, string attOwnerID)
|
||||
{
|
||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
||||
sendData["GroupID"] = groupID.ToString();
|
||||
sendData["NoticeID"] = noticeID.ToString();
|
||||
sendData["FromName"] = GroupsDataUtils.Sanitize(fromName);
|
||||
sendData["Subject"] = GroupsDataUtils.Sanitize(subject);
|
||||
sendData["Message"] = GroupsDataUtils.Sanitize(message);
|
||||
sendData["HasAttachment"] = hasAttachment.ToString();
|
||||
if (hasAttachment)
|
||||
{
|
||||
sendData["AttachmentType"] = attType.ToString();
|
||||
sendData["AttachmentName"] = attName.ToString();
|
||||
sendData["AttachmentItemID"] = attItemID.ToString();
|
||||
sendData["AttachmentOwnerID"] = attOwnerID;
|
||||
}
|
||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
||||
|
||||
Dictionary<string, object> ret = MakeRequest("ADDNOTICE", sendData);
|
||||
|
||||
if (ret == null)
|
||||
return false;
|
||||
|
||||
if (!ret.ContainsKey("RESULT"))
|
||||
return false;
|
||||
|
||||
if (ret["RESULT"].ToString().ToLower() != "true")
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public GroupNoticeInfo GetGroupNotice(string RequestingAgentID, UUID noticeID)
|
||||
{
|
||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
||||
sendData["NoticeID"] = noticeID.ToString();
|
||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
||||
|
||||
Dictionary<string, object> ret = MakeRequest("GETNOTICES", sendData);
|
||||
|
||||
if (ret == null)
|
||||
return null;
|
||||
|
||||
if (!ret.ContainsKey("RESULT"))
|
||||
return null;
|
||||
|
||||
if (ret["RESULT"].ToString() == "NULL")
|
||||
return null;
|
||||
|
||||
return GroupsDataUtils.GroupNoticeInfo((Dictionary<string, object>)ret["RESULT"]);
|
||||
}
|
||||
|
||||
public List<ExtendedGroupNoticeData> GetGroupNotices(string RequestingAgentID, UUID GroupID)
|
||||
{
|
||||
List<ExtendedGroupNoticeData> notices = new List<ExtendedGroupNoticeData>();
|
||||
|
||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
||||
sendData["GroupID"] = GroupID.ToString();
|
||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
||||
Dictionary<string, object> ret = MakeRequest("GETNOTICES", sendData);
|
||||
|
||||
if (ret == null)
|
||||
return notices;
|
||||
|
||||
if (!ret.ContainsKey("RESULT"))
|
||||
return notices;
|
||||
|
||||
if (ret["RESULT"].ToString() == "NULL")
|
||||
return notices;
|
||||
|
||||
foreach (object v in ((Dictionary<string, object>)ret["RESULT"]).Values)
|
||||
{
|
||||
ExtendedGroupNoticeData m = GroupsDataUtils.GroupNoticeData((Dictionary<string, object>)v);
|
||||
notices.Add(m);
|
||||
}
|
||||
|
||||
return notices;
|
||||
}
|
||||
|
||||
#region Make Request
|
||||
|
||||
private Dictionary<string, object> MakeRequest(string method, Dictionary<string, object> sendData)
|
||||
{
|
||||
sendData["METHOD"] = method;
|
||||
|
||||
string reply = string.Empty;
|
||||
lock (m_Lock)
|
||||
reply = SynchronousRestFormsRequester.MakeRequest("POST",
|
||||
m_ServerURI + "groups",
|
||||
ServerUtils.BuildQueryString(sendData));
|
||||
|
||||
if (reply == string.Empty)
|
||||
return null;
|
||||
|
||||
Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(
|
||||
reply);
|
||||
|
||||
return replyData;
|
||||
}
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,412 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Text;
|
||||
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Server.Base;
|
||||
|
||||
using OpenMetaverse;
|
||||
using Mono.Addins;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
|
||||
namespace OpenSim.Groups
|
||||
{
|
||||
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GroupsServiceRemoteConnectorModule")]
|
||||
public class GroupsServiceRemoteConnectorModule : ISharedRegionModule, IGroupsServicesConnector
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private bool m_Enabled = false;
|
||||
private GroupsServiceRemoteConnector m_GroupsService;
|
||||
private IUserManagement m_UserManagement;
|
||||
private List<Scene> m_Scenes;
|
||||
|
||||
private RemoteConnectorCacheWrapper m_CacheWrapper;
|
||||
|
||||
#region constructors
|
||||
public GroupsServiceRemoteConnectorModule()
|
||||
{
|
||||
}
|
||||
|
||||
public GroupsServiceRemoteConnectorModule(IConfigSource config, IUserManagement uman)
|
||||
{
|
||||
Init(config);
|
||||
m_UserManagement = uman;
|
||||
m_CacheWrapper = new RemoteConnectorCacheWrapper(m_UserManagement);
|
||||
|
||||
}
|
||||
#endregion
|
||||
|
||||
private void Init(IConfigSource config)
|
||||
{
|
||||
IConfig groupsConfig = config.Configs["Groups"];
|
||||
string url = groupsConfig.GetString("GroupsServerURI", string.Empty);
|
||||
if (!Uri.IsWellFormedUriString(url, UriKind.Absolute))
|
||||
throw new Exception(string.Format("[Groups.RemoteConnector]: Malformed groups server URL {0}. Fix it or disable the Groups feature.", url));
|
||||
|
||||
m_GroupsService = new GroupsServiceRemoteConnector(url);
|
||||
m_Scenes = new List<Scene>();
|
||||
|
||||
}
|
||||
|
||||
#region ISharedRegionModule
|
||||
|
||||
public void Initialise(IConfigSource config)
|
||||
{
|
||||
IConfig groupsConfig = config.Configs["Groups"];
|
||||
if (groupsConfig == null)
|
||||
return;
|
||||
|
||||
if ((groupsConfig.GetBoolean("Enabled", false) == false)
|
||||
|| (groupsConfig.GetString("ServicesConnectorModule", string.Empty) != Name))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Init(config);
|
||||
|
||||
m_Enabled = true;
|
||||
m_log.DebugFormat("[Groups.RemoteConnector]: Initializing {0}", this.Name);
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return "Groups Remote Service Connector"; }
|
||||
}
|
||||
|
||||
public Type ReplaceableInterface
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
public void AddRegion(Scene scene)
|
||||
{
|
||||
if (!m_Enabled)
|
||||
return;
|
||||
|
||||
m_log.DebugFormat("[Groups.RemoteConnector]: Registering {0} with {1}", this.Name, scene.RegionInfo.RegionName);
|
||||
scene.RegisterModuleInterface<IGroupsServicesConnector>(this);
|
||||
m_Scenes.Add(scene);
|
||||
}
|
||||
|
||||
public void RemoveRegion(Scene scene)
|
||||
{
|
||||
if (!m_Enabled)
|
||||
return;
|
||||
|
||||
scene.UnregisterModuleInterface<IGroupsServicesConnector>(this);
|
||||
m_Scenes.Remove(scene);
|
||||
}
|
||||
|
||||
public void RegionLoaded(Scene scene)
|
||||
{
|
||||
if (!m_Enabled)
|
||||
return;
|
||||
|
||||
if (m_UserManagement == null)
|
||||
{
|
||||
m_UserManagement = scene.RequestModuleInterface<IUserManagement>();
|
||||
m_CacheWrapper = new RemoteConnectorCacheWrapper(m_UserManagement);
|
||||
}
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IGroupsServicesConnector
|
||||
|
||||
public UUID CreateGroup(UUID RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment,
|
||||
bool allowPublish, bool maturePublish, UUID founderID, out string reason)
|
||||
{
|
||||
m_log.DebugFormat("[Groups.RemoteConnector]: Creating group {0}", name);
|
||||
string r = string.Empty;
|
||||
|
||||
UUID groupID = m_CacheWrapper.CreateGroup(RequestingAgentID, delegate
|
||||
{
|
||||
return m_GroupsService.CreateGroup(RequestingAgentID.ToString(), name, charter, showInList, insigniaID,
|
||||
membershipFee, openEnrollment, allowPublish, maturePublish, founderID, out r);
|
||||
});
|
||||
|
||||
reason = r;
|
||||
return groupID;
|
||||
}
|
||||
|
||||
public bool UpdateGroup(string RequestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee,
|
||||
bool openEnrollment, bool allowPublish, bool maturePublish, out string reason)
|
||||
{
|
||||
string r = string.Empty;
|
||||
|
||||
bool success = m_CacheWrapper.UpdateGroup(groupID, delegate
|
||||
{
|
||||
return m_GroupsService.UpdateGroup(RequestingAgentID, groupID, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish);
|
||||
});
|
||||
|
||||
reason = r;
|
||||
return success;
|
||||
}
|
||||
|
||||
public ExtendedGroupRecord GetGroupRecord(string RequestingAgentID, UUID GroupID, string GroupName)
|
||||
{
|
||||
if (GroupID == UUID.Zero && (GroupName == null || GroupName != null && GroupName == string.Empty))
|
||||
return null;
|
||||
|
||||
return m_CacheWrapper.GetGroupRecord(RequestingAgentID,GroupID,GroupName, delegate
|
||||
{
|
||||
return m_GroupsService.GetGroupRecord(RequestingAgentID, GroupID, GroupName);
|
||||
});
|
||||
}
|
||||
|
||||
public List<DirGroupsReplyData> FindGroups(string RequestingAgentID, string search)
|
||||
{
|
||||
// TODO!
|
||||
return m_GroupsService.FindGroups(RequestingAgentID, search);
|
||||
}
|
||||
|
||||
public bool AddAgentToGroup(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID, string token, out string reason)
|
||||
{
|
||||
string agentFullID = AgentID;
|
||||
m_log.DebugFormat("[Groups.RemoteConnector]: Add agent {0} to group {1}", agentFullID, GroupID);
|
||||
string r = string.Empty;
|
||||
|
||||
bool success = m_CacheWrapper.AddAgentToGroup(RequestingAgentID, AgentID, GroupID, delegate
|
||||
{
|
||||
return m_GroupsService.AddAgentToGroup(RequestingAgentID, agentFullID, GroupID, RoleID, token, out r);
|
||||
});
|
||||
|
||||
reason = r;
|
||||
return success;
|
||||
}
|
||||
|
||||
public void RemoveAgentFromGroup(string RequestingAgentID, string AgentID, UUID GroupID)
|
||||
{
|
||||
m_CacheWrapper.RemoveAgentFromGroup(RequestingAgentID, AgentID, GroupID, delegate
|
||||
{
|
||||
m_GroupsService.RemoveAgentFromGroup(RequestingAgentID, AgentID, GroupID);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public void SetAgentActiveGroup(string RequestingAgentID, string AgentID, UUID GroupID)
|
||||
{
|
||||
m_CacheWrapper.SetAgentActiveGroup(AgentID, delegate
|
||||
{
|
||||
return m_GroupsService.SetAgentActiveGroup(RequestingAgentID, AgentID, GroupID);
|
||||
});
|
||||
}
|
||||
|
||||
public ExtendedGroupMembershipData GetAgentActiveMembership(string RequestingAgentID, string AgentID)
|
||||
{
|
||||
return m_CacheWrapper.GetAgentActiveMembership(AgentID, delegate
|
||||
{
|
||||
return m_GroupsService.GetMembership(RequestingAgentID, AgentID, UUID.Zero);
|
||||
});
|
||||
}
|
||||
|
||||
public ExtendedGroupMembershipData GetAgentGroupMembership(string RequestingAgentID, string AgentID, UUID GroupID)
|
||||
{
|
||||
return m_CacheWrapper.GetAgentGroupMembership(AgentID, GroupID, delegate
|
||||
{
|
||||
return m_GroupsService.GetMembership(RequestingAgentID, AgentID, GroupID);
|
||||
});
|
||||
}
|
||||
|
||||
public List<GroupMembershipData> GetAgentGroupMemberships(string RequestingAgentID, string AgentID)
|
||||
{
|
||||
return m_CacheWrapper.GetAgentGroupMemberships(AgentID, delegate
|
||||
{
|
||||
return m_GroupsService.GetMemberships(RequestingAgentID, AgentID);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public List<GroupMembersData> GetGroupMembers(string RequestingAgentID, UUID GroupID)
|
||||
{
|
||||
return m_CacheWrapper.GetGroupMembers(RequestingAgentID, GroupID, delegate
|
||||
{
|
||||
return m_GroupsService.GetGroupMembers(RequestingAgentID, GroupID);
|
||||
});
|
||||
}
|
||||
|
||||
public bool AddGroupRole(string RequestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers, out string reason)
|
||||
{
|
||||
string r = string.Empty;
|
||||
bool success = m_CacheWrapper.AddGroupRole(groupID, roleID, description, name, powers, title, delegate
|
||||
{
|
||||
return m_GroupsService.AddGroupRole(RequestingAgentID, groupID, roleID, name, description, title, powers, out r);
|
||||
});
|
||||
|
||||
reason = r;
|
||||
return success;
|
||||
}
|
||||
|
||||
public bool UpdateGroupRole(string RequestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers)
|
||||
{
|
||||
return m_CacheWrapper.UpdateGroupRole(groupID, roleID, name, description, title, powers, delegate
|
||||
{
|
||||
return m_GroupsService.UpdateGroupRole(RequestingAgentID, groupID, roleID, name, description, title, powers);
|
||||
});
|
||||
}
|
||||
|
||||
public void RemoveGroupRole(string RequestingAgentID, UUID groupID, UUID roleID)
|
||||
{
|
||||
m_CacheWrapper.RemoveGroupRole(RequestingAgentID, groupID, roleID, delegate
|
||||
{
|
||||
m_GroupsService.RemoveGroupRole(RequestingAgentID, groupID, roleID);
|
||||
});
|
||||
}
|
||||
|
||||
public List<GroupRolesData> GetGroupRoles(string RequestingAgentID, UUID GroupID)
|
||||
{
|
||||
return m_CacheWrapper.GetGroupRoles(RequestingAgentID, GroupID, delegate
|
||||
{
|
||||
return m_GroupsService.GetGroupRoles(RequestingAgentID, GroupID);
|
||||
});
|
||||
}
|
||||
|
||||
public List<GroupRoleMembersData> GetGroupRoleMembers(string RequestingAgentID, UUID GroupID)
|
||||
{
|
||||
return m_CacheWrapper.GetGroupRoleMembers(RequestingAgentID, GroupID, delegate
|
||||
{
|
||||
return m_GroupsService.GetGroupRoleMembers(RequestingAgentID, GroupID);
|
||||
});
|
||||
}
|
||||
|
||||
public void AddAgentToGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID)
|
||||
{
|
||||
m_CacheWrapper.AddAgentToGroupRole(RequestingAgentID, AgentID, GroupID, RoleID, delegate
|
||||
{
|
||||
return m_GroupsService.AddAgentToGroupRole(RequestingAgentID, AgentID, GroupID, RoleID);
|
||||
});
|
||||
}
|
||||
|
||||
public void RemoveAgentFromGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID)
|
||||
{
|
||||
m_CacheWrapper.RemoveAgentFromGroupRole(RequestingAgentID, AgentID, GroupID, RoleID, delegate
|
||||
{
|
||||
return m_GroupsService.RemoveAgentFromGroupRole(RequestingAgentID, AgentID, GroupID, RoleID);
|
||||
});
|
||||
}
|
||||
|
||||
public List<GroupRolesData> GetAgentGroupRoles(string RequestingAgentID, string AgentID, UUID GroupID)
|
||||
{
|
||||
return m_CacheWrapper.GetAgentGroupRoles(RequestingAgentID, AgentID, GroupID, delegate
|
||||
{
|
||||
return m_GroupsService.GetAgentGroupRoles(RequestingAgentID, AgentID, GroupID); ;
|
||||
});
|
||||
}
|
||||
|
||||
public void SetAgentActiveGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID)
|
||||
{
|
||||
m_CacheWrapper.SetAgentActiveGroupRole(AgentID, GroupID, delegate
|
||||
{
|
||||
m_GroupsService.SetAgentActiveGroupRole(RequestingAgentID, AgentID, GroupID, RoleID);
|
||||
});
|
||||
}
|
||||
|
||||
public void UpdateMembership(string RequestingAgentID, string AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile)
|
||||
{
|
||||
m_CacheWrapper.UpdateMembership(AgentID, GroupID, AcceptNotices, ListInProfile, delegate
|
||||
{
|
||||
m_GroupsService.UpdateMembership(RequestingAgentID, AgentID, GroupID, AcceptNotices, ListInProfile);
|
||||
});
|
||||
}
|
||||
|
||||
public bool AddAgentToGroupInvite(string RequestingAgentID, UUID inviteID, UUID groupID, UUID roleID, string agentID)
|
||||
{
|
||||
return m_GroupsService.AddAgentToGroupInvite(RequestingAgentID, inviteID, groupID, roleID, agentID);
|
||||
}
|
||||
|
||||
public GroupInviteInfo GetAgentToGroupInvite(string RequestingAgentID, UUID inviteID)
|
||||
{
|
||||
return m_GroupsService.GetAgentToGroupInvite(RequestingAgentID, inviteID);
|
||||
}
|
||||
|
||||
public void RemoveAgentToGroupInvite(string RequestingAgentID, UUID inviteID)
|
||||
{
|
||||
m_GroupsService.RemoveAgentToGroupInvite(RequestingAgentID, inviteID);
|
||||
}
|
||||
|
||||
public bool AddGroupNotice(string RequestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message,
|
||||
bool hasAttachment, byte attType, string attName, UUID attItemID, string attOwnerID)
|
||||
{
|
||||
GroupNoticeInfo notice = new GroupNoticeInfo();
|
||||
notice.GroupID = groupID;
|
||||
notice.Message = message;
|
||||
notice.noticeData = new ExtendedGroupNoticeData();
|
||||
notice.noticeData.AttachmentItemID = attItemID;
|
||||
notice.noticeData.AttachmentName = attName;
|
||||
notice.noticeData.AttachmentOwnerID = attOwnerID.ToString();
|
||||
notice.noticeData.AttachmentType = attType;
|
||||
notice.noticeData.FromName = fromName;
|
||||
notice.noticeData.HasAttachment = hasAttachment;
|
||||
notice.noticeData.NoticeID = noticeID;
|
||||
notice.noticeData.Subject = subject;
|
||||
notice.noticeData.Timestamp = (uint)Util.UnixTimeSinceEpoch();
|
||||
|
||||
return m_CacheWrapper.AddGroupNotice(groupID, noticeID, notice, delegate
|
||||
{
|
||||
return m_GroupsService.AddGroupNotice(RequestingAgentID, groupID, noticeID, fromName, subject, message,
|
||||
hasAttachment, attType, attName, attItemID, attOwnerID);
|
||||
});
|
||||
}
|
||||
|
||||
public GroupNoticeInfo GetGroupNotice(string RequestingAgentID, UUID noticeID)
|
||||
{
|
||||
return m_CacheWrapper.GetGroupNotice(noticeID, delegate
|
||||
{
|
||||
return m_GroupsService.GetGroupNotice(RequestingAgentID, noticeID);
|
||||
});
|
||||
}
|
||||
|
||||
public List<ExtendedGroupNoticeData> GetGroupNotices(string RequestingAgentID, UUID GroupID)
|
||||
{
|
||||
return m_CacheWrapper.GetGroupNotices(GroupID, delegate
|
||||
{
|
||||
return m_GroupsService.GetGroupNotices(RequestingAgentID, GroupID);
|
||||
});
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,789 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Nini.Config;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Server.Base;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using OpenSim.Framework.Servers.HttpServer;
|
||||
using OpenSim.Server.Handlers.Base;
|
||||
using log4net;
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace OpenSim.Groups
|
||||
{
|
||||
public class GroupsServiceRobustConnector : ServiceConnector
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private GroupsService m_GroupsService;
|
||||
private string m_ConfigName = "Groups";
|
||||
|
||||
public GroupsServiceRobustConnector(IConfigSource config, IHttpServer server, string configName) :
|
||||
base(config, server, configName)
|
||||
{
|
||||
if (configName != String.Empty)
|
||||
m_ConfigName = configName;
|
||||
|
||||
m_log.DebugFormat("[Groups.RobustConnector]: Starting with config name {0}", m_ConfigName);
|
||||
|
||||
m_GroupsService = new GroupsService(config);
|
||||
|
||||
server.AddStreamHandler(new GroupsServicePostHandler(m_GroupsService));
|
||||
}
|
||||
}
|
||||
|
||||
public class GroupsServicePostHandler : BaseStreamHandler
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private GroupsService m_GroupsService;
|
||||
|
||||
public GroupsServicePostHandler(GroupsService service) :
|
||||
base("POST", "/groups")
|
||||
{
|
||||
m_GroupsService = service;
|
||||
}
|
||||
|
||||
protected override byte[] ProcessRequest(string path, Stream requestData,
|
||||
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
||||
{
|
||||
StreamReader sr = new StreamReader(requestData);
|
||||
string body = sr.ReadToEnd();
|
||||
sr.Close();
|
||||
body = body.Trim();
|
||||
|
||||
//m_log.DebugFormat("[XXX]: query String: {0}", body);
|
||||
|
||||
try
|
||||
{
|
||||
Dictionary<string, object> request =
|
||||
ServerUtils.ParseQueryString(body);
|
||||
|
||||
if (!request.ContainsKey("METHOD"))
|
||||
return FailureResult();
|
||||
|
||||
string method = request["METHOD"].ToString();
|
||||
request.Remove("METHOD");
|
||||
|
||||
m_log.DebugFormat("[Groups.Handler]: {0}", method);
|
||||
switch (method)
|
||||
{
|
||||
case "PUTGROUP":
|
||||
return HandleAddOrUpdateGroup(request);
|
||||
case "GETGROUP":
|
||||
return HandleGetGroup(request);
|
||||
case "ADDAGENTTOGROUP":
|
||||
return HandleAddAgentToGroup(request);
|
||||
case "REMOVEAGENTFROMGROUP":
|
||||
return HandleRemoveAgentFromGroup(request);
|
||||
case "GETMEMBERSHIP":
|
||||
return HandleGetMembership(request);
|
||||
case "GETGROUPMEMBERS":
|
||||
return HandleGetGroupMembers(request);
|
||||
case "PUTROLE":
|
||||
return HandlePutRole(request);
|
||||
case "REMOVEROLE":
|
||||
return HandleRemoveRole(request);
|
||||
case "GETGROUPROLES":
|
||||
return HandleGetGroupRoles(request);
|
||||
case "GETROLEMEMBERS":
|
||||
return HandleGetRoleMembers(request);
|
||||
case "AGENTROLE":
|
||||
return HandleAgentRole(request);
|
||||
case "GETAGENTROLES":
|
||||
return HandleGetAgentRoles(request);
|
||||
case "SETACTIVE":
|
||||
return HandleSetActive(request);
|
||||
case "UPDATEMEMBERSHIP":
|
||||
return HandleUpdateMembership(request);
|
||||
case "INVITE":
|
||||
return HandleInvite(request);
|
||||
case "ADDNOTICE":
|
||||
return HandleAddNotice(request);
|
||||
case "GETNOTICES":
|
||||
return HandleGetNotices(request);
|
||||
case "FINDGROUPS":
|
||||
return HandleFindGroups(request);
|
||||
}
|
||||
m_log.DebugFormat("[GROUPS HANDLER]: unknown method request: {0}", method);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[GROUPS HANDLER]: Exception {0}", e.StackTrace);
|
||||
}
|
||||
|
||||
return FailureResult();
|
||||
}
|
||||
|
||||
byte[] HandleAddOrUpdateGroup(Dictionary<string, object> request)
|
||||
{
|
||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
||||
|
||||
ExtendedGroupRecord grec = GroupsDataUtils.GroupRecord(request);
|
||||
if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("OP"))
|
||||
NullResult(result, "Bad network data");
|
||||
|
||||
else
|
||||
{
|
||||
string RequestingAgentID = request["RequestingAgentID"].ToString();
|
||||
string reason = string.Empty;
|
||||
string op = request["OP"].ToString();
|
||||
if (op == "ADD")
|
||||
{
|
||||
grec.GroupID = m_GroupsService.CreateGroup(RequestingAgentID, grec.GroupName, grec.Charter, grec.ShowInList, grec.GroupPicture, grec.MembershipFee,
|
||||
grec.OpenEnrollment, grec.AllowPublish, grec.MaturePublish, grec.FounderID, out reason);
|
||||
|
||||
}
|
||||
else if (op == "UPDATE")
|
||||
{
|
||||
m_GroupsService.UpdateGroup(RequestingAgentID, grec.GroupID, grec.Charter, grec.ShowInList, grec.GroupPicture, grec.MembershipFee,
|
||||
grec.OpenEnrollment, grec.AllowPublish, grec.MaturePublish);
|
||||
|
||||
}
|
||||
|
||||
if (grec.GroupID != UUID.Zero)
|
||||
{
|
||||
grec = m_GroupsService.GetGroupRecord(RequestingAgentID, grec.GroupID);
|
||||
if (grec == null)
|
||||
NullResult(result, "Internal Error");
|
||||
else
|
||||
result["RESULT"] = GroupsDataUtils.GroupRecord(grec);
|
||||
}
|
||||
else
|
||||
NullResult(result, reason);
|
||||
}
|
||||
|
||||
string xmlString = ServerUtils.BuildXmlResponse(result);
|
||||
|
||||
//m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
|
||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
||||
}
|
||||
|
||||
byte[] HandleGetGroup(Dictionary<string, object> request)
|
||||
{
|
||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
||||
|
||||
if (!request.ContainsKey("RequestingAgentID"))
|
||||
NullResult(result, "Bad network data");
|
||||
else
|
||||
{
|
||||
string RequestingAgentID = request["RequestingAgentID"].ToString();
|
||||
ExtendedGroupRecord grec = null;
|
||||
if (request.ContainsKey("GroupID"))
|
||||
{
|
||||
UUID groupID = new UUID(request["GroupID"].ToString());
|
||||
grec = m_GroupsService.GetGroupRecord(RequestingAgentID, groupID);
|
||||
}
|
||||
else if (request.ContainsKey("Name"))
|
||||
{
|
||||
string name = request["Name"].ToString();
|
||||
grec = m_GroupsService.GetGroupRecord(RequestingAgentID, name);
|
||||
}
|
||||
|
||||
if (grec == null)
|
||||
NullResult(result, "Group not found");
|
||||
else
|
||||
result["RESULT"] = GroupsDataUtils.GroupRecord(grec);
|
||||
}
|
||||
|
||||
string xmlString = ServerUtils.BuildXmlResponse(result);
|
||||
|
||||
//m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
|
||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
||||
}
|
||||
|
||||
byte[] HandleAddAgentToGroup(Dictionary<string, object> request)
|
||||
{
|
||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
||||
|
||||
if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("AgentID") ||
|
||||
!request.ContainsKey("GroupID") || !request.ContainsKey("RoleID"))
|
||||
NullResult(result, "Bad network data");
|
||||
else
|
||||
{
|
||||
UUID groupID = new UUID(request["GroupID"].ToString());
|
||||
UUID roleID = new UUID(request["RoleID"].ToString());
|
||||
string agentID = request["AgentID"].ToString();
|
||||
string requestingAgentID = request["RequestingAgentID"].ToString();
|
||||
string token = string.Empty;
|
||||
string reason = string.Empty;
|
||||
|
||||
if (request.ContainsKey("AccessToken"))
|
||||
token = request["AccessToken"].ToString();
|
||||
|
||||
if (!m_GroupsService.AddAgentToGroup(requestingAgentID, agentID, groupID, roleID, token, out reason))
|
||||
NullResult(result, reason);
|
||||
else
|
||||
{
|
||||
GroupMembershipData membership = m_GroupsService.GetAgentGroupMembership(requestingAgentID, agentID, groupID);
|
||||
if (membership == null)
|
||||
NullResult(result, "Internal error");
|
||||
else
|
||||
result["RESULT"] = GroupsDataUtils.GroupMembershipData((ExtendedGroupMembershipData)membership);
|
||||
}
|
||||
}
|
||||
|
||||
string xmlString = ServerUtils.BuildXmlResponse(result);
|
||||
|
||||
//m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
|
||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
||||
}
|
||||
|
||||
byte[] HandleRemoveAgentFromGroup(Dictionary<string, object> request)
|
||||
{
|
||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
||||
|
||||
if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("AgentID") || !request.ContainsKey("GroupID"))
|
||||
NullResult(result, "Bad network data");
|
||||
else
|
||||
{
|
||||
UUID groupID = new UUID(request["GroupID"].ToString());
|
||||
string agentID = request["AgentID"].ToString();
|
||||
string requestingAgentID = request["RequestingAgentID"].ToString();
|
||||
|
||||
m_GroupsService.RemoveAgentFromGroup(requestingAgentID, agentID, groupID);
|
||||
}
|
||||
|
||||
//m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
|
||||
result["RESULT"] = "true";
|
||||
return Util.UTF8NoBomEncoding.GetBytes(ServerUtils.BuildXmlResponse(result));
|
||||
}
|
||||
|
||||
byte[] HandleGetMembership(Dictionary<string, object> request)
|
||||
{
|
||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
||||
|
||||
if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("AgentID"))
|
||||
NullResult(result, "Bad network data");
|
||||
else
|
||||
{
|
||||
string agentID = request["AgentID"].ToString();
|
||||
UUID groupID = UUID.Zero;
|
||||
if (request.ContainsKey("GroupID"))
|
||||
groupID = new UUID(request["GroupID"].ToString());
|
||||
string requestingAgentID = request["RequestingAgentID"].ToString();
|
||||
bool all = request.ContainsKey("ALL");
|
||||
|
||||
if (!all)
|
||||
{
|
||||
ExtendedGroupMembershipData membership = null;
|
||||
if (groupID == UUID.Zero)
|
||||
{
|
||||
membership = m_GroupsService.GetAgentActiveMembership(requestingAgentID, agentID);
|
||||
}
|
||||
else
|
||||
{
|
||||
membership = m_GroupsService.GetAgentGroupMembership(requestingAgentID, agentID, groupID);
|
||||
}
|
||||
|
||||
if (membership == null)
|
||||
NullResult(result, "No such membership");
|
||||
else
|
||||
result["RESULT"] = GroupsDataUtils.GroupMembershipData(membership);
|
||||
}
|
||||
else
|
||||
{
|
||||
List<GroupMembershipData> memberships = m_GroupsService.GetAgentGroupMemberships(requestingAgentID, agentID);
|
||||
if (memberships == null || (memberships != null && memberships.Count == 0))
|
||||
{
|
||||
NullResult(result, "No memberships");
|
||||
}
|
||||
else
|
||||
{
|
||||
Dictionary<string, object> dict = new Dictionary<string, object>();
|
||||
int i = 0;
|
||||
foreach (GroupMembershipData m in memberships)
|
||||
dict["m-" + i++] = GroupsDataUtils.GroupMembershipData((ExtendedGroupMembershipData)m);
|
||||
|
||||
result["RESULT"] = dict;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string xmlString = ServerUtils.BuildXmlResponse(result);
|
||||
|
||||
//m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
|
||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
||||
}
|
||||
|
||||
byte[] HandleGetGroupMembers(Dictionary<string, object> request)
|
||||
{
|
||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
||||
|
||||
if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("GroupID"))
|
||||
NullResult(result, "Bad network data");
|
||||
else
|
||||
{
|
||||
UUID groupID = new UUID(request["GroupID"].ToString());
|
||||
string requestingAgentID = request["RequestingAgentID"].ToString();
|
||||
|
||||
List<ExtendedGroupMembersData> members = m_GroupsService.GetGroupMembers(requestingAgentID, groupID);
|
||||
if (members == null || (members != null && members.Count == 0))
|
||||
{
|
||||
NullResult(result, "No members");
|
||||
}
|
||||
else
|
||||
{
|
||||
Dictionary<string, object> dict = new Dictionary<string, object>();
|
||||
int i = 0;
|
||||
foreach (ExtendedGroupMembersData m in members)
|
||||
{
|
||||
dict["m-" + i++] = GroupsDataUtils.GroupMembersData(m);
|
||||
}
|
||||
|
||||
result["RESULT"] = dict;
|
||||
}
|
||||
}
|
||||
|
||||
string xmlString = ServerUtils.BuildXmlResponse(result);
|
||||
|
||||
//m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
|
||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
||||
}
|
||||
|
||||
byte[] HandlePutRole(Dictionary<string, object> request)
|
||||
{
|
||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
||||
|
||||
if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("GroupID") || !request.ContainsKey("RoleID") ||
|
||||
!request.ContainsKey("Name") || !request.ContainsKey("Description") || !request.ContainsKey("Title") ||
|
||||
!request.ContainsKey("Powers") || !request.ContainsKey("OP"))
|
||||
NullResult(result, "Bad network data");
|
||||
|
||||
else
|
||||
{
|
||||
string op = request["OP"].ToString();
|
||||
string reason = string.Empty;
|
||||
|
||||
bool success = false;
|
||||
if (op == "ADD")
|
||||
success = m_GroupsService.AddGroupRole(request["RequestingAgentID"].ToString(), new UUID(request["GroupID"].ToString()),
|
||||
new UUID(request["RoleID"].ToString()), request["Name"].ToString(), request["Description"].ToString(),
|
||||
request["Title"].ToString(), UInt64.Parse(request["Powers"].ToString()), out reason);
|
||||
|
||||
else if (op == "UPDATE")
|
||||
success = m_GroupsService.UpdateGroupRole(request["RequestingAgentID"].ToString(), new UUID(request["GroupID"].ToString()),
|
||||
new UUID(request["RoleID"].ToString()), request["Name"].ToString(), request["Description"].ToString(),
|
||||
request["Title"].ToString(), UInt64.Parse(request["Powers"].ToString()));
|
||||
|
||||
result["RESULT"] = success.ToString();
|
||||
}
|
||||
|
||||
string xmlString = ServerUtils.BuildXmlResponse(result);
|
||||
|
||||
//m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
|
||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
||||
}
|
||||
|
||||
byte[] HandleRemoveRole(Dictionary<string, object> request)
|
||||
{
|
||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
||||
|
||||
if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("GroupID") || !request.ContainsKey("RoleID"))
|
||||
NullResult(result, "Bad network data");
|
||||
|
||||
else
|
||||
{
|
||||
m_GroupsService.RemoveGroupRole(request["RequestingAgentID"].ToString(), new UUID(request["GroupID"].ToString()),
|
||||
new UUID(request["RoleID"].ToString()));
|
||||
result["RESULT"] = "true";
|
||||
}
|
||||
|
||||
//m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
|
||||
return Util.UTF8NoBomEncoding.GetBytes(ServerUtils.BuildXmlResponse(result));
|
||||
}
|
||||
|
||||
byte[] HandleGetGroupRoles(Dictionary<string, object> request)
|
||||
{
|
||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
||||
|
||||
if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("GroupID"))
|
||||
NullResult(result, "Bad network data");
|
||||
else
|
||||
{
|
||||
UUID groupID = new UUID(request["GroupID"].ToString());
|
||||
string requestingAgentID = request["RequestingAgentID"].ToString();
|
||||
|
||||
List<GroupRolesData> roles = m_GroupsService.GetGroupRoles(requestingAgentID, groupID);
|
||||
if (roles == null || (roles != null && roles.Count == 0))
|
||||
{
|
||||
NullResult(result, "No members");
|
||||
}
|
||||
else
|
||||
{
|
||||
Dictionary<string, object> dict = new Dictionary<string, object>();
|
||||
int i = 0;
|
||||
foreach (GroupRolesData r in roles)
|
||||
dict["r-" + i++] = GroupsDataUtils.GroupRolesData(r);
|
||||
|
||||
result["RESULT"] = dict;
|
||||
}
|
||||
}
|
||||
|
||||
string xmlString = ServerUtils.BuildXmlResponse(result);
|
||||
|
||||
//m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
|
||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
||||
}
|
||||
|
||||
byte[] HandleGetRoleMembers(Dictionary<string, object> request)
|
||||
{
|
||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
||||
|
||||
if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("GroupID"))
|
||||
NullResult(result, "Bad network data");
|
||||
else
|
||||
{
|
||||
UUID groupID = new UUID(request["GroupID"].ToString());
|
||||
string requestingAgentID = request["RequestingAgentID"].ToString();
|
||||
|
||||
List<ExtendedGroupRoleMembersData> rmembers = m_GroupsService.GetGroupRoleMembers(requestingAgentID, groupID);
|
||||
if (rmembers == null || (rmembers != null && rmembers.Count == 0))
|
||||
{
|
||||
NullResult(result, "No members");
|
||||
}
|
||||
else
|
||||
{
|
||||
Dictionary<string, object> dict = new Dictionary<string, object>();
|
||||
int i = 0;
|
||||
foreach (ExtendedGroupRoleMembersData rm in rmembers)
|
||||
dict["rm-" + i++] = GroupsDataUtils.GroupRoleMembersData(rm);
|
||||
|
||||
result["RESULT"] = dict;
|
||||
}
|
||||
}
|
||||
|
||||
string xmlString = ServerUtils.BuildXmlResponse(result);
|
||||
|
||||
//m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
|
||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
||||
}
|
||||
|
||||
byte[] HandleAgentRole(Dictionary<string, object> request)
|
||||
{
|
||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
||||
|
||||
if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("GroupID") || !request.ContainsKey("RoleID") ||
|
||||
!request.ContainsKey("AgentID") || !request.ContainsKey("OP"))
|
||||
NullResult(result, "Bad network data");
|
||||
|
||||
else
|
||||
{
|
||||
string op = request["OP"].ToString();
|
||||
|
||||
bool success = false;
|
||||
if (op == "ADD")
|
||||
success = m_GroupsService.AddAgentToGroupRole(request["RequestingAgentID"].ToString(), request["AgentID"].ToString(),
|
||||
new UUID(request["GroupID"].ToString()), new UUID(request["RoleID"].ToString()));
|
||||
|
||||
else if (op == "DELETE")
|
||||
success = m_GroupsService.RemoveAgentFromGroupRole(request["RequestingAgentID"].ToString(), request["AgentID"].ToString(),
|
||||
new UUID(request["GroupID"].ToString()), new UUID(request["RoleID"].ToString()));
|
||||
|
||||
result["RESULT"] = success.ToString();
|
||||
}
|
||||
|
||||
string xmlString = ServerUtils.BuildXmlResponse(result);
|
||||
|
||||
//m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
|
||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
||||
}
|
||||
|
||||
byte[] HandleGetAgentRoles(Dictionary<string, object> request)
|
||||
{
|
||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
||||
|
||||
if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("GroupID") || !request.ContainsKey("AgentID"))
|
||||
NullResult(result, "Bad network data");
|
||||
else
|
||||
{
|
||||
UUID groupID = new UUID(request["GroupID"].ToString());
|
||||
string agentID = request["AgentID"].ToString();
|
||||
string requestingAgentID = request["RequestingAgentID"].ToString();
|
||||
|
||||
List<GroupRolesData> roles = m_GroupsService.GetAgentGroupRoles(requestingAgentID, agentID, groupID);
|
||||
if (roles == null || (roles != null && roles.Count == 0))
|
||||
{
|
||||
NullResult(result, "No members");
|
||||
}
|
||||
else
|
||||
{
|
||||
Dictionary<string, object> dict = new Dictionary<string, object>();
|
||||
int i = 0;
|
||||
foreach (GroupRolesData r in roles)
|
||||
dict["r-" + i++] = GroupsDataUtils.GroupRolesData(r);
|
||||
|
||||
result["RESULT"] = dict;
|
||||
}
|
||||
}
|
||||
|
||||
string xmlString = ServerUtils.BuildXmlResponse(result);
|
||||
|
||||
//m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
|
||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
||||
}
|
||||
|
||||
byte[] HandleSetActive(Dictionary<string, object> request)
|
||||
{
|
||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
||||
|
||||
if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("GroupID") ||
|
||||
!request.ContainsKey("AgentID") || !request.ContainsKey("OP"))
|
||||
{
|
||||
NullResult(result, "Bad network data");
|
||||
string xmlString = ServerUtils.BuildXmlResponse(result);
|
||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
||||
}
|
||||
else
|
||||
{
|
||||
string op = request["OP"].ToString();
|
||||
|
||||
if (op == "GROUP")
|
||||
{
|
||||
ExtendedGroupMembershipData group = m_GroupsService.SetAgentActiveGroup(request["RequestingAgentID"].ToString(),
|
||||
request["AgentID"].ToString(), new UUID(request["GroupID"].ToString()));
|
||||
|
||||
if (group == null)
|
||||
NullResult(result, "Internal error");
|
||||
else
|
||||
result["RESULT"] = GroupsDataUtils.GroupMembershipData(group);
|
||||
|
||||
string xmlString = ServerUtils.BuildXmlResponse(result);
|
||||
|
||||
//m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
|
||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
||||
|
||||
}
|
||||
else if (op == "ROLE" && request.ContainsKey("RoleID"))
|
||||
{
|
||||
m_GroupsService.SetAgentActiveGroupRole(request["RequestingAgentID"].ToString(), request["AgentID"].ToString(),
|
||||
new UUID(request["GroupID"].ToString()), new UUID(request["RoleID"].ToString()));
|
||||
result["RESULT"] = "true";
|
||||
}
|
||||
|
||||
return Util.UTF8NoBomEncoding.GetBytes(ServerUtils.BuildXmlResponse(result));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
byte[] HandleUpdateMembership(Dictionary<string, object> request)
|
||||
{
|
||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
||||
|
||||
if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("AgentID") || !request.ContainsKey("GroupID") ||
|
||||
!request.ContainsKey("AcceptNotices") || !request.ContainsKey("ListInProfile"))
|
||||
NullResult(result, "Bad network data");
|
||||
|
||||
else
|
||||
{
|
||||
m_GroupsService.UpdateMembership(request["RequestingAgentID"].ToString(), request["AgentID"].ToString(), new UUID(request["GroupID"].ToString()),
|
||||
bool.Parse(request["AcceptNotices"].ToString()), bool.Parse(request["ListInProfile"].ToString()));
|
||||
|
||||
result["RESULT"] = "true";
|
||||
}
|
||||
|
||||
//m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
|
||||
return Util.UTF8NoBomEncoding.GetBytes(ServerUtils.BuildXmlResponse(result));
|
||||
}
|
||||
|
||||
byte[] HandleInvite(Dictionary<string, object> request)
|
||||
{
|
||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
||||
|
||||
if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("InviteID"))
|
||||
{
|
||||
NullResult(result, "Bad network data");
|
||||
string xmlString = ServerUtils.BuildXmlResponse(result);
|
||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
||||
}
|
||||
else
|
||||
{
|
||||
string op = request["OP"].ToString();
|
||||
|
||||
if (op == "ADD" && request.ContainsKey("GroupID") && request.ContainsKey("RoleID") && request.ContainsKey("AgentID"))
|
||||
{
|
||||
bool success = m_GroupsService.AddAgentToGroupInvite(request["RequestingAgentID"].ToString(),
|
||||
new UUID(request["InviteID"].ToString()), new UUID(request["GroupID"].ToString()),
|
||||
new UUID(request["RoleID"].ToString()), request["AgentID"].ToString());
|
||||
|
||||
result["RESULT"] = success.ToString();
|
||||
return Util.UTF8NoBomEncoding.GetBytes(ServerUtils.BuildXmlResponse(result));
|
||||
|
||||
}
|
||||
else if (op == "DELETE")
|
||||
{
|
||||
m_GroupsService.RemoveAgentToGroupInvite(request["RequestingAgentID"].ToString(), new UUID(request["InviteID"].ToString()));
|
||||
result["RESULT"] = "true";
|
||||
return Util.UTF8NoBomEncoding.GetBytes(ServerUtils.BuildXmlResponse(result));
|
||||
}
|
||||
else if (op == "GET")
|
||||
{
|
||||
GroupInviteInfo invite = m_GroupsService.GetAgentToGroupInvite(request["RequestingAgentID"].ToString(),
|
||||
new UUID(request["InviteID"].ToString()));
|
||||
|
||||
result["RESULT"] = GroupsDataUtils.GroupInviteInfo(invite);
|
||||
return Util.UTF8NoBomEncoding.GetBytes(ServerUtils.BuildXmlResponse(result));
|
||||
}
|
||||
|
||||
NullResult(result, "Bad OP in request");
|
||||
return Util.UTF8NoBomEncoding.GetBytes(ServerUtils.BuildXmlResponse(result));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
byte[] HandleAddNotice(Dictionary<string, object> request)
|
||||
{
|
||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
||||
|
||||
if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("GroupID") || !request.ContainsKey("NoticeID") ||
|
||||
!request.ContainsKey("FromName") || !request.ContainsKey("Subject") || !request.ContainsKey("Message") ||
|
||||
!request.ContainsKey("HasAttachment"))
|
||||
NullResult(result, "Bad network data");
|
||||
|
||||
else
|
||||
{
|
||||
|
||||
bool hasAtt = bool.Parse(request["HasAttachment"].ToString());
|
||||
byte attType = 0;
|
||||
string attName = string.Empty;
|
||||
string attOwner = string.Empty;
|
||||
UUID attItem = UUID.Zero;
|
||||
if (request.ContainsKey("AttachmentType"))
|
||||
attType = byte.Parse(request["AttachmentType"].ToString());
|
||||
if (request.ContainsKey("AttachmentName"))
|
||||
attName = request["AttachmentName"].ToString();
|
||||
if (request.ContainsKey("AttachmentItemID"))
|
||||
attItem = new UUID(request["AttachmentItemID"].ToString());
|
||||
if (request.ContainsKey("AttachmentOwnerID"))
|
||||
attOwner = request["AttachmentOwnerID"].ToString();
|
||||
|
||||
bool success = m_GroupsService.AddGroupNotice(request["RequestingAgentID"].ToString(), new UUID(request["GroupID"].ToString()),
|
||||
new UUID(request["NoticeID"].ToString()), request["FromName"].ToString(), request["Subject"].ToString(),
|
||||
request["Message"].ToString(), hasAtt, attType, attName, attItem, attOwner);
|
||||
|
||||
result["RESULT"] = success.ToString();
|
||||
}
|
||||
|
||||
string xmlString = ServerUtils.BuildXmlResponse(result);
|
||||
|
||||
//m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
|
||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
||||
}
|
||||
|
||||
byte[] HandleGetNotices(Dictionary<string, object> request)
|
||||
{
|
||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
||||
|
||||
if (!request.ContainsKey("RequestingAgentID"))
|
||||
NullResult(result, "Bad network data");
|
||||
|
||||
else if (request.ContainsKey("NoticeID")) // just one
|
||||
{
|
||||
GroupNoticeInfo notice = m_GroupsService.GetGroupNotice(request["RequestingAgentID"].ToString(), new UUID(request["NoticeID"].ToString()));
|
||||
|
||||
if (notice == null)
|
||||
NullResult(result, "NO such notice");
|
||||
else
|
||||
result["RESULT"] = GroupsDataUtils.GroupNoticeInfo(notice);
|
||||
|
||||
}
|
||||
else if (request.ContainsKey("GroupID")) // all notices for group
|
||||
{
|
||||
List<ExtendedGroupNoticeData> notices = m_GroupsService.GetGroupNotices(request["RequestingAgentID"].ToString(), new UUID(request["GroupID"].ToString()));
|
||||
|
||||
if (notices == null || (notices != null && notices.Count == 0))
|
||||
NullResult(result, "No notices");
|
||||
else
|
||||
{
|
||||
Dictionary<string, object> dict = new Dictionary<string, object>();
|
||||
int i = 0;
|
||||
foreach (ExtendedGroupNoticeData n in notices)
|
||||
dict["n-" + i++] = GroupsDataUtils.GroupNoticeData(n);
|
||||
|
||||
result["RESULT"] = dict;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
NullResult(result, "Bad OP in request");
|
||||
|
||||
string xmlString = ServerUtils.BuildXmlResponse(result);
|
||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
||||
}
|
||||
|
||||
byte[] HandleFindGroups(Dictionary<string, object> request)
|
||||
{
|
||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
||||
|
||||
if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("Query"))
|
||||
NullResult(result, "Bad network data");
|
||||
|
||||
List<DirGroupsReplyData> hits = m_GroupsService.FindGroups(request["RequestingAgentID"].ToString(), request["Query"].ToString());
|
||||
|
||||
if (hits == null || (hits != null && hits.Count == 0))
|
||||
NullResult(result, "No hits");
|
||||
else
|
||||
{
|
||||
Dictionary<string, object> dict = new Dictionary<string, object>();
|
||||
int i = 0;
|
||||
foreach (DirGroupsReplyData n in hits)
|
||||
dict["n-" + i++] = GroupsDataUtils.DirGroupsReplyData(n);
|
||||
|
||||
result["RESULT"] = dict;
|
||||
}
|
||||
|
||||
|
||||
string xmlString = ServerUtils.BuildXmlResponse(result);
|
||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
||||
}
|
||||
|
||||
|
||||
#region Helpers
|
||||
|
||||
private void NullResult(Dictionary<string, object> result, string reason)
|
||||
{
|
||||
result["RESULT"] = "NULL";
|
||||
result["REASON"] = reason;
|
||||
}
|
||||
|
||||
private byte[] FailureResult()
|
||||
{
|
||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
||||
NullResult(result, "Unknown method");
|
||||
string xmlString = ServerUtils.BuildXmlResponse(result);
|
||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,828 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace OpenSim.Groups
|
||||
{
|
||||
public delegate ExtendedGroupRecord GroupRecordDelegate();
|
||||
public delegate GroupMembershipData GroupMembershipDelegate();
|
||||
public delegate List<GroupMembershipData> GroupMembershipListDelegate();
|
||||
public delegate List<ExtendedGroupMembersData> GroupMembersListDelegate();
|
||||
public delegate List<GroupRolesData> GroupRolesListDelegate();
|
||||
public delegate List<ExtendedGroupRoleMembersData> RoleMembersListDelegate();
|
||||
public delegate GroupNoticeInfo NoticeDelegate();
|
||||
public delegate List<ExtendedGroupNoticeData> NoticeListDelegate();
|
||||
public delegate void VoidDelegate();
|
||||
public delegate bool BooleanDelegate();
|
||||
|
||||
public class RemoteConnectorCacheWrapper
|
||||
{
|
||||
private ForeignImporter m_ForeignImporter;
|
||||
|
||||
private Dictionary<string, bool> m_ActiveRequests = new Dictionary<string, bool>();
|
||||
private const int GROUPS_CACHE_TIMEOUT = 1 * 60; // 1 minutes
|
||||
|
||||
// This all important cache cahces objects of different types:
|
||||
// group-<GroupID> or group-<Name> => ExtendedGroupRecord
|
||||
// active-<AgentID> => GroupMembershipData
|
||||
// membership-<AgentID>-<GroupID> => GroupMembershipData
|
||||
// memberships-<AgentID> => List<GroupMembershipData>
|
||||
// members-<RequestingAgentID>-<GroupID> => List<ExtendedGroupMembersData>
|
||||
// role-<RoleID> => GroupRolesData
|
||||
// roles-<GroupID> => List<GroupRolesData> ; all roles in the group
|
||||
// roles-<GroupID>-<AgentID> => List<GroupRolesData> ; roles that the agent has
|
||||
// rolemembers-<RequestingAgentID>-<GroupID> => List<ExtendedGroupRoleMembersData>
|
||||
// notice-<noticeID> => GroupNoticeInfo
|
||||
// notices-<GroupID> => List<ExtendedGroupNoticeData>
|
||||
private ExpiringCache<string, object> m_Cache = new ExpiringCache<string, object>();
|
||||
|
||||
public RemoteConnectorCacheWrapper(IUserManagement uman)
|
||||
{
|
||||
m_ForeignImporter = new ForeignImporter(uman);
|
||||
}
|
||||
|
||||
public UUID CreateGroup(UUID RequestingAgentID, GroupRecordDelegate d)
|
||||
{
|
||||
//m_log.DebugFormat("[Groups.RemoteConnector]: Creating group {0}", name);
|
||||
//reason = string.Empty;
|
||||
|
||||
//ExtendedGroupRecord group = m_GroupsService.CreateGroup(RequestingAgentID.ToString(), name, charter, showInList, insigniaID,
|
||||
// membershipFee, openEnrollment, allowPublish, maturePublish, founderID, out reason);
|
||||
ExtendedGroupRecord group = d();
|
||||
|
||||
if (group == null)
|
||||
return UUID.Zero;
|
||||
|
||||
if (group.GroupID != UUID.Zero)
|
||||
lock (m_Cache)
|
||||
{
|
||||
m_Cache.Add("group-" + group.GroupID.ToString(), group, GROUPS_CACHE_TIMEOUT);
|
||||
if (m_Cache.Contains("memberships-" + RequestingAgentID.ToString()))
|
||||
m_Cache.Remove("memberships-" + RequestingAgentID.ToString());
|
||||
}
|
||||
|
||||
return group.GroupID;
|
||||
}
|
||||
|
||||
public bool UpdateGroup(UUID groupID, GroupRecordDelegate d)
|
||||
{
|
||||
//reason = string.Empty;
|
||||
//ExtendedGroupRecord group = m_GroupsService.UpdateGroup(RequestingAgentID, groupID, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish);
|
||||
ExtendedGroupRecord group = d();
|
||||
|
||||
if (group != null && group.GroupID != UUID.Zero)
|
||||
lock (m_Cache)
|
||||
m_Cache.AddOrUpdate("group-" + group.GroupID.ToString(), group, GROUPS_CACHE_TIMEOUT);
|
||||
return true;
|
||||
}
|
||||
|
||||
public ExtendedGroupRecord GetGroupRecord(string RequestingAgentID, UUID GroupID, string GroupName, GroupRecordDelegate d)
|
||||
{
|
||||
//if (GroupID == UUID.Zero && (GroupName == null || GroupName != null && GroupName == string.Empty))
|
||||
// return null;
|
||||
|
||||
object group = null;
|
||||
bool firstCall = false;
|
||||
string cacheKey = "group-";
|
||||
if (GroupID != UUID.Zero)
|
||||
cacheKey += GroupID.ToString();
|
||||
else
|
||||
cacheKey += GroupName;
|
||||
|
||||
//m_log.DebugFormat("[XXX]: GetGroupRecord {0}", cacheKey);
|
||||
|
||||
while (true)
|
||||
{
|
||||
lock (m_Cache)
|
||||
{
|
||||
if (m_Cache.TryGetValue(cacheKey, out group))
|
||||
{
|
||||
//m_log.DebugFormat("[XXX]: GetGroupRecord {0} cached!", cacheKey);
|
||||
return (ExtendedGroupRecord)group;
|
||||
}
|
||||
|
||||
// not cached
|
||||
if (!m_ActiveRequests.ContainsKey(cacheKey))
|
||||
{
|
||||
m_ActiveRequests.Add(cacheKey, true);
|
||||
firstCall = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (firstCall)
|
||||
{
|
||||
//group = m_GroupsService.GetGroupRecord(RequestingAgentID, GroupID, GroupName);
|
||||
group = d();
|
||||
|
||||
lock (m_Cache)
|
||||
{
|
||||
m_Cache.AddOrUpdate(cacheKey, group, GROUPS_CACHE_TIMEOUT);
|
||||
m_ActiveRequests.Remove(cacheKey);
|
||||
return (ExtendedGroupRecord)group;
|
||||
}
|
||||
}
|
||||
else
|
||||
Thread.Sleep(50);
|
||||
}
|
||||
}
|
||||
|
||||
public bool AddAgentToGroup(string RequestingAgentID, string AgentID, UUID GroupID, GroupMembershipDelegate d)
|
||||
{
|
||||
GroupMembershipData membership = d();
|
||||
if (membership == null)
|
||||
return false;
|
||||
|
||||
lock (m_Cache)
|
||||
{
|
||||
// first, remove everything! add a user is a heavy-duty op
|
||||
m_Cache.Clear();
|
||||
|
||||
m_Cache.AddOrUpdate("active-" + AgentID.ToString(), membership, GROUPS_CACHE_TIMEOUT);
|
||||
m_Cache.AddOrUpdate("membership-" + AgentID.ToString() + "-" + GroupID.ToString(), membership, GROUPS_CACHE_TIMEOUT);
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void RemoveAgentFromGroup(string RequestingAgentID, string AgentID, UUID GroupID, VoidDelegate d)
|
||||
{
|
||||
d();
|
||||
|
||||
lock (m_Cache)
|
||||
{
|
||||
string cacheKey = "active-" + AgentID.ToString();
|
||||
if (m_Cache.Contains(cacheKey))
|
||||
m_Cache.Remove(cacheKey);
|
||||
|
||||
cacheKey = "memberships-" + AgentID.ToString();
|
||||
if (m_Cache.Contains(cacheKey))
|
||||
m_Cache.Remove(cacheKey);
|
||||
|
||||
cacheKey = "membership-" + AgentID.ToString() + "-" + GroupID.ToString();
|
||||
if (m_Cache.Contains(cacheKey))
|
||||
m_Cache.Remove(cacheKey);
|
||||
|
||||
cacheKey = "members-" + RequestingAgentID.ToString() + "-" + GroupID.ToString();
|
||||
if (m_Cache.Contains(cacheKey))
|
||||
m_Cache.Remove(cacheKey);
|
||||
|
||||
cacheKey = "roles-" + "-" + GroupID.ToString() + "-" + AgentID.ToString();
|
||||
if (m_Cache.Contains(cacheKey))
|
||||
m_Cache.Remove(cacheKey);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetAgentActiveGroup(string AgentID, GroupMembershipDelegate d)
|
||||
{
|
||||
GroupMembershipData activeGroup = d();
|
||||
string cacheKey = "active-" + AgentID.ToString();
|
||||
lock (m_Cache)
|
||||
if (m_Cache.Contains(cacheKey))
|
||||
m_Cache.AddOrUpdate(cacheKey, activeGroup, GROUPS_CACHE_TIMEOUT);
|
||||
}
|
||||
|
||||
public ExtendedGroupMembershipData GetAgentActiveMembership(string AgentID, GroupMembershipDelegate d)
|
||||
{
|
||||
object membership = null;
|
||||
bool firstCall = false;
|
||||
string cacheKey = "active-" + AgentID.ToString();
|
||||
|
||||
//m_log.DebugFormat("[XXX]: GetAgentActiveMembership {0}", cacheKey);
|
||||
|
||||
while (true)
|
||||
{
|
||||
lock (m_Cache)
|
||||
{
|
||||
if (m_Cache.TryGetValue(cacheKey, out membership))
|
||||
{
|
||||
//m_log.DebugFormat("[XXX]: GetAgentActiveMembership {0} cached!", cacheKey);
|
||||
return (ExtendedGroupMembershipData)membership;
|
||||
}
|
||||
|
||||
// not cached
|
||||
if (!m_ActiveRequests.ContainsKey(cacheKey))
|
||||
{
|
||||
m_ActiveRequests.Add(cacheKey, true);
|
||||
firstCall = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (firstCall)
|
||||
{
|
||||
membership = d();
|
||||
|
||||
lock (m_Cache)
|
||||
{
|
||||
m_Cache.AddOrUpdate(cacheKey, membership, GROUPS_CACHE_TIMEOUT);
|
||||
m_ActiveRequests.Remove(cacheKey);
|
||||
return (ExtendedGroupMembershipData)membership;
|
||||
}
|
||||
}
|
||||
else
|
||||
Thread.Sleep(50);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public ExtendedGroupMembershipData GetAgentGroupMembership(string AgentID, UUID GroupID, GroupMembershipDelegate d)
|
||||
{
|
||||
object membership = null;
|
||||
bool firstCall = false;
|
||||
string cacheKey = "membership-" + AgentID.ToString() + "-" + GroupID.ToString();
|
||||
|
||||
//m_log.DebugFormat("[XXX]: GetAgentGroupMembership {0}", cacheKey);
|
||||
|
||||
while (true)
|
||||
{
|
||||
lock (m_Cache)
|
||||
{
|
||||
if (m_Cache.TryGetValue(cacheKey, out membership))
|
||||
{
|
||||
//m_log.DebugFormat("[XXX]: GetAgentGroupMembership {0}", cacheKey);
|
||||
return (ExtendedGroupMembershipData)membership;
|
||||
}
|
||||
|
||||
// not cached
|
||||
if (!m_ActiveRequests.ContainsKey(cacheKey))
|
||||
{
|
||||
m_ActiveRequests.Add(cacheKey, true);
|
||||
firstCall = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (firstCall)
|
||||
{
|
||||
membership = d();
|
||||
lock (m_Cache)
|
||||
{
|
||||
m_Cache.AddOrUpdate(cacheKey, membership, GROUPS_CACHE_TIMEOUT);
|
||||
m_ActiveRequests.Remove(cacheKey);
|
||||
return (ExtendedGroupMembershipData)membership;
|
||||
}
|
||||
}
|
||||
else
|
||||
Thread.Sleep(50);
|
||||
}
|
||||
}
|
||||
|
||||
public List<GroupMembershipData> GetAgentGroupMemberships(string AgentID, GroupMembershipListDelegate d)
|
||||
{
|
||||
object memberships = null;
|
||||
bool firstCall = false;
|
||||
string cacheKey = "memberships-" + AgentID.ToString();
|
||||
|
||||
//m_log.DebugFormat("[XXX]: GetAgentGroupMemberships {0}", cacheKey);
|
||||
|
||||
while (true)
|
||||
{
|
||||
lock (m_Cache)
|
||||
{
|
||||
if (m_Cache.TryGetValue(cacheKey, out memberships))
|
||||
{
|
||||
//m_log.DebugFormat("[XXX]: GetAgentGroupMemberships {0} cached!", cacheKey);
|
||||
return (List<GroupMembershipData>)memberships;
|
||||
}
|
||||
|
||||
// not cached
|
||||
if (!m_ActiveRequests.ContainsKey(cacheKey))
|
||||
{
|
||||
m_ActiveRequests.Add(cacheKey, true);
|
||||
firstCall = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (firstCall)
|
||||
{
|
||||
memberships = d();
|
||||
lock (m_Cache)
|
||||
{
|
||||
m_Cache.AddOrUpdate(cacheKey, memberships, GROUPS_CACHE_TIMEOUT);
|
||||
m_ActiveRequests.Remove(cacheKey);
|
||||
return (List<GroupMembershipData>)memberships;
|
||||
}
|
||||
}
|
||||
else
|
||||
Thread.Sleep(50);
|
||||
}
|
||||
}
|
||||
|
||||
public List<GroupMembersData> GetGroupMembers(string RequestingAgentID, UUID GroupID, GroupMembersListDelegate d)
|
||||
{
|
||||
object members = null;
|
||||
bool firstCall = false;
|
||||
// we need to key in also on the requester, because different ppl have different view privileges
|
||||
string cacheKey = "members-" + RequestingAgentID.ToString() + "-" + GroupID.ToString();
|
||||
|
||||
//m_log.DebugFormat("[XXX]: GetGroupMembers {0}", cacheKey);
|
||||
|
||||
while (true)
|
||||
{
|
||||
lock (m_Cache)
|
||||
{
|
||||
if (m_Cache.TryGetValue(cacheKey, out members))
|
||||
{
|
||||
List<ExtendedGroupMembersData> xx = (List<ExtendedGroupMembersData>)members;
|
||||
return xx.ConvertAll<GroupMembersData>(new Converter<ExtendedGroupMembersData, GroupMembersData>(m_ForeignImporter.ConvertGroupMembersData));
|
||||
}
|
||||
|
||||
// not cached
|
||||
if (!m_ActiveRequests.ContainsKey(cacheKey))
|
||||
{
|
||||
m_ActiveRequests.Add(cacheKey, true);
|
||||
firstCall = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (firstCall)
|
||||
{
|
||||
List<ExtendedGroupMembersData> _members = d();
|
||||
|
||||
if (_members != null && _members.Count > 0)
|
||||
members = _members.ConvertAll<GroupMembersData>(new Converter<ExtendedGroupMembersData, GroupMembersData>(m_ForeignImporter.ConvertGroupMembersData));
|
||||
else
|
||||
members = new List<GroupMembersData>();
|
||||
|
||||
lock (m_Cache)
|
||||
{
|
||||
//m_Cache.AddOrUpdate(cacheKey, members, GROUPS_CACHE_TIMEOUT);
|
||||
m_Cache.AddOrUpdate(cacheKey, _members, GROUPS_CACHE_TIMEOUT);
|
||||
m_ActiveRequests.Remove(cacheKey);
|
||||
|
||||
return (List<GroupMembersData>)members;
|
||||
}
|
||||
}
|
||||
else
|
||||
Thread.Sleep(50);
|
||||
}
|
||||
}
|
||||
|
||||
public bool AddGroupRole(UUID groupID, UUID roleID, string description, string name, ulong powers, string title, BooleanDelegate d)
|
||||
{
|
||||
if (d())
|
||||
{
|
||||
GroupRolesData role = new GroupRolesData();
|
||||
role.Description = description;
|
||||
role.Members = 0;
|
||||
role.Name = name;
|
||||
role.Powers = powers;
|
||||
role.RoleID = roleID;
|
||||
role.Title = title;
|
||||
|
||||
lock (m_Cache)
|
||||
{
|
||||
m_Cache.AddOrUpdate("role-" + roleID.ToString(), role, GROUPS_CACHE_TIMEOUT);
|
||||
|
||||
// also remove this list
|
||||
if (m_Cache.Contains("roles-" + groupID.ToString()))
|
||||
m_Cache.Remove("roles-" + groupID.ToString());
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool UpdateGroupRole(UUID groupID, UUID roleID, string name, string description, string title, ulong powers, BooleanDelegate d)
|
||||
{
|
||||
if (d())
|
||||
{
|
||||
object role;
|
||||
lock (m_Cache)
|
||||
if (m_Cache.TryGetValue("role-" + roleID.ToString(), out role))
|
||||
{
|
||||
GroupRolesData r = (GroupRolesData)role;
|
||||
r.Description = description;
|
||||
r.Name = name;
|
||||
r.Powers = powers;
|
||||
r.Title = title;
|
||||
|
||||
m_Cache.Update("role-" + roleID.ToString(), r, GROUPS_CACHE_TIMEOUT);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
lock (m_Cache)
|
||||
{
|
||||
if (m_Cache.Contains("role-" + roleID.ToString()))
|
||||
m_Cache.Remove("role-" + roleID.ToString());
|
||||
|
||||
// also remove these lists, because they will have an outdated role
|
||||
if (m_Cache.Contains("roles-" + groupID.ToString()))
|
||||
m_Cache.Remove("roles-" + groupID.ToString());
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveGroupRole(string RequestingAgentID, UUID groupID, UUID roleID, VoidDelegate d)
|
||||
{
|
||||
d();
|
||||
|
||||
lock (m_Cache)
|
||||
{
|
||||
if (m_Cache.Contains("role-" + roleID.ToString()))
|
||||
m_Cache.Remove("role-" + roleID.ToString());
|
||||
|
||||
// also remove the list, because it will have an removed role
|
||||
if (m_Cache.Contains("roles-" + groupID.ToString()))
|
||||
m_Cache.Remove("roles-" + groupID.ToString());
|
||||
|
||||
if (m_Cache.Contains("roles-" + groupID.ToString() + "-" + RequestingAgentID.ToString()))
|
||||
m_Cache.Remove("roles-" + groupID.ToString() + "-" + RequestingAgentID.ToString());
|
||||
|
||||
if (m_Cache.Contains("rolemembers-" + RequestingAgentID.ToString() + "-" + groupID.ToString()))
|
||||
m_Cache.Remove("rolemembers-" + RequestingAgentID.ToString() + "-" + groupID.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public List<GroupRolesData> GetGroupRoles(string RequestingAgentID, UUID GroupID, GroupRolesListDelegate d)
|
||||
{
|
||||
object roles = null;
|
||||
bool firstCall = false;
|
||||
string cacheKey = "roles-" + GroupID.ToString();
|
||||
|
||||
while (true)
|
||||
{
|
||||
lock (m_Cache)
|
||||
{
|
||||
if (m_Cache.TryGetValue(cacheKey, out roles))
|
||||
return (List<GroupRolesData>)roles;
|
||||
|
||||
// not cached
|
||||
if (!m_ActiveRequests.ContainsKey(cacheKey))
|
||||
{
|
||||
m_ActiveRequests.Add(cacheKey, true);
|
||||
firstCall = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (firstCall)
|
||||
{
|
||||
roles = d();
|
||||
if (roles != null)
|
||||
{
|
||||
lock (m_Cache)
|
||||
{
|
||||
m_Cache.AddOrUpdate(cacheKey, roles, GROUPS_CACHE_TIMEOUT);
|
||||
m_ActiveRequests.Remove(cacheKey);
|
||||
return (List<GroupRolesData>)roles;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
Thread.Sleep(50);
|
||||
}
|
||||
}
|
||||
|
||||
public List<GroupRoleMembersData> GetGroupRoleMembers(string RequestingAgentID, UUID GroupID, RoleMembersListDelegate d)
|
||||
{
|
||||
object rmembers = null;
|
||||
bool firstCall = false;
|
||||
// we need to key in also on the requester, because different ppl have different view privileges
|
||||
string cacheKey = "rolemembers-" + RequestingAgentID.ToString() + "-" + GroupID.ToString();
|
||||
|
||||
//m_log.DebugFormat("[XXX]: GetGroupRoleMembers {0}", cacheKey);
|
||||
while (true)
|
||||
{
|
||||
lock (m_Cache)
|
||||
{
|
||||
if (m_Cache.TryGetValue(cacheKey, out rmembers))
|
||||
{
|
||||
List<ExtendedGroupRoleMembersData> xx = (List<ExtendedGroupRoleMembersData>)rmembers;
|
||||
return xx.ConvertAll<GroupRoleMembersData>(m_ForeignImporter.ConvertGroupRoleMembersData);
|
||||
}
|
||||
|
||||
// not cached
|
||||
if (!m_ActiveRequests.ContainsKey(cacheKey))
|
||||
{
|
||||
m_ActiveRequests.Add(cacheKey, true);
|
||||
firstCall = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (firstCall)
|
||||
{
|
||||
List<ExtendedGroupRoleMembersData> _rmembers = d();
|
||||
|
||||
if (_rmembers != null && _rmembers.Count > 0)
|
||||
rmembers = _rmembers.ConvertAll<GroupRoleMembersData>(new Converter<ExtendedGroupRoleMembersData, GroupRoleMembersData>(m_ForeignImporter.ConvertGroupRoleMembersData));
|
||||
else
|
||||
rmembers = new List<GroupRoleMembersData>();
|
||||
|
||||
lock (m_Cache)
|
||||
{
|
||||
// For some strange reason, when I cache the list of GroupRoleMembersData,
|
||||
// it gets emptied out. The TryGet gets an empty list...
|
||||
//m_Cache.AddOrUpdate(cacheKey, rmembers, GROUPS_CACHE_TIMEOUT);
|
||||
// Caching the list of ExtendedGroupRoleMembersData doesn't show that issue
|
||||
// I don't get it.
|
||||
m_Cache.AddOrUpdate(cacheKey, _rmembers, GROUPS_CACHE_TIMEOUT);
|
||||
m_ActiveRequests.Remove(cacheKey);
|
||||
return (List<GroupRoleMembersData>)rmembers;
|
||||
}
|
||||
}
|
||||
else
|
||||
Thread.Sleep(50);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddAgentToGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID, BooleanDelegate d)
|
||||
{
|
||||
if (d())
|
||||
{
|
||||
lock (m_Cache)
|
||||
{
|
||||
// update the cached role
|
||||
string cacheKey = "role-" + RoleID.ToString();
|
||||
object obj;
|
||||
if (m_Cache.TryGetValue(cacheKey, out obj))
|
||||
{
|
||||
GroupRolesData r = (GroupRolesData)obj;
|
||||
r.Members++;
|
||||
}
|
||||
|
||||
// add this agent to the list of role members
|
||||
cacheKey = "rolemembers-" + RequestingAgentID.ToString() + "-" + GroupID.ToString();
|
||||
if (m_Cache.TryGetValue(cacheKey, out obj))
|
||||
{
|
||||
try
|
||||
{
|
||||
// This may throw an exception, in which case the agentID is not a UUID but a full ID
|
||||
// In that case, let's just remove the whoe things from the cache
|
||||
UUID id = new UUID(AgentID);
|
||||
List<ExtendedGroupRoleMembersData> xx = (List<ExtendedGroupRoleMembersData>)obj;
|
||||
List<GroupRoleMembersData> rmlist = xx.ConvertAll<GroupRoleMembersData>(m_ForeignImporter.ConvertGroupRoleMembersData);
|
||||
GroupRoleMembersData rm = new GroupRoleMembersData();
|
||||
rm.MemberID = id;
|
||||
rm.RoleID = RoleID;
|
||||
rmlist.Add(rm);
|
||||
}
|
||||
catch
|
||||
{
|
||||
m_Cache.Remove(cacheKey);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove the cached info about this agent's roles
|
||||
// because we don't have enough local info about the new role
|
||||
cacheKey = "roles-" + GroupID.ToString() + "-" + AgentID.ToString();
|
||||
if (m_Cache.Contains(cacheKey))
|
||||
m_Cache.Remove(cacheKey);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveAgentFromGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID, BooleanDelegate d)
|
||||
{
|
||||
if (d())
|
||||
{
|
||||
lock (m_Cache)
|
||||
{
|
||||
// update the cached role
|
||||
string cacheKey = "role-" + RoleID.ToString();
|
||||
object obj;
|
||||
if (m_Cache.TryGetValue(cacheKey, out obj))
|
||||
{
|
||||
GroupRolesData r = (GroupRolesData)obj;
|
||||
r.Members--;
|
||||
}
|
||||
|
||||
cacheKey = "roles-" + GroupID.ToString() + "-" + AgentID.ToString();
|
||||
if (m_Cache.Contains(cacheKey))
|
||||
m_Cache.Remove(cacheKey);
|
||||
|
||||
cacheKey = "rolemembers-" + RequestingAgentID.ToString() + "-" + GroupID.ToString();
|
||||
if (m_Cache.Contains(cacheKey))
|
||||
m_Cache.Remove(cacheKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<GroupRolesData> GetAgentGroupRoles(string RequestingAgentID, string AgentID, UUID GroupID, GroupRolesListDelegate d)
|
||||
{
|
||||
object roles = null;
|
||||
bool firstCall = false;
|
||||
string cacheKey = "roles-" + GroupID.ToString() + "-" + AgentID.ToString();
|
||||
|
||||
//m_log.DebugFormat("[XXX]: GetAgentGroupRoles {0}", cacheKey);
|
||||
|
||||
while (true)
|
||||
{
|
||||
lock (m_Cache)
|
||||
{
|
||||
if (m_Cache.TryGetValue(cacheKey, out roles))
|
||||
{
|
||||
//m_log.DebugFormat("[XXX]: GetAgentGroupRoles {0} cached!", cacheKey);
|
||||
return (List<GroupRolesData>)roles;
|
||||
}
|
||||
|
||||
// not cached
|
||||
if (!m_ActiveRequests.ContainsKey(cacheKey))
|
||||
{
|
||||
m_ActiveRequests.Add(cacheKey, true);
|
||||
firstCall = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (firstCall)
|
||||
{
|
||||
roles = d();
|
||||
lock (m_Cache)
|
||||
{
|
||||
m_Cache.AddOrUpdate(cacheKey, roles, GROUPS_CACHE_TIMEOUT);
|
||||
m_ActiveRequests.Remove(cacheKey);
|
||||
return (List<GroupRolesData>)roles;
|
||||
}
|
||||
}
|
||||
else
|
||||
Thread.Sleep(50);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetAgentActiveGroupRole(string AgentID, UUID GroupID, VoidDelegate d)
|
||||
{
|
||||
d();
|
||||
|
||||
lock (m_Cache)
|
||||
{
|
||||
// Invalidate cached info, because it has ActiveRoleID and Powers
|
||||
string cacheKey = "membership-" + AgentID.ToString() + "-" + GroupID.ToString();
|
||||
if (m_Cache.Contains(cacheKey))
|
||||
m_Cache.Remove(cacheKey);
|
||||
|
||||
cacheKey = "memberships-" + AgentID.ToString();
|
||||
if (m_Cache.Contains(cacheKey))
|
||||
m_Cache.Remove(cacheKey);
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateMembership(string AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile, VoidDelegate d)
|
||||
{
|
||||
d();
|
||||
|
||||
lock (m_Cache)
|
||||
{
|
||||
string cacheKey = "membership-" + AgentID.ToString() + "-" + GroupID.ToString();
|
||||
if (m_Cache.Contains(cacheKey))
|
||||
m_Cache.Remove(cacheKey);
|
||||
|
||||
cacheKey = "memberships-" + AgentID.ToString();
|
||||
if (m_Cache.Contains(cacheKey))
|
||||
m_Cache.Remove(cacheKey);
|
||||
|
||||
cacheKey = "active-" + AgentID.ToString();
|
||||
object m = null;
|
||||
if (m_Cache.TryGetValue(cacheKey, out m))
|
||||
{
|
||||
GroupMembershipData membership = (GroupMembershipData)m;
|
||||
membership.ListInProfile = ListInProfile;
|
||||
membership.AcceptNotices = AcceptNotices;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool AddGroupNotice(UUID groupID, UUID noticeID, GroupNoticeInfo notice, BooleanDelegate d)
|
||||
{
|
||||
if (d())
|
||||
{
|
||||
lock (m_Cache)
|
||||
{
|
||||
m_Cache.AddOrUpdate("notice-" + noticeID.ToString(), notice, GROUPS_CACHE_TIMEOUT);
|
||||
string cacheKey = "notices-" + groupID.ToString();
|
||||
if (m_Cache.Contains(cacheKey))
|
||||
m_Cache.Remove(cacheKey);
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public GroupNoticeInfo GetGroupNotice(UUID noticeID, NoticeDelegate d)
|
||||
{
|
||||
object notice = null;
|
||||
bool firstCall = false;
|
||||
string cacheKey = "notice-" + noticeID.ToString();
|
||||
|
||||
//m_log.DebugFormat("[XXX]: GetAgentGroupRoles {0}", cacheKey);
|
||||
|
||||
while (true)
|
||||
{
|
||||
lock (m_Cache)
|
||||
{
|
||||
if (m_Cache.TryGetValue(cacheKey, out notice))
|
||||
{
|
||||
return (GroupNoticeInfo)notice;
|
||||
}
|
||||
|
||||
// not cached
|
||||
if (!m_ActiveRequests.ContainsKey(cacheKey))
|
||||
{
|
||||
m_ActiveRequests.Add(cacheKey, true);
|
||||
firstCall = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (firstCall)
|
||||
{
|
||||
GroupNoticeInfo _notice = d();
|
||||
|
||||
lock (m_Cache)
|
||||
{
|
||||
m_Cache.AddOrUpdate(cacheKey, _notice, GROUPS_CACHE_TIMEOUT);
|
||||
m_ActiveRequests.Remove(cacheKey);
|
||||
return _notice;
|
||||
}
|
||||
}
|
||||
else
|
||||
Thread.Sleep(50);
|
||||
}
|
||||
}
|
||||
|
||||
public List<ExtendedGroupNoticeData> GetGroupNotices(UUID GroupID, NoticeListDelegate d)
|
||||
{
|
||||
object notices = null;
|
||||
bool firstCall = false;
|
||||
string cacheKey = "notices-" + GroupID.ToString();
|
||||
|
||||
//m_log.DebugFormat("[XXX]: GetGroupNotices {0}", cacheKey);
|
||||
|
||||
while (true)
|
||||
{
|
||||
lock (m_Cache)
|
||||
{
|
||||
if (m_Cache.TryGetValue(cacheKey, out notices))
|
||||
{
|
||||
//m_log.DebugFormat("[XXX]: GetGroupNotices {0} cached!", cacheKey);
|
||||
return (List<ExtendedGroupNoticeData>)notices;
|
||||
}
|
||||
|
||||
// not cached
|
||||
if (!m_ActiveRequests.ContainsKey(cacheKey))
|
||||
{
|
||||
m_ActiveRequests.Add(cacheKey, true);
|
||||
firstCall = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (firstCall)
|
||||
{
|
||||
notices = d();
|
||||
|
||||
lock (m_Cache)
|
||||
{
|
||||
m_Cache.AddOrUpdate(cacheKey, notices, GROUPS_CACHE_TIMEOUT);
|
||||
m_ActiveRequests.Remove(cacheKey);
|
||||
return (List<ExtendedGroupNoticeData>)notices;
|
||||
}
|
||||
}
|
||||
else
|
||||
Thread.Sleep(50);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,84 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using Nini.Config;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Data;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using OpenSim.Services.Base;
|
||||
|
||||
namespace OpenSim.Groups
|
||||
{
|
||||
public class GroupsServiceBase : ServiceBase
|
||||
{
|
||||
protected IGroupsData m_Database = null;
|
||||
|
||||
public GroupsServiceBase(IConfigSource config, string cName)
|
||||
: base(config)
|
||||
{
|
||||
string dllName = String.Empty;
|
||||
string connString = String.Empty;
|
||||
string realm = "os_groups";
|
||||
string configName = (cName == string.Empty) ? "Groups" : cName;
|
||||
|
||||
//
|
||||
// Try reading the [DatabaseService] section, if it exists
|
||||
//
|
||||
IConfig dbConfig = config.Configs["DatabaseService"];
|
||||
if (dbConfig != null)
|
||||
{
|
||||
if (dllName == String.Empty)
|
||||
dllName = dbConfig.GetString("StorageProvider", String.Empty);
|
||||
if (connString == String.Empty)
|
||||
connString = dbConfig.GetString("ConnectionString", String.Empty);
|
||||
}
|
||||
|
||||
//
|
||||
// [Groups] section overrides [DatabaseService], if it exists
|
||||
//
|
||||
IConfig groupsConfig = config.Configs[configName];
|
||||
if (groupsConfig != null)
|
||||
{
|
||||
dllName = groupsConfig.GetString("StorageProvider", dllName);
|
||||
connString = groupsConfig.GetString("ConnectionString", connString);
|
||||
realm = groupsConfig.GetString("Realm", realm);
|
||||
}
|
||||
|
||||
//
|
||||
// We tried, but this doesn't exist. We can't proceed.
|
||||
//
|
||||
if (dllName.Equals(String.Empty))
|
||||
throw new Exception("No StorageProvider configured");
|
||||
|
||||
m_Database = LoadPlugin<IGroupsData>(dllName, new Object[] { connString, realm });
|
||||
if (m_Database == null)
|
||||
throw new Exception("Could not find a storage interface in the given module " + dllName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,353 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Timers;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Data;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Services.Interfaces;
|
||||
|
||||
namespace OpenSim.Groups
|
||||
{
|
||||
public class HGGroupsService : GroupsService
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private IOfflineIMService m_OfflineIM;
|
||||
private IUserAccountService m_UserAccounts;
|
||||
private string m_HomeURI;
|
||||
|
||||
public HGGroupsService(IConfigSource config, IOfflineIMService im, IUserAccountService users, string homeURI)
|
||||
: base(config, string.Empty)
|
||||
{
|
||||
m_OfflineIM = im;
|
||||
m_UserAccounts = users;
|
||||
m_HomeURI = homeURI;
|
||||
if (!m_HomeURI.EndsWith("/"))
|
||||
m_HomeURI += "/";
|
||||
}
|
||||
|
||||
|
||||
#region HG specific operations
|
||||
|
||||
public bool CreateGroupProxy(string RequestingAgentID, string agentID, string accessToken, UUID groupID, string serviceLocation, string name, out string reason)
|
||||
{
|
||||
reason = string.Empty;
|
||||
Uri uri = null;
|
||||
try
|
||||
{
|
||||
uri = new Uri(serviceLocation);
|
||||
}
|
||||
catch (UriFormatException)
|
||||
{
|
||||
reason = "Bad location for group proxy";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if it already exists
|
||||
GroupData grec = m_Database.RetrieveGroup(groupID);
|
||||
if (grec == null ||
|
||||
(grec != null && grec.Data["Location"] != string.Empty && grec.Data["Location"].ToLower() != serviceLocation.ToLower()))
|
||||
{
|
||||
// Create the group
|
||||
grec = new GroupData();
|
||||
grec.GroupID = groupID;
|
||||
grec.Data = new Dictionary<string, string>();
|
||||
grec.Data["Name"] = name + " @ " + uri.Authority;
|
||||
grec.Data["Location"] = serviceLocation;
|
||||
grec.Data["Charter"] = string.Empty;
|
||||
grec.Data["InsigniaID"] = UUID.Zero.ToString();
|
||||
grec.Data["FounderID"] = UUID.Zero.ToString();
|
||||
grec.Data["MembershipFee"] = "0";
|
||||
grec.Data["OpenEnrollment"] = "0";
|
||||
grec.Data["ShowInList"] = "0";
|
||||
grec.Data["AllowPublish"] = "0";
|
||||
grec.Data["MaturePublish"] = "0";
|
||||
grec.Data["OwnerRoleID"] = UUID.Zero.ToString();
|
||||
|
||||
|
||||
if (!m_Database.StoreGroup(grec))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (grec.Data["Location"] == string.Empty)
|
||||
{
|
||||
reason = "Cannot add proxy membership to non-proxy group";
|
||||
return false;
|
||||
}
|
||||
|
||||
UUID uid = UUID.Zero;
|
||||
string url = string.Empty, first = string.Empty, last = string.Empty, tmp = string.Empty;
|
||||
Util.ParseUniversalUserIdentifier(RequestingAgentID, out uid, out url, out first, out last, out tmp);
|
||||
string fromName = first + "." + last + "@" + url;
|
||||
|
||||
// Invite to group again
|
||||
InviteToGroup(fromName, groupID, new UUID(agentID), grec.Data["Name"]);
|
||||
|
||||
// Stick the proxy membership in the DB already
|
||||
// we'll delete it if the agent declines the invitation
|
||||
MembershipData membership = new MembershipData();
|
||||
membership.PrincipalID = agentID;
|
||||
membership.GroupID = groupID;
|
||||
membership.Data = new Dictionary<string, string>();
|
||||
membership.Data["SelectedRoleID"] = UUID.Zero.ToString();
|
||||
membership.Data["Contribution"] = "0";
|
||||
membership.Data["ListInProfile"] = "1";
|
||||
membership.Data["AcceptNotices"] = "1";
|
||||
membership.Data["AccessToken"] = accessToken;
|
||||
|
||||
m_Database.StoreMember(membership);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void RemoveAgentFromGroup(string RequestingAgentID, string AgentID, UUID GroupID, string token)
|
||||
{
|
||||
// check the token
|
||||
MembershipData membership = m_Database.RetrieveMember(GroupID, AgentID);
|
||||
if (membership != null)
|
||||
{
|
||||
if (token != string.Empty && token.Equals(membership.Data["AccessToken"]))
|
||||
RemoveAgentFromGroup(RequestingAgentID, AgentID, GroupID);
|
||||
else
|
||||
m_log.DebugFormat("[Groups.HGGroupsService]: access token {0} did not match stored one {1}", token, membership.Data["AccessToken"]);
|
||||
}
|
||||
else
|
||||
m_log.DebugFormat("[Groups.HGGroupsService]: membership not found for {0}", AgentID);
|
||||
}
|
||||
|
||||
public ExtendedGroupRecord GetGroupRecord(string RequestingAgentID, UUID GroupID, string groupName, string token)
|
||||
{
|
||||
// check the token
|
||||
if (!VerifyToken(GroupID, RequestingAgentID, token))
|
||||
return null;
|
||||
|
||||
ExtendedGroupRecord grec;
|
||||
if (GroupID == UUID.Zero)
|
||||
grec = GetGroupRecord(RequestingAgentID, groupName);
|
||||
else
|
||||
grec = GetGroupRecord(RequestingAgentID, GroupID);
|
||||
|
||||
if (grec != null)
|
||||
FillFounderUUI(grec);
|
||||
|
||||
return grec;
|
||||
}
|
||||
|
||||
public List<ExtendedGroupMembersData> GetGroupMembers(string RequestingAgentID, UUID GroupID, string token)
|
||||
{
|
||||
if (!VerifyToken(GroupID, RequestingAgentID, token))
|
||||
return new List<ExtendedGroupMembersData>();
|
||||
|
||||
List<ExtendedGroupMembersData> members = GetGroupMembers(RequestingAgentID, GroupID);
|
||||
|
||||
// convert UUIDs to UUIs
|
||||
members.ForEach(delegate (ExtendedGroupMembersData m)
|
||||
{
|
||||
if (m.AgentID.ToString().Length == 36) // UUID
|
||||
{
|
||||
UserAccount account = m_UserAccounts.GetUserAccount(UUID.Zero, new UUID(m.AgentID));
|
||||
if (account != null)
|
||||
m.AgentID = Util.UniversalIdentifier(account.PrincipalID, account.FirstName, account.LastName, m_HomeURI);
|
||||
}
|
||||
});
|
||||
|
||||
return members;
|
||||
}
|
||||
|
||||
public List<GroupRolesData> GetGroupRoles(string RequestingAgentID, UUID GroupID, string token)
|
||||
{
|
||||
if (!VerifyToken(GroupID, RequestingAgentID, token))
|
||||
return new List<GroupRolesData>();
|
||||
|
||||
return GetGroupRoles(RequestingAgentID, GroupID);
|
||||
}
|
||||
|
||||
public List<ExtendedGroupRoleMembersData> GetGroupRoleMembers(string RequestingAgentID, UUID GroupID, string token)
|
||||
{
|
||||
if (!VerifyToken(GroupID, RequestingAgentID, token))
|
||||
return new List<ExtendedGroupRoleMembersData>();
|
||||
|
||||
List<ExtendedGroupRoleMembersData> rolemembers = GetGroupRoleMembers(RequestingAgentID, GroupID);
|
||||
|
||||
// convert UUIDs to UUIs
|
||||
rolemembers.ForEach(delegate(ExtendedGroupRoleMembersData m)
|
||||
{
|
||||
if (m.MemberID.ToString().Length == 36) // UUID
|
||||
{
|
||||
UserAccount account = m_UserAccounts.GetUserAccount(UUID.Zero, new UUID(m.MemberID));
|
||||
if (account != null)
|
||||
m.MemberID = Util.UniversalIdentifier(account.PrincipalID, account.FirstName, account.LastName, m_HomeURI);
|
||||
}
|
||||
});
|
||||
|
||||
return rolemembers;
|
||||
}
|
||||
|
||||
public bool AddNotice(string RequestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message,
|
||||
bool hasAttachment, byte attType, string attName, UUID attItemID, string attOwnerID)
|
||||
{
|
||||
// check that the group proxy exists
|
||||
ExtendedGroupRecord grec = GetGroupRecord(RequestingAgentID, groupID);
|
||||
if (grec == null)
|
||||
{
|
||||
m_log.DebugFormat("[Groups.HGGroupsService]: attempt at adding notice to non-existent group proxy");
|
||||
return false;
|
||||
}
|
||||
|
||||
// check that the group is remote
|
||||
if (grec.ServiceLocation == string.Empty)
|
||||
{
|
||||
m_log.DebugFormat("[Groups.HGGroupsService]: attempt at adding notice to local (non-proxy) group");
|
||||
return false;
|
||||
}
|
||||
|
||||
// check that there isn't already a notice with the same ID
|
||||
if (GetGroupNotice(RequestingAgentID, noticeID) != null)
|
||||
{
|
||||
m_log.DebugFormat("[Groups.HGGroupsService]: a notice with the same ID already exists", grec.ServiceLocation);
|
||||
return false;
|
||||
}
|
||||
|
||||
// This has good intentions (security) but it will potentially DDS the origin...
|
||||
// We'll need to send a proof along with the message. Maybe encrypt the message
|
||||
// using key pairs
|
||||
//
|
||||
//// check that the notice actually exists in the origin
|
||||
//GroupsServiceHGConnector c = new GroupsServiceHGConnector(grec.ServiceLocation);
|
||||
//if (!c.VerifyNotice(noticeID, groupID))
|
||||
//{
|
||||
// m_log.DebugFormat("[Groups.HGGroupsService]: notice does not exist at origin {0}", grec.ServiceLocation);
|
||||
// return false;
|
||||
//}
|
||||
|
||||
// ok, we're good!
|
||||
return _AddNotice(groupID, noticeID, fromName, subject, message, hasAttachment, attType, attName, attItemID, attOwnerID);
|
||||
}
|
||||
|
||||
public bool VerifyNotice(UUID noticeID, UUID groupID)
|
||||
{
|
||||
GroupNoticeInfo notice = GetGroupNotice(string.Empty, noticeID);
|
||||
|
||||
if (notice == null)
|
||||
return false;
|
||||
|
||||
if (notice.GroupID != groupID)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void InviteToGroup(string fromName, UUID groupID, UUID invitedAgentID, string groupName)
|
||||
{
|
||||
// Todo: Security check, probably also want to send some kind of notification
|
||||
UUID InviteID = UUID.Random();
|
||||
|
||||
if (AddAgentToGroupInvite(InviteID, groupID, invitedAgentID.ToString()))
|
||||
{
|
||||
Guid inviteUUID = InviteID.Guid;
|
||||
|
||||
GridInstantMessage msg = new GridInstantMessage();
|
||||
|
||||
msg.imSessionID = inviteUUID;
|
||||
|
||||
// msg.fromAgentID = agentID.Guid;
|
||||
msg.fromAgentID = groupID.Guid;
|
||||
msg.toAgentID = invitedAgentID.Guid;
|
||||
//msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
|
||||
msg.timestamp = 0;
|
||||
msg.fromAgentName = fromName;
|
||||
msg.message = string.Format("Please confirm your acceptance to join group {0}.", groupName);
|
||||
msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.GroupInvitation;
|
||||
msg.fromGroup = true;
|
||||
msg.offline = (byte)0;
|
||||
msg.ParentEstateID = 0;
|
||||
msg.Position = Vector3.Zero;
|
||||
msg.RegionID = UUID.Zero.Guid;
|
||||
msg.binaryBucket = new byte[20];
|
||||
|
||||
string reason = string.Empty;
|
||||
m_OfflineIM.StoreMessage(msg, out reason);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private bool AddAgentToGroupInvite(UUID inviteID, UUID groupID, string agentID)
|
||||
{
|
||||
// Check whether the invitee is already a member of the group
|
||||
MembershipData m = m_Database.RetrieveMember(groupID, agentID);
|
||||
if (m != null)
|
||||
return false;
|
||||
|
||||
// Check whether there are pending invitations and delete them
|
||||
InvitationData invite = m_Database.RetrieveInvitation(groupID, agentID);
|
||||
if (invite != null)
|
||||
m_Database.DeleteInvite(invite.InviteID);
|
||||
|
||||
invite = new InvitationData();
|
||||
invite.InviteID = inviteID;
|
||||
invite.PrincipalID = agentID;
|
||||
invite.GroupID = groupID;
|
||||
invite.RoleID = UUID.Zero;
|
||||
invite.Data = new Dictionary<string, string>();
|
||||
|
||||
return m_Database.StoreInvitation(invite);
|
||||
}
|
||||
|
||||
private void FillFounderUUI(ExtendedGroupRecord grec)
|
||||
{
|
||||
UserAccount account = m_UserAccounts.GetUserAccount(UUID.Zero, grec.FounderID);
|
||||
if (account != null)
|
||||
grec.FounderUUI = Util.UniversalIdentifier(account.PrincipalID, account.FirstName, account.LastName, m_HomeURI);
|
||||
}
|
||||
|
||||
private bool VerifyToken(UUID groupID, string agentID, string token)
|
||||
{
|
||||
// check the token
|
||||
MembershipData membership = m_Database.RetrieveMember(groupID, agentID);
|
||||
if (membership != null)
|
||||
{
|
||||
if (token != string.Empty && token.Equals(membership.Data["AccessToken"]))
|
||||
return true;
|
||||
else
|
||||
m_log.DebugFormat("[Groups.HGGroupsService]: access token {0} did not match stored one {1}", token, membership.Data["AccessToken"]);
|
||||
}
|
||||
else
|
||||
m_log.DebugFormat("[Groups.HGGroupsService]: membership not found for {0}", agentID);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,272 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using log4net;
|
||||
using Mono.Addins;
|
||||
using Nini.Config;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Servers;
|
||||
using OpenSim.Framework.Client;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Services.Interfaces;
|
||||
|
||||
namespace OpenSim.OfflineIM
|
||||
{
|
||||
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "OfflineIMConnectorModule")]
|
||||
public class OfflineIMRegionModule : ISharedRegionModule, IOfflineIMService
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private bool m_Enabled = false;
|
||||
private List<Scene> m_SceneList = new List<Scene>();
|
||||
IMessageTransferModule m_TransferModule = null;
|
||||
private bool m_ForwardOfflineGroupMessages = true;
|
||||
|
||||
private IOfflineIMService m_OfflineIMService;
|
||||
|
||||
public void Initialise(IConfigSource config)
|
||||
{
|
||||
IConfig cnf = config.Configs["Messaging"];
|
||||
if (cnf == null)
|
||||
return;
|
||||
if (cnf != null && cnf.GetString("OfflineMessageModule", string.Empty) != Name)
|
||||
return;
|
||||
|
||||
m_Enabled = true;
|
||||
|
||||
string serviceLocation = cnf.GetString("OfflineMessageURL", string.Empty);
|
||||
if (serviceLocation == string.Empty)
|
||||
m_OfflineIMService = new OfflineIMService(config);
|
||||
else
|
||||
m_OfflineIMService = new OfflineIMServiceRemoteConnector(serviceLocation);
|
||||
|
||||
m_ForwardOfflineGroupMessages = cnf.GetBoolean("ForwardOfflineGroupMessages", m_ForwardOfflineGroupMessages);
|
||||
m_log.DebugFormat("[OfflineIM.V2]: Offline messages enabled by {0}", Name);
|
||||
}
|
||||
|
||||
public void AddRegion(Scene scene)
|
||||
{
|
||||
if (!m_Enabled)
|
||||
return;
|
||||
|
||||
scene.RegisterModuleInterface<IOfflineIMService>(this);
|
||||
m_SceneList.Add(scene);
|
||||
scene.EventManager.OnNewClient += OnNewClient;
|
||||
}
|
||||
|
||||
public void RegionLoaded(Scene scene)
|
||||
{
|
||||
if (!m_Enabled)
|
||||
return;
|
||||
|
||||
if (m_TransferModule == null)
|
||||
{
|
||||
m_TransferModule = scene.RequestModuleInterface<IMessageTransferModule>();
|
||||
if (m_TransferModule == null)
|
||||
{
|
||||
scene.EventManager.OnNewClient -= OnNewClient;
|
||||
|
||||
m_SceneList.Clear();
|
||||
|
||||
m_log.Error("[OfflineIM.V2]: No message transfer module is enabled. Disabling offline messages");
|
||||
}
|
||||
m_TransferModule.OnUndeliveredMessage += UndeliveredMessage;
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveRegion(Scene scene)
|
||||
{
|
||||
if (!m_Enabled)
|
||||
return;
|
||||
|
||||
m_SceneList.Remove(scene);
|
||||
scene.EventManager.OnNewClient -= OnNewClient;
|
||||
m_TransferModule.OnUndeliveredMessage -= UndeliveredMessage;
|
||||
|
||||
scene.ForEachClient(delegate(IClientAPI client)
|
||||
{
|
||||
client.OnRetrieveInstantMessages -= RetrieveInstantMessages;
|
||||
client.OnMuteListRequest -= OnMuteListRequest;
|
||||
});
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return "Offline Message Module V2"; }
|
||||
}
|
||||
|
||||
public Type ReplaceableInterface
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
m_SceneList.Clear();
|
||||
}
|
||||
|
||||
private Scene FindScene(UUID agentID)
|
||||
{
|
||||
foreach (Scene s in m_SceneList)
|
||||
{
|
||||
ScenePresence presence = s.GetScenePresence(agentID);
|
||||
if (presence != null && !presence.IsChildAgent)
|
||||
return s;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private IClientAPI FindClient(UUID agentID)
|
||||
{
|
||||
foreach (Scene s in m_SceneList)
|
||||
{
|
||||
ScenePresence presence = s.GetScenePresence(agentID);
|
||||
if (presence != null && !presence.IsChildAgent)
|
||||
return presence.ControllingClient;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void OnNewClient(IClientAPI client)
|
||||
{
|
||||
client.OnRetrieveInstantMessages += RetrieveInstantMessages;
|
||||
client.OnMuteListRequest += OnMuteListRequest;
|
||||
}
|
||||
|
||||
private void RetrieveInstantMessages(IClientAPI client)
|
||||
{
|
||||
m_log.DebugFormat("[OfflineIM.V2]: Retrieving stored messages for {0}", client.AgentId);
|
||||
|
||||
List<GridInstantMessage> msglist = m_OfflineIMService.GetMessages(client.AgentId);
|
||||
|
||||
if (msglist == null)
|
||||
m_log.DebugFormat("[OfflineIM.V2]: WARNING null message list.");
|
||||
|
||||
foreach (GridInstantMessage im in msglist)
|
||||
{
|
||||
if (im.dialog == (byte)InstantMessageDialog.InventoryOffered)
|
||||
// send it directly or else the item will be given twice
|
||||
client.SendInstantMessage(im);
|
||||
else
|
||||
{
|
||||
// Send through scene event manager so all modules get a chance
|
||||
// to look at this message before it gets delivered.
|
||||
//
|
||||
// Needed for proper state management for stored group
|
||||
// invitations
|
||||
//
|
||||
Scene s = FindScene(client.AgentId);
|
||||
if (s != null)
|
||||
s.EventManager.TriggerIncomingInstantMessage(im);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Apparently this is needed in order for the viewer to request the IMs.
|
||||
private void OnMuteListRequest(IClientAPI client, uint crc)
|
||||
{
|
||||
m_log.DebugFormat("[OfflineIM.V2] Got mute list request for crc {0}", crc);
|
||||
string filename = "mutes" + client.AgentId.ToString();
|
||||
|
||||
IXfer xfer = client.Scene.RequestModuleInterface<IXfer>();
|
||||
if (xfer != null)
|
||||
{
|
||||
xfer.AddNewFile(filename, new Byte[0]);
|
||||
client.SendMuteListUpdate(filename);
|
||||
}
|
||||
}
|
||||
|
||||
private void UndeliveredMessage(GridInstantMessage im)
|
||||
{
|
||||
if (im.dialog != (byte)InstantMessageDialog.MessageFromObject &&
|
||||
im.dialog != (byte)InstantMessageDialog.MessageFromAgent &&
|
||||
im.dialog != (byte)InstantMessageDialog.GroupNotice &&
|
||||
im.dialog != (byte)InstantMessageDialog.GroupInvitation &&
|
||||
im.dialog != (byte)InstantMessageDialog.InventoryOffered)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_ForwardOfflineGroupMessages)
|
||||
{
|
||||
if (im.dialog == (byte)InstantMessageDialog.GroupNotice ||
|
||||
im.dialog == (byte)InstantMessageDialog.GroupInvitation)
|
||||
return;
|
||||
}
|
||||
|
||||
Scene scene = FindScene(new UUID(im.fromAgentID));
|
||||
if (scene == null)
|
||||
scene = m_SceneList[0];
|
||||
|
||||
string reason = string.Empty;
|
||||
bool success = m_OfflineIMService.StoreMessage(im, out reason);
|
||||
|
||||
if (im.dialog == (byte)InstantMessageDialog.MessageFromAgent)
|
||||
{
|
||||
IClientAPI client = FindClient(new UUID(im.fromAgentID));
|
||||
if (client == null)
|
||||
return;
|
||||
|
||||
client.SendInstantMessage(new GridInstantMessage(
|
||||
null, new UUID(im.toAgentID),
|
||||
"System", new UUID(im.fromAgentID),
|
||||
(byte)InstantMessageDialog.MessageFromAgent,
|
||||
"User is not logged in. " +
|
||||
(success ? "Message saved." : "Message not saved: " + reason),
|
||||
false, new Vector3()));
|
||||
}
|
||||
}
|
||||
|
||||
#region IOfflineIM
|
||||
|
||||
public List<GridInstantMessage> GetMessages(UUID principalID)
|
||||
{
|
||||
return m_OfflineIMService.GetMessages(principalID);
|
||||
}
|
||||
|
||||
public bool StoreMessage(GridInstantMessage im, out string reason)
|
||||
{
|
||||
return m_OfflineIMService.StoreMessage(im, out reason);
|
||||
}
|
||||
|
||||
public void DeleteMessages(UUID userID)
|
||||
{
|
||||
m_OfflineIMService.DeleteMessages(userID);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using Mono.Addins;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("OpenSim.Addons.OfflineIM")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("http://opensimulator.org")]
|
||||
[assembly: AssemblyProduct("OpenSim.Addons.OfflineIM")]
|
||||
[assembly: AssemblyCopyright("Copyright (c) OpenSimulator.org Developers")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("a16a9905-4393-4872-9fca-4c81bedbd9f2")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
[assembly: AssemblyVersion("0.8.0.*")]
|
||||
|
||||
[assembly: Addin("OpenSim.OfflineIM", "0.1")]
|
||||
[assembly: AddinDependency("OpenSim", "0.5")]
|
||||
@@ -1,151 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Server.Base;
|
||||
using OpenSim.Services.Interfaces;
|
||||
|
||||
using OpenMetaverse;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
|
||||
namespace OpenSim.OfflineIM
|
||||
{
|
||||
public class OfflineIMServiceRemoteConnector : IOfflineIMService
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private string m_ServerURI = string.Empty;
|
||||
private object m_Lock = new object();
|
||||
|
||||
public OfflineIMServiceRemoteConnector(string url)
|
||||
{
|
||||
m_ServerURI = url;
|
||||
m_log.DebugFormat("[OfflineIM.V2.RemoteConnector]: Offline IM server at {0}", m_ServerURI);
|
||||
}
|
||||
|
||||
public OfflineIMServiceRemoteConnector(IConfigSource config)
|
||||
{
|
||||
IConfig cnf = config.Configs["Messaging"];
|
||||
if (cnf == null)
|
||||
{
|
||||
m_log.WarnFormat("[OfflineIM.V2.RemoteConnector]: Missing Messaging configuration");
|
||||
return;
|
||||
}
|
||||
|
||||
m_ServerURI = cnf.GetString("OfflineMessageURL", string.Empty);
|
||||
|
||||
}
|
||||
|
||||
#region IOfflineIMService
|
||||
public List<GridInstantMessage> GetMessages(UUID principalID)
|
||||
{
|
||||
List<GridInstantMessage> ims = new List<GridInstantMessage>();
|
||||
|
||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
||||
sendData["PrincipalID"] = principalID;
|
||||
Dictionary<string, object> ret = MakeRequest("GET", sendData);
|
||||
|
||||
if (ret == null)
|
||||
return ims;
|
||||
|
||||
if (!ret.ContainsKey("RESULT"))
|
||||
return ims;
|
||||
|
||||
if (ret["RESULT"].ToString() == "NULL")
|
||||
return ims;
|
||||
|
||||
foreach (object v in ((Dictionary<string, object>)ret["RESULT"]).Values)
|
||||
{
|
||||
GridInstantMessage m = OfflineIMDataUtils.GridInstantMessage((Dictionary<string, object>)v);
|
||||
ims.Add(m);
|
||||
}
|
||||
|
||||
return ims;
|
||||
}
|
||||
|
||||
public bool StoreMessage(GridInstantMessage im, out string reason)
|
||||
{
|
||||
reason = string.Empty;
|
||||
Dictionary<string, object> sendData = OfflineIMDataUtils.GridInstantMessage(im);
|
||||
|
||||
Dictionary<string, object> ret = MakeRequest("STORE", sendData);
|
||||
|
||||
if (ret == null)
|
||||
{
|
||||
reason = "Bad response from server";
|
||||
return false;
|
||||
}
|
||||
|
||||
string result = ret["RESULT"].ToString();
|
||||
if (result == "NULL" || result.ToLower() == "false")
|
||||
{
|
||||
reason = ret["REASON"].ToString();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void DeleteMessages(UUID userID)
|
||||
{
|
||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
||||
sendData["UserID"] = userID;
|
||||
|
||||
MakeRequest("DELETE", sendData);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Make Request
|
||||
|
||||
private Dictionary<string, object> MakeRequest(string method, Dictionary<string, object> sendData)
|
||||
{
|
||||
sendData["METHOD"] = method;
|
||||
|
||||
string reply = string.Empty;
|
||||
lock (m_Lock)
|
||||
reply = SynchronousRestFormsRequester.MakeRequest("POST",
|
||||
m_ServerURI + "/offlineim",
|
||||
ServerUtils.BuildQueryString(sendData));
|
||||
|
||||
Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(
|
||||
reply);
|
||||
|
||||
return replyData;
|
||||
}
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,231 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Nini.Config;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Server.Base;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using OpenSim.Framework.Servers.HttpServer;
|
||||
using OpenSim.Server.Handlers.Base;
|
||||
using log4net;
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace OpenSim.OfflineIM
|
||||
{
|
||||
public class OfflineIMServiceRobustConnector : ServiceConnector
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private IOfflineIMService m_OfflineIMService;
|
||||
private string m_ConfigName = "Messaging";
|
||||
|
||||
public OfflineIMServiceRobustConnector(IConfigSource config, IHttpServer server, string configName) :
|
||||
base(config, server, configName)
|
||||
{
|
||||
if (configName != String.Empty)
|
||||
m_ConfigName = configName;
|
||||
|
||||
m_log.DebugFormat("[OfflineIM.V2.RobustConnector]: Starting with config name {0}", m_ConfigName);
|
||||
|
||||
m_OfflineIMService = new OfflineIMService(config);
|
||||
|
||||
server.AddStreamHandler(new OfflineIMServicePostHandler(m_OfflineIMService));
|
||||
}
|
||||
}
|
||||
|
||||
public class OfflineIMServicePostHandler : BaseStreamHandler
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private IOfflineIMService m_OfflineIMService;
|
||||
|
||||
public OfflineIMServicePostHandler(IOfflineIMService service) :
|
||||
base("POST", "/offlineim")
|
||||
{
|
||||
m_OfflineIMService = service;
|
||||
}
|
||||
|
||||
protected override byte[] ProcessRequest(string path, Stream requestData,
|
||||
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
||||
{
|
||||
StreamReader sr = new StreamReader(requestData);
|
||||
string body = sr.ReadToEnd();
|
||||
sr.Close();
|
||||
body = body.Trim();
|
||||
|
||||
//m_log.DebugFormat("[XXX]: query String: {0}", body);
|
||||
|
||||
try
|
||||
{
|
||||
Dictionary<string, object> request =
|
||||
ServerUtils.ParseQueryString(body);
|
||||
|
||||
if (!request.ContainsKey("METHOD"))
|
||||
return FailureResult();
|
||||
|
||||
string method = request["METHOD"].ToString();
|
||||
request.Remove("METHOD");
|
||||
|
||||
switch (method)
|
||||
{
|
||||
case "GET":
|
||||
return HandleGet(request);
|
||||
case "STORE":
|
||||
return HandleStore(request);
|
||||
case "DELETE":
|
||||
return HandleDelete(request);
|
||||
}
|
||||
m_log.DebugFormat("[OFFLINE IM HANDLER]: unknown method request: {0}", method);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[OFFLINE IM HANDLER]: Exception {0}", e.StackTrace);
|
||||
}
|
||||
|
||||
return FailureResult();
|
||||
}
|
||||
|
||||
byte[] HandleStore(Dictionary<string, object> request)
|
||||
{
|
||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
||||
|
||||
GridInstantMessage im = OfflineIMDataUtils.GridInstantMessage(request);
|
||||
|
||||
string reason = string.Empty;
|
||||
|
||||
bool success = m_OfflineIMService.StoreMessage(im, out reason);
|
||||
|
||||
result["RESULT"] = success.ToString();
|
||||
if (!success)
|
||||
result["REASON"] = reason;
|
||||
|
||||
string xmlString = ServerUtils.BuildXmlResponse(result);
|
||||
|
||||
//m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
|
||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
||||
}
|
||||
|
||||
byte[] HandleGet(Dictionary<string, object> request)
|
||||
{
|
||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
||||
|
||||
if (!request.ContainsKey("PrincipalID"))
|
||||
NullResult(result, "Bad network data");
|
||||
else
|
||||
{
|
||||
UUID principalID = new UUID(request["PrincipalID"].ToString());
|
||||
List<GridInstantMessage> ims = m_OfflineIMService.GetMessages(principalID);
|
||||
|
||||
Dictionary<string, object> dict = new Dictionary<string, object>();
|
||||
int i = 0;
|
||||
foreach (GridInstantMessage m in ims)
|
||||
dict["im-" + i++] = OfflineIMDataUtils.GridInstantMessage(m);
|
||||
|
||||
result["RESULT"] = dict;
|
||||
}
|
||||
|
||||
string xmlString = ServerUtils.BuildXmlResponse(result);
|
||||
|
||||
//m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
|
||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
||||
}
|
||||
|
||||
byte[] HandleDelete(Dictionary<string, object> request)
|
||||
{
|
||||
if (!request.ContainsKey("UserID"))
|
||||
{
|
||||
return FailureResult();
|
||||
}
|
||||
else
|
||||
{
|
||||
UUID userID = new UUID(request["UserID"].ToString());
|
||||
m_OfflineIMService.DeleteMessages(userID);
|
||||
|
||||
return SuccessResult();
|
||||
}
|
||||
}
|
||||
|
||||
#region Helpers
|
||||
|
||||
private void NullResult(Dictionary<string, object> result, string reason)
|
||||
{
|
||||
result["RESULT"] = "NULL";
|
||||
result["REASON"] = reason;
|
||||
}
|
||||
|
||||
private byte[] FailureResult()
|
||||
{
|
||||
return BoolResult(false);
|
||||
}
|
||||
|
||||
private byte[] SuccessResult()
|
||||
{
|
||||
return BoolResult(true);
|
||||
}
|
||||
|
||||
private byte[] BoolResult(bool value)
|
||||
{
|
||||
XmlDocument doc = new XmlDocument();
|
||||
|
||||
XmlNode xmlnode = doc.CreateNode(XmlNodeType.XmlDeclaration,
|
||||
"", "");
|
||||
|
||||
doc.AppendChild(xmlnode);
|
||||
|
||||
XmlElement rootElement = doc.CreateElement("", "ServerResponse",
|
||||
"");
|
||||
|
||||
doc.AppendChild(rootElement);
|
||||
|
||||
XmlElement result = doc.CreateElement("", "RESULT", "");
|
||||
result.AppendChild(doc.CreateTextNode(value.ToString()));
|
||||
|
||||
rootElement.AppendChild(result);
|
||||
|
||||
return DocToBytes(doc);
|
||||
}
|
||||
|
||||
private byte[] DocToBytes(XmlDocument doc)
|
||||
{
|
||||
MemoryStream ms = new MemoryStream();
|
||||
XmlTextWriter xw = new XmlTextWriter(ms, null);
|
||||
xw.Formatting = Formatting.Indented;
|
||||
doc.WriteTo(xw);
|
||||
xw.Flush();
|
||||
|
||||
return ms.ToArray();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,135 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Text;
|
||||
using System.Timers;
|
||||
using System.Xml;
|
||||
using System.Xml.Serialization;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Data;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Services.Interfaces;
|
||||
|
||||
namespace OpenSim.OfflineIM
|
||||
{
|
||||
public class OfflineIMService : OfflineIMServiceBase, IOfflineIMService
|
||||
{
|
||||
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
private const int MAX_IM = 25;
|
||||
|
||||
private XmlSerializer m_serializer;
|
||||
private static bool m_Initialized = false;
|
||||
|
||||
public OfflineIMService(IConfigSource config)
|
||||
: base(config)
|
||||
{
|
||||
m_serializer = new XmlSerializer(typeof(GridInstantMessage));
|
||||
if (!m_Initialized)
|
||||
{
|
||||
m_Database.DeleteOld();
|
||||
m_Initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
public List<GridInstantMessage> GetMessages(UUID principalID)
|
||||
{
|
||||
List<GridInstantMessage> ims = new List<GridInstantMessage>();
|
||||
|
||||
OfflineIMData[] messages = m_Database.Get("PrincipalID", principalID.ToString());
|
||||
|
||||
if (messages == null || (messages != null && messages.Length == 0))
|
||||
return ims;
|
||||
|
||||
foreach (OfflineIMData m in messages)
|
||||
{
|
||||
using (MemoryStream mstream = new MemoryStream(Encoding.UTF8.GetBytes(m.Data["Message"])))
|
||||
{
|
||||
GridInstantMessage im = (GridInstantMessage)m_serializer.Deserialize(mstream);
|
||||
ims.Add(im);
|
||||
}
|
||||
}
|
||||
|
||||
// Then, delete them
|
||||
m_Database.Delete("PrincipalID", principalID.ToString());
|
||||
|
||||
return ims;
|
||||
}
|
||||
|
||||
public bool StoreMessage(GridInstantMessage im, out string reason)
|
||||
{
|
||||
reason = string.Empty;
|
||||
|
||||
// Check limits
|
||||
UUID principalID = new UUID(im.toAgentID);
|
||||
long count = m_Database.GetCount("PrincipalID", principalID.ToString());
|
||||
if (count >= MAX_IM)
|
||||
{
|
||||
reason = "Number of offline IMs has maxed out";
|
||||
return false;
|
||||
}
|
||||
|
||||
string imXml;
|
||||
using (MemoryStream mstream = new MemoryStream())
|
||||
{
|
||||
XmlWriterSettings settings = new XmlWriterSettings();
|
||||
settings.Encoding = Encoding.UTF8;
|
||||
|
||||
using (XmlWriter writer = XmlWriter.Create(mstream, settings))
|
||||
{
|
||||
m_serializer.Serialize(writer, im);
|
||||
writer.Flush();
|
||||
}
|
||||
|
||||
imXml = Util.UTF8.GetString(mstream.ToArray());
|
||||
}
|
||||
|
||||
OfflineIMData data = new OfflineIMData();
|
||||
data.PrincipalID = principalID;
|
||||
data.FromID = new UUID(im.fromAgentID);
|
||||
data.Data = new Dictionary<string, string>();
|
||||
data.Data["Message"] = imXml;
|
||||
|
||||
return m_Database.Store(data);
|
||||
|
||||
}
|
||||
|
||||
public void DeleteMessages(UUID userID)
|
||||
{
|
||||
m_Database.Delete("PrincipalID", userID.ToString());
|
||||
m_Database.Delete("FromID", userID.ToString());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -99,12 +99,12 @@ namespace OpenSim.ApplicationPlugins.LoadRegions
|
||||
RegionInfo[] regionsToLoad = regionLoader.LoadRegions();
|
||||
|
||||
m_log.Info("[LOAD REGIONS PLUGIN]: Loading specific shared modules...");
|
||||
//m_log.Info("[LOAD REGIONS PLUGIN]: DynamicTextureModule...");
|
||||
//m_openSim.ModuleLoader.LoadDefaultSharedModule(new DynamicTextureModule());
|
||||
//m_log.Info("[LOAD REGIONS PLUGIN]: LoadImageURLModule...");
|
||||
//m_openSim.ModuleLoader.LoadDefaultSharedModule(new LoadImageURLModule());
|
||||
//m_log.Info("[LOAD REGIONS PLUGIN]: XMLRPCModule...");
|
||||
//m_openSim.ModuleLoader.LoadDefaultSharedModule(new XMLRPCModule());
|
||||
m_log.Info("[LOAD REGIONS PLUGIN]: DynamicTextureModule...");
|
||||
m_openSim.ModuleLoader.LoadDefaultSharedModule(new DynamicTextureModule());
|
||||
m_log.Info("[LOAD REGIONS PLUGIN]: LoadImageURLModule...");
|
||||
m_openSim.ModuleLoader.LoadDefaultSharedModule(new LoadImageURLModule());
|
||||
m_log.Info("[LOAD REGIONS PLUGIN]: XMLRPCModule...");
|
||||
m_openSim.ModuleLoader.LoadDefaultSharedModule(new XMLRPCModule());
|
||||
// m_log.Info("[LOADREGIONSPLUGIN]: AssetTransactionModule...");
|
||||
// m_openSim.ModuleLoader.LoadDefaultSharedModule(new AssetTransactionModule());
|
||||
m_log.Info("[LOAD REGIONS PLUGIN]: Done.");
|
||||
@@ -115,8 +115,6 @@ namespace OpenSim.ApplicationPlugins.LoadRegions
|
||||
Environment.Exit(1);
|
||||
}
|
||||
|
||||
List<IScene> createdScenes = new List<IScene>();
|
||||
|
||||
for (int i = 0; i < regionsToLoad.Length; i++)
|
||||
{
|
||||
IScene scene;
|
||||
@@ -124,25 +122,22 @@ namespace OpenSim.ApplicationPlugins.LoadRegions
|
||||
Thread.CurrentThread.ManagedThreadId.ToString() +
|
||||
")");
|
||||
|
||||
bool changed = m_openSim.PopulateRegionEstateInfo(regionsToLoad[i]);
|
||||
|
||||
m_openSim.PopulateRegionEstateInfo(regionsToLoad[i]);
|
||||
m_openSim.CreateRegion(regionsToLoad[i], true, out scene);
|
||||
createdScenes.Add(scene);
|
||||
|
||||
if (changed)
|
||||
regionsToLoad[i].EstateSettings.Save();
|
||||
}
|
||||
|
||||
foreach (IScene scene in createdScenes)
|
||||
{
|
||||
scene.Start();
|
||||
|
||||
m_newRegionCreatedHandler = OnNewRegionCreated;
|
||||
if (m_newRegionCreatedHandler != null)
|
||||
regionsToLoad[i].EstateSettings.Save();
|
||||
|
||||
if (scene != null)
|
||||
{
|
||||
m_newRegionCreatedHandler(scene);
|
||||
m_newRegionCreatedHandler = OnNewRegionCreated;
|
||||
if (m_newRegionCreatedHandler != null)
|
||||
{
|
||||
m_newRegionCreatedHandler(scene);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_openSim.ModuleLoader.PostInitialise();
|
||||
m_openSim.ModuleLoader.ClearCache();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
||||
@@ -60,6 +60,7 @@ using System.Runtime.InteropServices;
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("0.7.6.*")]
|
||||
// [assembly: AssemblyVersion("0.6.5.*")]
|
||||
|
||||
[assembly : AssemblyVersion("0.8.0.*")]
|
||||
[assembly : AssemblyVersion("0.6.5.*")]
|
||||
[assembly : AssemblyFileVersion("0.6.5.0")]
|
||||
@@ -1,33 +0,0 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("OpenSim.ApplicationPlugins.RegionModulesController")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("http://opensimulator.org")]
|
||||
[assembly: AssemblyProduct("OpenSim")]
|
||||
[assembly: AssemblyCopyright("OpenSimulator developers")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("c023816d-194e-40c1-9195-a0f281d4ac5d")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
[assembly: AssemblyVersion("0.8.0.*")]
|
||||
|
||||
@@ -85,26 +85,16 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
|
||||
if (modulesConfig == null)
|
||||
modulesConfig = m_openSim.ConfigSource.Source.AddConfig("Modules");
|
||||
|
||||
Dictionary<RuntimeAddin, IList<int>> loadedModules = new Dictionary<RuntimeAddin, IList<int>>();
|
||||
|
||||
// Scan modules and load all that aren't disabled
|
||||
foreach (TypeExtensionNode node in
|
||||
AddinManager.GetExtensionNodes("/OpenSim/RegionModules"))
|
||||
{
|
||||
IList<int> loadedModuleData;
|
||||
|
||||
if (!loadedModules.ContainsKey(node.Addin))
|
||||
loadedModules.Add(node.Addin, new List<int> { 0, 0, 0 });
|
||||
|
||||
loadedModuleData = loadedModules[node.Addin];
|
||||
|
||||
if (node.Type.GetInterface(typeof(ISharedRegionModule).ToString()) != null)
|
||||
{
|
||||
if (CheckModuleEnabled(node, modulesConfig))
|
||||
{
|
||||
m_log.DebugFormat("[REGIONMODULES]: Found shared region module {0}, class {1}", node.Id, node.Type);
|
||||
m_sharedModules.Add(node);
|
||||
loadedModuleData[0]++;
|
||||
}
|
||||
}
|
||||
else if (node.Type.GetInterface(typeof(INonSharedRegionModule).ToString()) != null)
|
||||
@@ -113,26 +103,14 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
|
||||
{
|
||||
m_log.DebugFormat("[REGIONMODULES]: Found non-shared region module {0}, class {1}", node.Id, node.Type);
|
||||
m_nonSharedModules.Add(node);
|
||||
loadedModuleData[1]++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.WarnFormat("[REGIONMODULES]: Found unknown type of module {0}, class {1}", node.Id, node.Type);
|
||||
loadedModuleData[2]++;
|
||||
m_log.DebugFormat("[REGIONMODULES]: Found unknown type of module {0}, class {1}", node.Id, node.Type);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (KeyValuePair<RuntimeAddin, IList<int>> loadedModuleData in loadedModules)
|
||||
{
|
||||
m_log.InfoFormat(
|
||||
"[REGIONMODULES]: From plugin {0}, (version {1}), loaded {2} modules, {3} shared, {4} non-shared {5} unknown",
|
||||
loadedModuleData.Key.Id,
|
||||
loadedModuleData.Key.Version,
|
||||
loadedModuleData.Value[0] + loadedModuleData.Value[1] + loadedModuleData.Value[2],
|
||||
loadedModuleData.Value[0], loadedModuleData.Value[1], loadedModuleData.Value[2]);
|
||||
}
|
||||
|
||||
// Load and init the module. We try a constructor with a port
|
||||
// if a port was given, fall back to one without if there is
|
||||
// no port or the more specific constructor fails.
|
||||
@@ -237,7 +215,7 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
|
||||
}
|
||||
}
|
||||
|
||||
#region Region Module interfacesController implementation
|
||||
#region IRegionModulesController implementation
|
||||
|
||||
/// <summary>
|
||||
/// Check that the given module is no disabled in the [Modules] section of the config files.
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("OpenSim.ApplicationPlugins.RemoteController")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("http://opensimulator.org")]
|
||||
[assembly: AssemblyProduct("OpenSim")]
|
||||
[assembly: AssemblyCopyright("Copyright OpenSimulator developers © 2012")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("efec6e69-fc4a-4e21-86e6-4a261c12d4db")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
[assembly: AssemblyVersion("0.8.0.*")]
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using System.Net;
|
||||
@@ -51,8 +50,6 @@ using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo;
|
||||
using GridRegion = OpenSim.Services.Interfaces.GridRegion;
|
||||
using PermissionMask = OpenSim.Framework.PermissionMask;
|
||||
using RegionInfo = OpenSim.Framework.RegionInfo;
|
||||
|
||||
namespace OpenSim.ApplicationPlugins.RemoteController
|
||||
{
|
||||
@@ -139,7 +136,6 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||
availableMethods["admin_save_heightmap"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcSaveHeightmapMethod);
|
||||
|
||||
// Agent management
|
||||
availableMethods["admin_get_agents"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcGetAgentsMethod);
|
||||
availableMethods["admin_teleport_agent"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcTeleportAgentMethod);
|
||||
|
||||
// User management
|
||||
@@ -147,7 +143,6 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||
availableMethods["admin_create_user_email"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcCreateUserMethod);
|
||||
availableMethods["admin_exists_user"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcUserExistsMethod);
|
||||
availableMethods["admin_update_user"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcUpdateUserAccountMethod);
|
||||
availableMethods["admin_authenticate_user"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcAuthenticateUserMethod);
|
||||
|
||||
// Region state management
|
||||
availableMethods["admin_load_xml"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcLoadXMLMethod);
|
||||
@@ -160,7 +155,6 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||
availableMethods["admin_acl_add"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcAccessListAdd);
|
||||
availableMethods["admin_acl_remove"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcAccessListRemove);
|
||||
availableMethods["admin_acl_list"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcAccessListList);
|
||||
availableMethods["admin_estate_reload"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcEstateReload);
|
||||
|
||||
// Either enable full remote functionality or just selected features
|
||||
string enabledMethods = m_config.GetString("enabled_methods", "all");
|
||||
@@ -330,26 +324,18 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||
// k, (string)requestData[k], ((string)requestData[k]).Length);
|
||||
// }
|
||||
|
||||
CheckStringParameters(requestData, responseData, new string[] { "filename" });
|
||||
CheckStringParameters(requestData, responseData, new string[] {"filename", "regionid"});
|
||||
CheckRegionParams(requestData, responseData);
|
||||
|
||||
Scene scene = null;
|
||||
GetSceneFromRegionParams(requestData, responseData, out scene);
|
||||
string file = (string)requestData["filename"];
|
||||
|
||||
if (scene != null)
|
||||
{
|
||||
string file = (string)requestData["filename"];
|
||||
responseData["accepted"] = true;
|
||||
|
||||
responseData["accepted"] = true;
|
||||
LoadHeightmap(file, scene.RegionInfo.RegionID);
|
||||
|
||||
LoadHeightmap(file, scene.RegionInfo.RegionID);
|
||||
|
||||
responseData["success"] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
responseData["success"] = false;
|
||||
}
|
||||
responseData["success"] = true;
|
||||
|
||||
m_log.Info("[RADMIN]: Load height maps request complete");
|
||||
}
|
||||
@@ -363,30 +349,23 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||
|
||||
// m_log.DebugFormat("[RADMIN]: Save Terrain: XmlRpc {0}", request.ToString());
|
||||
|
||||
CheckStringParameters(requestData, responseData, new string[] { "filename" });
|
||||
CheckStringParameters(requestData, responseData, new string[] { "filename", "regionid" });
|
||||
CheckRegionParams(requestData, responseData);
|
||||
|
||||
Scene scene = null;
|
||||
GetSceneFromRegionParams(requestData, responseData, out scene);
|
||||
Scene region = null;
|
||||
GetSceneFromRegionParams(requestData, responseData, out region);
|
||||
|
||||
if (scene != null)
|
||||
{
|
||||
string file = (string)requestData["filename"];
|
||||
m_log.InfoFormat("[RADMIN]: Terrain Saving: {0}", file);
|
||||
string file = (string)requestData["filename"];
|
||||
m_log.InfoFormat("[RADMIN]: Terrain Saving: {0}", file);
|
||||
|
||||
responseData["accepted"] = true;
|
||||
responseData["accepted"] = true;
|
||||
|
||||
ITerrainModule terrainModule = scene.RequestModuleInterface<ITerrainModule>();
|
||||
if (null == terrainModule) throw new Exception("terrain module not available");
|
||||
ITerrainModule terrainModule = region.RequestModuleInterface<ITerrainModule>();
|
||||
if (null == terrainModule) throw new Exception("terrain module not available");
|
||||
|
||||
terrainModule.SaveToFile(file);
|
||||
terrainModule.SaveToFile(file);
|
||||
|
||||
responseData["success"] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
responseData["success"] = false;
|
||||
}
|
||||
responseData["success"] = true;
|
||||
|
||||
m_log.Info("[RADMIN]: Save height maps request complete");
|
||||
}
|
||||
@@ -593,7 +572,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||
|
||||
region.ExternalHostName = (string) requestData["external_address"];
|
||||
|
||||
bool persist = Convert.ToBoolean(requestData["persist"]);
|
||||
bool persist = Convert.ToBoolean((string) requestData["persist"]);
|
||||
if (persist)
|
||||
{
|
||||
// default place for region configuration files is in the
|
||||
@@ -719,7 +698,6 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||
|
||||
IScene newScene;
|
||||
m_application.CreateRegion(region, out newScene);
|
||||
newScene.Start();
|
||||
|
||||
// If an access specification was provided, use it.
|
||||
// Otherwise accept the default.
|
||||
@@ -750,6 +728,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||
responseData["success"] = true;
|
||||
responseData["region_name"] = region.RegionName;
|
||||
responseData["region_id"] = region.RegionID.ToString();
|
||||
responseData["region_uuid"] = region.RegionID.ToString(); //Deprecate July 2012
|
||||
|
||||
m_log.Info("[RADMIN]: CreateRegion: request complete");
|
||||
}
|
||||
@@ -1003,8 +982,8 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||
string lastName = (string) requestData["user_lastname"];
|
||||
string password = (string) requestData["user_password"];
|
||||
|
||||
uint regionXLocation = Convert.ToUInt32(requestData["start_region_x"]);
|
||||
uint regionYLocation = Convert.ToUInt32(requestData["start_region_y"]);
|
||||
uint regionXLocation = Convert.ToUInt32((Int32) requestData["start_region_x"]);
|
||||
uint regionYLocation = Convert.ToUInt32((Int32) requestData["start_region_y"]);
|
||||
|
||||
string email = ""; // empty string for email
|
||||
if (requestData.Contains("user_email"))
|
||||
@@ -1022,7 +1001,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||
// Set home position
|
||||
|
||||
GridRegion home = scene.GridService.GetRegionByPosition(scopeID,
|
||||
(int)Util.RegionToWorldLoc(regionXLocation), (int)Util.RegionToWorldLoc(regionYLocation));
|
||||
(int)(regionXLocation * Constants.RegionSize), (int)(regionYLocation * Constants.RegionSize));
|
||||
if (null == home)
|
||||
{
|
||||
m_log.WarnFormat("[RADMIN]: Unable to set home region for newly created user account {0} {1}", firstName, lastName);
|
||||
@@ -1114,7 +1093,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||
{
|
||||
GridUserInfo userInfo = m_application.SceneManager.CurrentOrFirstScene.GridUserService.GetGridUserInfo(account.PrincipalID.ToString());
|
||||
if (userInfo != null)
|
||||
responseData["lastlogin"] = Util.ToUnixTime(userInfo.Login);
|
||||
responseData["lastlogin"] = userInfo.Login;
|
||||
else
|
||||
responseData["lastlogin"] = 0;
|
||||
|
||||
@@ -1201,9 +1180,9 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||
|
||||
if (requestData.ContainsKey("user_password")) password = (string) requestData["user_password"];
|
||||
if (requestData.ContainsKey("start_region_x"))
|
||||
regionXLocation = Convert.ToUInt32(requestData["start_region_x"]);
|
||||
regionXLocation = Convert.ToUInt32((Int32) requestData["start_region_x"]);
|
||||
if (requestData.ContainsKey("start_region_y"))
|
||||
regionYLocation = Convert.ToUInt32(requestData["start_region_y"]);
|
||||
regionYLocation = Convert.ToUInt32((Int32) requestData["start_region_y"]);
|
||||
|
||||
// if (requestData.ContainsKey("start_lookat_x"))
|
||||
// ulaX = Convert.ToUInt32((Int32) requestData["start_lookat_x"]);
|
||||
@@ -1252,7 +1231,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||
if ((null != regionXLocation) && (null != regionYLocation))
|
||||
{
|
||||
GridRegion home = scene.GridService.GetRegionByPosition(scopeID,
|
||||
(int)Util.RegionToWorldLoc((uint)regionXLocation), (int)Util.RegionToWorldLoc((uint)regionYLocation));
|
||||
(int)(regionXLocation * Constants.RegionSize), (int)(regionYLocation * Constants.RegionSize));
|
||||
if (null == home) {
|
||||
m_log.WarnFormat("[RADMIN]: Unable to set home region for updated user account {0} {1}", firstName, lastName);
|
||||
} else {
|
||||
@@ -1283,139 +1262,6 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Authenticate an user.
|
||||
/// <summary>
|
||||
/// <param name="request">incoming XML RPC request</param>
|
||||
/// <remarks>
|
||||
/// XmlRpcAuthenticateUserMethod takes the following XMLRPC
|
||||
/// parameters
|
||||
/// <list type="table">
|
||||
/// <listheader><term>parameter name</term><description>description</description></listheader>
|
||||
/// <item><term>password</term>
|
||||
/// <description>admin password as set in OpenSim.ini</description></item>
|
||||
/// <item><term>user_firstname</term>
|
||||
/// <description>avatar's first name</description></item>
|
||||
/// <item><term>user_lastname</term>
|
||||
/// <description>avatar's last name</description></item>
|
||||
/// <item><term>user_password</term>
|
||||
/// <description>MD5 hash of avatar's password</description></item>
|
||||
/// <item><term>token_lifetime</term>
|
||||
/// <description>the lifetime of the returned token (upper bounded to 30s)</description></item>
|
||||
/// </list>
|
||||
///
|
||||
/// XmlRpcAuthenticateUserMethod returns
|
||||
/// <list type="table">
|
||||
/// <listheader><term>name</term><description>description</description></listheader>
|
||||
/// <item><term>success</term>
|
||||
/// <description>true or false</description></item>
|
||||
/// <item><term>token</term>
|
||||
/// <description>the authentication token sent by OpenSim</description></item>
|
||||
/// <item><term>error</term>
|
||||
/// <description>error message if success is false</description></item>
|
||||
/// </list>
|
||||
/// </remarks>
|
||||
private void XmlRpcAuthenticateUserMethod(XmlRpcRequest request, XmlRpcResponse response,
|
||||
IPEndPoint remoteClient)
|
||||
{
|
||||
m_log.Info("[RADMIN]: AuthenticateUser: new request");
|
||||
|
||||
var responseData = (Hashtable)response.Value;
|
||||
var requestData = (Hashtable)request.Params[0];
|
||||
|
||||
lock (m_requestLock)
|
||||
{
|
||||
try
|
||||
{
|
||||
CheckStringParameters(requestData, responseData, new[]
|
||||
{
|
||||
"user_firstname",
|
||||
"user_lastname",
|
||||
"user_password",
|
||||
"token_lifetime"
|
||||
});
|
||||
|
||||
var firstName = (string)requestData["user_firstname"];
|
||||
var lastName = (string)requestData["user_lastname"];
|
||||
var password = (string)requestData["user_password"];
|
||||
|
||||
var scene = m_application.SceneManager.CurrentOrFirstScene;
|
||||
|
||||
if (scene.Equals(null))
|
||||
{
|
||||
m_log.Debug("scene does not exist");
|
||||
throw new Exception("Scene does not exist.");
|
||||
}
|
||||
|
||||
var scopeID = scene.RegionInfo.ScopeID;
|
||||
var account = scene.UserAccountService.GetUserAccount(scopeID, firstName, lastName);
|
||||
|
||||
if (account.Equals(null) || account.PrincipalID.Equals(UUID.Zero))
|
||||
{
|
||||
m_log.DebugFormat("avatar {0} {1} does not exist", firstName, lastName);
|
||||
throw new Exception(String.Format("avatar {0} {1} does not exist", firstName, lastName));
|
||||
}
|
||||
|
||||
if (String.IsNullOrEmpty(password))
|
||||
{
|
||||
m_log.DebugFormat("[RADMIN]: AuthenticateUser: no password provided for {0} {1}", firstName,
|
||||
lastName);
|
||||
throw new Exception(String.Format("no password provided for {0} {1}", firstName,
|
||||
lastName));
|
||||
}
|
||||
|
||||
int lifetime;
|
||||
if (int.TryParse((string)requestData["token_lifetime"], NumberStyles.Integer, CultureInfo.InvariantCulture, out lifetime) == false)
|
||||
{
|
||||
m_log.DebugFormat("[RADMIN]: AuthenticateUser: no token lifetime provided for {0} {1}", firstName,
|
||||
lastName);
|
||||
throw new Exception(String.Format("no token lifetime provided for {0} {1}", firstName,
|
||||
lastName));
|
||||
}
|
||||
|
||||
// Upper bound on lifetime set to 30s.
|
||||
if (lifetime > 30)
|
||||
{
|
||||
m_log.DebugFormat("[RADMIN]: AuthenticateUser: token lifetime longer than 30s for {0} {1}", firstName,
|
||||
lastName);
|
||||
throw new Exception(String.Format("token lifetime longer than 30s for {0} {1}", firstName,
|
||||
lastName));
|
||||
}
|
||||
|
||||
var authModule = scene.RequestModuleInterface<IAuthenticationService>();
|
||||
if (authModule == null)
|
||||
{
|
||||
m_log.Debug("[RADMIN]: AuthenticateUser: no authentication module loded");
|
||||
throw new Exception("no authentication module loaded");
|
||||
}
|
||||
|
||||
var token = authModule.Authenticate(account.PrincipalID, password, lifetime);
|
||||
if (String.IsNullOrEmpty(token))
|
||||
{
|
||||
m_log.DebugFormat("[RADMIN]: AuthenticateUser: authentication failed for {0} {1}", firstName,
|
||||
lastName);
|
||||
throw new Exception(String.Format("authentication failed for {0} {1}", firstName,
|
||||
lastName));
|
||||
}
|
||||
|
||||
m_log.DebugFormat("[RADMIN]: AuthenticateUser: account for user {0} {1} identified with token {2}",
|
||||
firstName, lastName, token);
|
||||
|
||||
responseData["token"] = token;
|
||||
responseData["success"] = true;
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
responseData["success"] = false;
|
||||
responseData["error"] = e.Message;
|
||||
throw e;
|
||||
}
|
||||
|
||||
m_log.Info("[RADMIN]: AuthenticateUser: request complete");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Load an OAR file into a region..
|
||||
/// <summary>
|
||||
@@ -1484,11 +1330,8 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||
}
|
||||
|
||||
IRegionArchiverModule archiver = scene.RequestModuleInterface<IRegionArchiverModule>();
|
||||
Dictionary<string, object> archiveOptions = new Dictionary<string,object>();
|
||||
if (mergeOar) archiveOptions.Add("merge", null);
|
||||
if (skipAssets) archiveOptions.Add("skipAssets", null);
|
||||
if (archiver != null)
|
||||
archiver.DearchiveRegion(filename, Guid.Empty, archiveOptions);
|
||||
archiver.DearchiveRegion(filename, mergeOar, skipAssets, Guid.Empty);
|
||||
else
|
||||
throw new Exception("Archiver module not present for scene");
|
||||
|
||||
@@ -1526,8 +1369,6 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||
/// <description>profile url</description></item>
|
||||
/// <item><term>noassets</term>
|
||||
/// <description>true if no assets should be saved</description></item>
|
||||
/// <item><term>all</term>
|
||||
/// <description>true to save all the regions in the simulator</description></item>
|
||||
/// <item><term>perm</term>
|
||||
/// <description>C and/or T</description></item>
|
||||
/// </list>
|
||||
@@ -1547,7 +1388,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||
/// </remarks>
|
||||
private void XmlRpcSaveOARMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
|
||||
{
|
||||
m_log.Info("[RADMIN]: Received Save OAR Request");
|
||||
m_log.Info("[RADMIN]: Received Save OAR Administrator Request");
|
||||
|
||||
Hashtable responseData = (Hashtable)response.Value;
|
||||
Hashtable requestData = (Hashtable)request.Params[0];
|
||||
@@ -1584,23 +1425,12 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||
options["checkPermissions"] = (string)requestData["perm"];
|
||||
}
|
||||
|
||||
if ((string)requestData["all"] == "true")
|
||||
{
|
||||
options["all"] = (string)requestData["all"];
|
||||
}
|
||||
|
||||
IRegionArchiverModule archiver = scene.RequestModuleInterface<IRegionArchiverModule>();
|
||||
|
||||
if (archiver != null)
|
||||
{
|
||||
Guid requestId = Guid.NewGuid();
|
||||
scene.EventManager.OnOarFileSaved += RemoteAdminOarSaveCompleted;
|
||||
|
||||
m_log.InfoFormat(
|
||||
"[RADMIN]: Submitting save OAR request for {0} to file {1}, request ID {2}",
|
||||
scene.Name, filename, requestId);
|
||||
|
||||
archiver.ArchiveRegion(filename, requestId, options);
|
||||
archiver.ArchiveRegion(filename, options);
|
||||
|
||||
lock (m_saveOarLock)
|
||||
Monitor.Wait(m_saveOarLock,5000);
|
||||
@@ -1621,16 +1451,12 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||
throw e;
|
||||
}
|
||||
|
||||
m_log.Info("[RADMIN]: Save OAR Request complete");
|
||||
m_log.Info("[RADMIN]: Save OAR Administrator Request complete");
|
||||
}
|
||||
|
||||
private void RemoteAdminOarSaveCompleted(Guid uuid, string name)
|
||||
{
|
||||
if (name != "")
|
||||
m_log.ErrorFormat("[RADMIN]: Saving of OAR file with request ID {0} failed with message {1}", uuid, name);
|
||||
else
|
||||
m_log.DebugFormat("[RADMIN]: Saved OAR file for request {0}", uuid);
|
||||
|
||||
m_log.DebugFormat("[RADMIN]: File processing complete for {0}", name);
|
||||
lock (m_saveOarLock)
|
||||
Monitor.Pulse(m_saveOarLock);
|
||||
}
|
||||
@@ -1927,87 +1753,6 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||
m_log.Info("[RADMIN]: Access List List Request complete");
|
||||
}
|
||||
|
||||
private void XmlRpcEstateReload(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
|
||||
{
|
||||
m_log.Info("[RADMIN]: Received Estate Reload Request");
|
||||
|
||||
Hashtable responseData = (Hashtable)response.Value;
|
||||
// Hashtable requestData = (Hashtable)request.Params[0];
|
||||
|
||||
m_application.SceneManager.ForEachScene(s =>
|
||||
s.RegionInfo.EstateSettings = m_application.EstateDataService.LoadEstateSettings(s.RegionInfo.RegionID, false)
|
||||
);
|
||||
|
||||
responseData["success"] = true;
|
||||
|
||||
m_log.Info("[RADMIN]: Estate Reload Request complete");
|
||||
}
|
||||
|
||||
private void XmlRpcGetAgentsMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
|
||||
{
|
||||
Hashtable responseData = (Hashtable)response.Value;
|
||||
Hashtable requestData = (Hashtable)request.Params[0];
|
||||
|
||||
bool includeChildren = false;
|
||||
|
||||
if (requestData.Contains("include_children"))
|
||||
bool.TryParse((string)requestData["include_children"], out includeChildren);
|
||||
|
||||
Scene scene;
|
||||
GetSceneFromRegionParams(requestData, responseData, out scene);
|
||||
|
||||
ArrayList xmlRpcRegions = new ArrayList();
|
||||
responseData["regions"] = xmlRpcRegions;
|
||||
|
||||
Hashtable xmlRpcRegion = new Hashtable();
|
||||
xmlRpcRegions.Add(xmlRpcRegion);
|
||||
|
||||
xmlRpcRegion["name"] = scene.Name;
|
||||
xmlRpcRegion["id"] = scene.RegionInfo.RegionID.ToString();
|
||||
|
||||
List<ScenePresence> agents = scene.GetScenePresences();
|
||||
ArrayList xmlrpcAgents = new ArrayList();
|
||||
|
||||
foreach (ScenePresence agent in agents)
|
||||
{
|
||||
if (agent.IsChildAgent && !includeChildren)
|
||||
continue;
|
||||
|
||||
Hashtable xmlRpcAgent = new Hashtable();
|
||||
xmlRpcAgent.Add("name", agent.Name);
|
||||
xmlRpcAgent.Add("id", agent.UUID.ToString());
|
||||
xmlRpcAgent.Add("type", agent.PresenceType.ToString());
|
||||
xmlRpcAgent.Add("current_parcel_id", agent.currentParcelUUID.ToString());
|
||||
|
||||
Vector3 pos = agent.AbsolutePosition;
|
||||
xmlRpcAgent.Add("pos_x", pos.X.ToString());
|
||||
xmlRpcAgent.Add("pos_y", pos.Y.ToString());
|
||||
xmlRpcAgent.Add("pos_z", pos.Z.ToString());
|
||||
|
||||
Vector3 lookAt = agent.Lookat;
|
||||
xmlRpcAgent.Add("lookat_x", lookAt.X.ToString());
|
||||
xmlRpcAgent.Add("lookat_y", lookAt.Y.ToString());
|
||||
xmlRpcAgent.Add("lookat_z", lookAt.Z.ToString());
|
||||
|
||||
Vector3 vel = agent.Velocity;
|
||||
xmlRpcAgent.Add("vel_x", vel.X.ToString());
|
||||
xmlRpcAgent.Add("vel_y", vel.Y.ToString());
|
||||
xmlRpcAgent.Add("vel_z", vel.Z.ToString());
|
||||
|
||||
xmlRpcAgent.Add("is_flying", agent.Flying.ToString());
|
||||
xmlRpcAgent.Add("is_sat_on_ground", agent.SitGround.ToString());
|
||||
xmlRpcAgent.Add("is_sat_on_object", agent.IsSatOnObject.ToString());
|
||||
|
||||
xmlrpcAgents.Add(xmlRpcAgent);
|
||||
}
|
||||
|
||||
m_log.DebugFormat(
|
||||
"[REMOTE ADMIN]: XmlRpcGetAgents found {0} agents in {1}", xmlrpcAgents.Count, scene.Name);
|
||||
|
||||
xmlRpcRegion["agents"] = xmlrpcAgents;
|
||||
responseData["success"] = true;
|
||||
}
|
||||
|
||||
private void XmlRpcTeleportAgentMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
|
||||
{
|
||||
Hashtable responseData = (Hashtable)response.Value;
|
||||
@@ -2129,6 +1874,29 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||
{
|
||||
return;
|
||||
}
|
||||
#region Deprecate July 2012
|
||||
//region_ID, regionid, region_uuid will be deprecated in July 2012!!!!!!
|
||||
else if (requestData.ContainsKey("regionid") &&
|
||||
!String.IsNullOrEmpty((string)requestData["regionid"]))
|
||||
{
|
||||
m_log.WarnFormat("[RADMIN]: Use of parameter regionid will be deprecated as of July 2012. Use region_id instead");
|
||||
}
|
||||
else if (requestData.ContainsKey("region_ID") &&
|
||||
!String.IsNullOrEmpty((string)requestData["region_ID"]))
|
||||
{
|
||||
m_log.WarnFormat("[RADMIN]: Use of parameter region_ID will be deprecated as of July 2012. Use region_id instead");
|
||||
}
|
||||
else if (requestData.ContainsKey("regionID") &&
|
||||
!String.IsNullOrEmpty((string)requestData["regionID"]))
|
||||
{
|
||||
m_log.WarnFormat("[RADMIN]: Use of parameter regionID will be deprecated as of July 2012. Use region_id instead");
|
||||
}
|
||||
else if (requestData.ContainsKey("region_uuid") &&
|
||||
!String.IsNullOrEmpty((string)requestData["region_uuid"]))
|
||||
{
|
||||
m_log.WarnFormat("[RADMIN]: Use of parameter region_uuid will be deprecated as of July 2012. Use region_id instead");
|
||||
}
|
||||
#endregion
|
||||
else
|
||||
{
|
||||
responseData["accepted"] = false;
|
||||
@@ -2150,6 +1918,56 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||
throw new Exception(String.Format("Region ID {0} not found", regionID));
|
||||
}
|
||||
}
|
||||
#region Deprecate July 2012
|
||||
else if (requestData.ContainsKey("regionid") &&
|
||||
!String.IsNullOrEmpty((string)requestData["regionid"]))
|
||||
{
|
||||
m_log.WarnFormat("[RADMIN]: Use of parameter regionid will be deprecated as of July 2012. Use region_id instead");
|
||||
|
||||
UUID regionID = (UUID)(string)requestData["regionid"];
|
||||
if (!m_application.SceneManager.TryGetScene(regionID, out scene))
|
||||
{
|
||||
responseData["error"] = String.Format("Region ID {0} not found", regionID);
|
||||
throw new Exception(String.Format("Region ID {0} not found", regionID));
|
||||
}
|
||||
}
|
||||
else if (requestData.ContainsKey("region_ID") &&
|
||||
!String.IsNullOrEmpty((string)requestData["region_ID"]))
|
||||
{
|
||||
m_log.WarnFormat("[RADMIN]: Use of parameter region_ID will be deprecated as of July 2012. Use region_id instead");
|
||||
|
||||
UUID regionID = (UUID)(string)requestData["region_ID"];
|
||||
if (!m_application.SceneManager.TryGetScene(regionID, out scene))
|
||||
{
|
||||
responseData["error"] = String.Format("Region ID {0} not found", regionID);
|
||||
throw new Exception(String.Format("Region ID {0} not found", regionID));
|
||||
}
|
||||
}
|
||||
else if (requestData.ContainsKey("regionID") &&
|
||||
!String.IsNullOrEmpty((string)requestData["regionID"]))
|
||||
{
|
||||
m_log.WarnFormat("[RADMIN]: Use of parameter regionID will be deprecated as of July 2012. Use region_id instead");
|
||||
|
||||
UUID regionID = (UUID)(string)requestData["regionID"];
|
||||
if (!m_application.SceneManager.TryGetScene(regionID, out scene))
|
||||
{
|
||||
responseData["error"] = String.Format("Region ID {0} not found", regionID);
|
||||
throw new Exception(String.Format("Region ID {0} not found", regionID));
|
||||
}
|
||||
}
|
||||
else if (requestData.ContainsKey("region_uuid") &&
|
||||
!String.IsNullOrEmpty((string)requestData["region_uuid"]))
|
||||
{
|
||||
m_log.WarnFormat("[RADMIN]: Use of parameter region_uuid will be deprecated as of July 2012. Use region_id instead");
|
||||
|
||||
UUID regionID = (UUID)(string)requestData["region_uuid"];
|
||||
if (!m_application.SceneManager.TryGetScene(regionID, out scene))
|
||||
{
|
||||
responseData["error"] = String.Format("Region ID {0} not found", regionID);
|
||||
throw new Exception(String.Format("Region ID {0} not found", regionID));
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
else if (requestData.ContainsKey("region_name") &&
|
||||
!String.IsNullOrEmpty((string)requestData["region_name"]))
|
||||
{
|
||||
@@ -2563,6 +2381,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||
destinationItem.Description = item.Description;
|
||||
destinationItem.InvType = item.InvType;
|
||||
destinationItem.CreatorId = item.CreatorId;
|
||||
destinationItem.CreatorIdAsUuid = item.CreatorIdAsUuid;
|
||||
destinationItem.CreatorData = item.CreatorData;
|
||||
destinationItem.NextPermissions = item.NextPermissions;
|
||||
destinationItem.CurrentPermissions = item.CurrentPermissions;
|
||||
@@ -2617,6 +2436,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||
destinationItem.Description = item.Description;
|
||||
destinationItem.InvType = item.InvType;
|
||||
destinationItem.CreatorId = item.CreatorId;
|
||||
destinationItem.CreatorIdAsUuid = item.CreatorIdAsUuid;
|
||||
destinationItem.CreatorData = item.CreatorData;
|
||||
destinationItem.NextPermissions = item.NextPermissions;
|
||||
destinationItem.CurrentPermissions = item.CurrentPermissions;
|
||||
@@ -2729,6 +2549,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||
destinationItem.Description = item.Description;
|
||||
destinationItem.InvType = item.InvType;
|
||||
destinationItem.CreatorId = item.CreatorId;
|
||||
destinationItem.CreatorIdAsUuid = item.CreatorIdAsUuid;
|
||||
destinationItem.CreatorData = item.CreatorData;
|
||||
destinationItem.NextPermissions = item.NextPermissions;
|
||||
destinationItem.CurrentPermissions = item.CurrentPermissions;
|
||||
@@ -2766,13 +2587,15 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||
/// </summary>
|
||||
private void ApplyNextOwnerPermissions(InventoryItemBase item)
|
||||
{
|
||||
if (item.InvType == (int)InventoryType.Object)
|
||||
if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0)
|
||||
{
|
||||
uint perms = item.CurrentPermissions;
|
||||
PermissionsUtil.ApplyFoldedPermissions(item.CurrentPermissions, ref perms);
|
||||
item.CurrentPermissions = perms;
|
||||
if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0)
|
||||
item.CurrentPermissions &= ~(uint)PermissionMask.Copy;
|
||||
if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0)
|
||||
item.CurrentPermissions &= ~(uint)PermissionMask.Transfer;
|
||||
if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
|
||||
item.CurrentPermissions &= ~(uint)PermissionMask.Modify;
|
||||
}
|
||||
|
||||
item.CurrentPermissions &= item.NextPermissions;
|
||||
item.BasePermissions &= item.NextPermissions;
|
||||
item.EveryOnePermissions &= item.NextPermissions;
|
||||
@@ -2884,7 +2707,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||
// Set home position
|
||||
|
||||
GridRegion home = scene.GridService.GetRegionByPosition(scopeID,
|
||||
(int)Util.RegionToWorldLoc(regionXLocation), (int)Util.RegionToWorldLoc(regionYLocation));
|
||||
(int)(regionXLocation * Constants.RegionSize), (int)(regionYLocation * Constants.RegionSize));
|
||||
if (null == home) {
|
||||
m_log.WarnFormat("[RADMIN]: Unable to set home region for newly created user account {0} {1}", names[0], names[1]);
|
||||
} else {
|
||||
@@ -3032,6 +2855,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||
inventoryItem.Description = GetStringAttribute(item,"desc","");
|
||||
inventoryItem.InvType = GetIntegerAttribute(item,"invtype",-1);
|
||||
inventoryItem.CreatorId = GetStringAttribute(item,"creatorid","");
|
||||
inventoryItem.CreatorIdAsUuid = (UUID)GetStringAttribute(item,"creatoruuid","");
|
||||
inventoryItem.CreatorData = GetStringAttribute(item, "creatordata", "");
|
||||
inventoryItem.NextPermissions = GetUnsignedAttribute(perms, "next", 0x7fffffff);
|
||||
inventoryItem.CurrentPermissions = GetUnsignedAttribute(perms,"current",0x7fffffff);
|
||||
|
||||
@@ -25,23 +25,19 @@
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using OpenMetaverse;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using pCampBot.Interfaces;
|
||||
|
||||
namespace pCampBot
|
||||
namespace OpenSim.ApplicationPlugins.Rest.Inventory
|
||||
{
|
||||
/// <summary>
|
||||
/// Do nothing
|
||||
/// This interface represents the boundary between the general purpose
|
||||
/// REST plugin handling, and the functionally specific handlers. The
|
||||
/// handler knows only to initialize and terminate all such handlers
|
||||
/// that it finds. Implementing this interface identifies the class as
|
||||
/// a REST handler implementation.
|
||||
/// </summary>
|
||||
public class NoneBehaviour : AbstractBehaviour
|
||||
|
||||
internal interface IRest
|
||||
{
|
||||
public NoneBehaviour()
|
||||
{
|
||||
AbbreviatedName = "n";
|
||||
Name = "None";
|
||||
}
|
||||
void Initialize();
|
||||
void Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -25,35 +25,35 @@
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Servers.HttpServer;
|
||||
|
||||
namespace OpenSim.Data
|
||||
namespace OpenSim.ApplicationPlugins.Rest.Inventory
|
||||
{
|
||||
// This MUST be a ref type!
|
||||
public class HGTravelingData
|
||||
{
|
||||
public UUID SessionID;
|
||||
public UUID UserID;
|
||||
public Dictionary<string, string> Data;
|
||||
|
||||
public HGTravelingData()
|
||||
{
|
||||
Data = new Dictionary<string, string>();
|
||||
}
|
||||
}
|
||||
/// <remarks>
|
||||
/// The handler delegates are not noteworthy. The allocator allows
|
||||
/// a given handler to optionally subclass the base RequestData
|
||||
/// structure to carry any locally required per-request state
|
||||
/// needed.
|
||||
/// </remarks>
|
||||
|
||||
public delegate void RestMethodHandler(RequestData rdata);
|
||||
public delegate RequestData RestMethodAllocator(OSHttpRequest request, OSHttpResponse response, string path);
|
||||
|
||||
/// <summary>
|
||||
/// An interface for connecting to the user grid datastore
|
||||
/// This interface exports the generic plugin-handling services
|
||||
/// available to each loaded REST services module (IRest implementation)
|
||||
/// </summary>
|
||||
public interface IHGTravelingData
|
||||
|
||||
internal interface IRestHandler
|
||||
{
|
||||
HGTravelingData Get(UUID sessionID);
|
||||
HGTravelingData[] GetSessions(UUID userID);
|
||||
bool Store(HGTravelingData data);
|
||||
bool Delete(UUID sessionID);
|
||||
void DeleteOld();
|
||||
|
||||
string MsgId { get; }
|
||||
string RequestId { get; }
|
||||
|
||||
void AddPathHandler(RestMethodHandler mh, string path, RestMethodAllocator ma);
|
||||
void AddStreamHandler(string httpMethod, string path, RestMethod method);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
1465
OpenSim/ApplicationPlugins/Rest/Inventory/RequestData.cs
Normal file
1465
OpenSim/ApplicationPlugins/Rest/Inventory/RequestData.cs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,11 @@
|
||||
<Addin id="OpenSim.ApplicationPlugins.Rest.Inventory" version="0.1">
|
||||
<Runtime>
|
||||
<Import assembly="OpenSim.ApplicationPlugins.Rest.Inventory.dll"/>
|
||||
</Runtime>
|
||||
<Dependencies>
|
||||
<Addin id="OpenSim" version="0.5" />
|
||||
</Dependencies>
|
||||
<Extension path = "/OpenSim/Startup">
|
||||
<Plugin id="RestInventory" type="OpenSim.ApplicationPlugins.Rest.Inventory.RestHandler" />
|
||||
</Extension>
|
||||
</Addin>
|
||||
551
OpenSim/ApplicationPlugins/Rest/Inventory/Rest.cs
Normal file
551
OpenSim/ApplicationPlugins/Rest/Inventory/Rest.cs
Normal file
@@ -0,0 +1,551 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Communications;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using IAvatarService = OpenSim.Services.Interfaces.IAvatarService;
|
||||
|
||||
namespace OpenSim.ApplicationPlugins.Rest.Inventory
|
||||
{
|
||||
public class Rest
|
||||
{
|
||||
internal static readonly ILog Log =
|
||||
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
internal static bool DEBUG = Log.IsDebugEnabled;
|
||||
|
||||
/// <summary>
|
||||
/// Supported authentication schemes
|
||||
/// </summary>
|
||||
|
||||
public const string AS_BASIC = "Basic"; // simple user/password verification
|
||||
public const string AS_DIGEST = "Digest"; // password safe authentication
|
||||
|
||||
/// Supported Digest algorithms
|
||||
|
||||
public const string Digest_MD5 = "MD5"; // assumed default if omitted
|
||||
public const string Digest_MD5Sess = "MD5-sess"; // session-span - not good for REST?
|
||||
|
||||
public const string Qop_Auth = "auth"; // authentication only
|
||||
public const string Qop_Int = "auth-int"; // TODO
|
||||
|
||||
/// <summary>
|
||||
/// These values have a single value for the whole
|
||||
/// domain and lifetime of the plugin handler. We
|
||||
/// make them static for ease of reference within
|
||||
/// the assembly. These are initialized by the
|
||||
/// RestHandler class during start-up.
|
||||
/// </summary>
|
||||
|
||||
internal static IRestHandler Plugin = null;
|
||||
internal static OpenSimBase main = null;
|
||||
internal static string Prefix = null;
|
||||
internal static IConfig Config = null;
|
||||
internal static string GodKey = null;
|
||||
internal static bool Authenticate = true;
|
||||
internal static bool Secure = true;
|
||||
internal static bool ExtendedEscape = true;
|
||||
internal static bool DumpAsset = false;
|
||||
internal static bool Fill = true;
|
||||
internal static bool FlushEnabled = true;
|
||||
internal static string Realm = "OpenSim REST";
|
||||
internal static string Scheme = AS_BASIC;
|
||||
internal static int DumpLineSize = 32; // Should be a multiple of 16 or (possibly) 4
|
||||
|
||||
/// <summary>
|
||||
/// These are all dependent upon the Comms manager
|
||||
/// being initialized. So they have to be properties
|
||||
/// because the comms manager is now a module and is
|
||||
/// not guaranteed to be there when the rest handler
|
||||
/// initializes.
|
||||
/// </summary>
|
||||
|
||||
internal static IInventoryService InventoryServices
|
||||
{
|
||||
get { return main.SceneManager.CurrentOrFirstScene.InventoryService; }
|
||||
}
|
||||
|
||||
internal static IUserAccountService UserServices
|
||||
{
|
||||
get { return main.SceneManager.CurrentOrFirstScene.UserAccountService; }
|
||||
}
|
||||
|
||||
internal static IAuthenticationService AuthServices
|
||||
{
|
||||
get { return main.SceneManager.CurrentOrFirstScene.AuthenticationService; }
|
||||
}
|
||||
|
||||
internal static IAvatarService AvatarServices
|
||||
{
|
||||
get { return main.SceneManager.CurrentOrFirstScene.AvatarService; }
|
||||
}
|
||||
|
||||
internal static IAssetService AssetServices
|
||||
{
|
||||
get { return main.SceneManager.CurrentOrFirstScene.AssetService; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// HTTP requires that status information be generated for PUT
|
||||
/// and POST opertaions. This is in support of that. The
|
||||
/// operation verb gets substituted into the first string,
|
||||
/// and the completion code is inserted into the tail. The
|
||||
/// strings are put here to encourage consistency.
|
||||
/// </summary>
|
||||
|
||||
internal static string statusHead = "<html><body><title>{0} status</title><break>";
|
||||
internal static string statusTail = "</body></html>";
|
||||
|
||||
internal static Dictionary<int,string> HttpStatusDesc;
|
||||
|
||||
static Rest()
|
||||
{
|
||||
HttpStatusDesc = new Dictionary<int,string>();
|
||||
if (HttpStatusCodeArray.Length != HttpStatusDescArray.Length)
|
||||
{
|
||||
Log.ErrorFormat("{0} HTTP Status Code and Description arrays do not match");
|
||||
throw new Exception("HTTP Status array discrepancy");
|
||||
}
|
||||
|
||||
// Repackage the data into something more tractable. The sparse
|
||||
// nature of HTTP return codes makes an array a bad choice.
|
||||
|
||||
for (int i=0; i<HttpStatusCodeArray.Length; i++)
|
||||
{
|
||||
HttpStatusDesc.Add(HttpStatusCodeArray[i], HttpStatusDescArray[i]);
|
||||
}
|
||||
}
|
||||
|
||||
internal static int CreationDate
|
||||
{
|
||||
get { return (int) (DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds; }
|
||||
}
|
||||
|
||||
internal static string MsgId
|
||||
{
|
||||
get { return Plugin.MsgId; }
|
||||
}
|
||||
|
||||
internal static string RequestId
|
||||
{
|
||||
get { return Plugin.RequestId; }
|
||||
}
|
||||
|
||||
internal static Encoding Encoding = Util.UTF8;
|
||||
|
||||
/// <summary>
|
||||
/// Version control for REST implementation. This
|
||||
/// refers to the overall infrastructure represented
|
||||
/// by the following classes
|
||||
/// RequestData
|
||||
/// RequestInventoryPlugin
|
||||
/// Rest
|
||||
/// It does no describe implementation classes such as
|
||||
/// RestInventoryServices, which may morph much more
|
||||
/// often. Such classes ARE dependent upon this however
|
||||
/// and should check it in their Initialize method.
|
||||
/// </summary>
|
||||
|
||||
public static readonly float Version = 1.0F;
|
||||
public const string Name = "REST 1.0";
|
||||
|
||||
/// <summary>
|
||||
/// Currently defined HTTP methods.
|
||||
/// Only GET and HEAD are required to be
|
||||
/// supported by all servers. See Respond
|
||||
/// to see how these are handled.
|
||||
/// </summary>
|
||||
|
||||
// REST AGENT 1.0 interpretations
|
||||
public const string GET = "get"; // information retrieval - server state unchanged
|
||||
public const string HEAD = "head"; // same as get except only the headers are returned.
|
||||
public const string POST = "post"; // Replace the URI designated resource with the entity.
|
||||
public const string PUT = "put"; // Add the entity to the context represented by the URI
|
||||
public const string DELETE = "delete"; // Remove the URI designated resource from the server.
|
||||
|
||||
public const string OPTIONS = "options"; //
|
||||
public const string TRACE = "trace"; //
|
||||
public const string CONNECT = "connect"; //
|
||||
|
||||
// Define this in one place...
|
||||
|
||||
public const string UrlPathSeparator = "/";
|
||||
public const string UrlMethodSeparator = ":";
|
||||
|
||||
// Redirection qualifications
|
||||
|
||||
public const bool PERMANENT = false;
|
||||
public const bool TEMPORARY = true;
|
||||
|
||||
// Constant arrays used by String.Split
|
||||
|
||||
public static readonly char C_SPACE = ' ';
|
||||
public static readonly char C_SLASH = '/';
|
||||
public static readonly char C_PATHSEP = '/';
|
||||
public static readonly char C_COLON = ':';
|
||||
public static readonly char C_PLUS = '+';
|
||||
public static readonly char C_PERIOD = '.';
|
||||
public static readonly char C_COMMA = ',';
|
||||
public static readonly char C_DQUOTE = '"';
|
||||
|
||||
public static readonly string CS_SPACE = " ";
|
||||
public static readonly string CS_SLASH = "/";
|
||||
public static readonly string CS_PATHSEP = "/";
|
||||
public static readonly string CS_COLON = ":";
|
||||
public static readonly string CS_PLUS = "+";
|
||||
public static readonly string CS_PERIOD = ".";
|
||||
public static readonly string CS_COMMA = ",";
|
||||
public static readonly string CS_DQUOTE = "\"";
|
||||
|
||||
public static readonly char[] CA_SPACE = { C_SPACE };
|
||||
public static readonly char[] CA_SLASH = { C_SLASH };
|
||||
public static readonly char[] CA_PATHSEP = { C_PATHSEP };
|
||||
public static readonly char[] CA_COLON = { C_COLON };
|
||||
public static readonly char[] CA_PERIOD = { C_PERIOD };
|
||||
public static readonly char[] CA_PLUS = { C_PLUS };
|
||||
public static readonly char[] CA_COMMA = { C_COMMA };
|
||||
public static readonly char[] CA_DQUOTE = { C_DQUOTE };
|
||||
|
||||
// HTTP Code Values (in value order)
|
||||
|
||||
public const int HttpStatusCodeContinue = 100;
|
||||
public const int HttpStatusCodeSwitchingProtocols = 101;
|
||||
|
||||
public const int HttpStatusCodeOK = 200;
|
||||
public const int HttpStatusCodeCreated = 201;
|
||||
public const int HttpStatusCodeAccepted = 202;
|
||||
public const int HttpStatusCodeNonAuthoritative = 203;
|
||||
public const int HttpStatusCodeNoContent = 204;
|
||||
public const int HttpStatusCodeResetContent = 205;
|
||||
public const int HttpStatusCodePartialContent = 206;
|
||||
|
||||
public const int HttpStatusCodeMultipleChoices = 300;
|
||||
public const int HttpStatusCodePermanentRedirect = 301;
|
||||
public const int HttpStatusCodeFound = 302;
|
||||
public const int HttpStatusCodeSeeOther = 303;
|
||||
public const int HttpStatusCodeNotModified = 304;
|
||||
public const int HttpStatusCodeUseProxy = 305;
|
||||
public const int HttpStatusCodeReserved306 = 306;
|
||||
public const int HttpStatusCodeTemporaryRedirect = 307;
|
||||
|
||||
public const int HttpStatusCodeBadRequest = 400;
|
||||
public const int HttpStatusCodeNotAuthorized = 401;
|
||||
public const int HttpStatusCodePaymentRequired = 402;
|
||||
public const int HttpStatusCodeForbidden = 403;
|
||||
public const int HttpStatusCodeNotFound = 404;
|
||||
public const int HttpStatusCodeMethodNotAllowed = 405;
|
||||
public const int HttpStatusCodeNotAcceptable = 406;
|
||||
public const int HttpStatusCodeProxyAuthenticate = 407;
|
||||
public const int HttpStatusCodeTimeOut = 408;
|
||||
public const int HttpStatusCodeConflict = 409;
|
||||
public const int HttpStatusCodeGone = 410;
|
||||
public const int HttpStatusCodeLengthRequired = 411;
|
||||
public const int HttpStatusCodePreconditionFailed = 412;
|
||||
public const int HttpStatusCodeEntityTooLarge = 413;
|
||||
public const int HttpStatusCodeUriTooLarge = 414;
|
||||
public const int HttpStatusCodeUnsupportedMedia = 415;
|
||||
public const int HttpStatusCodeRangeNotSatsified = 416;
|
||||
public const int HttpStatusCodeExpectationFailed = 417;
|
||||
|
||||
public const int HttpStatusCodeServerError = 500;
|
||||
public const int HttpStatusCodeNotImplemented = 501;
|
||||
public const int HttpStatusCodeBadGateway = 502;
|
||||
public const int HttpStatusCodeServiceUnavailable = 503;
|
||||
public const int HttpStatusCodeGatewayTimeout = 504;
|
||||
public const int HttpStatusCodeHttpVersionError = 505;
|
||||
|
||||
public static readonly int[] HttpStatusCodeArray = {
|
||||
HttpStatusCodeContinue,
|
||||
HttpStatusCodeSwitchingProtocols,
|
||||
HttpStatusCodeOK,
|
||||
HttpStatusCodeCreated,
|
||||
HttpStatusCodeAccepted,
|
||||
HttpStatusCodeNonAuthoritative,
|
||||
HttpStatusCodeNoContent,
|
||||
HttpStatusCodeResetContent,
|
||||
HttpStatusCodePartialContent,
|
||||
HttpStatusCodeMultipleChoices,
|
||||
HttpStatusCodePermanentRedirect,
|
||||
HttpStatusCodeFound,
|
||||
HttpStatusCodeSeeOther,
|
||||
HttpStatusCodeNotModified,
|
||||
HttpStatusCodeUseProxy,
|
||||
HttpStatusCodeReserved306,
|
||||
HttpStatusCodeTemporaryRedirect,
|
||||
HttpStatusCodeBadRequest,
|
||||
HttpStatusCodeNotAuthorized,
|
||||
HttpStatusCodePaymentRequired,
|
||||
HttpStatusCodeForbidden,
|
||||
HttpStatusCodeNotFound,
|
||||
HttpStatusCodeMethodNotAllowed,
|
||||
HttpStatusCodeNotAcceptable,
|
||||
HttpStatusCodeProxyAuthenticate,
|
||||
HttpStatusCodeTimeOut,
|
||||
HttpStatusCodeConflict,
|
||||
HttpStatusCodeGone,
|
||||
HttpStatusCodeLengthRequired,
|
||||
HttpStatusCodePreconditionFailed,
|
||||
HttpStatusCodeEntityTooLarge,
|
||||
HttpStatusCodeUriTooLarge,
|
||||
HttpStatusCodeUnsupportedMedia,
|
||||
HttpStatusCodeRangeNotSatsified,
|
||||
HttpStatusCodeExpectationFailed,
|
||||
HttpStatusCodeServerError,
|
||||
HttpStatusCodeNotImplemented,
|
||||
HttpStatusCodeBadGateway,
|
||||
HttpStatusCodeServiceUnavailable,
|
||||
HttpStatusCodeGatewayTimeout,
|
||||
HttpStatusCodeHttpVersionError
|
||||
};
|
||||
|
||||
// HTTP Status Descriptions (in status code order)
|
||||
// This array must be kept strictly consistent with respect
|
||||
// to the status code array above.
|
||||
|
||||
public static readonly string[] HttpStatusDescArray = {
|
||||
"Continue Request",
|
||||
"Switching Protocols",
|
||||
"OK",
|
||||
"CREATED",
|
||||
"ACCEPTED",
|
||||
"NON-AUTHORITATIVE INFORMATION",
|
||||
"NO CONTENT",
|
||||
"RESET CONTENT",
|
||||
"PARTIAL CONTENT",
|
||||
"MULTIPLE CHOICES",
|
||||
"PERMANENT REDIRECT",
|
||||
"FOUND",
|
||||
"SEE OTHER",
|
||||
"NOT MODIFIED",
|
||||
"USE PROXY",
|
||||
"RESERVED CODE 306",
|
||||
"TEMPORARY REDIRECT",
|
||||
"BAD REQUEST",
|
||||
"NOT AUTHORIZED",
|
||||
"PAYMENT REQUIRED",
|
||||
"FORBIDDEN",
|
||||
"NOT FOUND",
|
||||
"METHOD NOT ALLOWED",
|
||||
"NOT ACCEPTABLE",
|
||||
"PROXY AUTHENTICATION REQUIRED",
|
||||
"TIMEOUT",
|
||||
"CONFLICT",
|
||||
"GONE",
|
||||
"LENGTH REQUIRED",
|
||||
"PRECONDITION FAILED",
|
||||
"ENTITY TOO LARGE",
|
||||
"URI TOO LARGE",
|
||||
"UNSUPPORTED MEDIA",
|
||||
"RANGE NOT SATISFIED",
|
||||
"EXPECTATION FAILED",
|
||||
"SERVER ERROR",
|
||||
"NOT IMPLEMENTED",
|
||||
"BAD GATEWAY",
|
||||
"SERVICE UNAVAILABLE",
|
||||
"GATEWAY TIMEOUT",
|
||||
"HTTP VERSION NOT SUPPORTED"
|
||||
};
|
||||
|
||||
// HTTP Headers
|
||||
|
||||
public const string HttpHeaderAccept = "Accept";
|
||||
public const string HttpHeaderAcceptCharset = "Accept-Charset";
|
||||
public const string HttpHeaderAcceptEncoding = "Accept-Encoding";
|
||||
public const string HttpHeaderAcceptLanguage = "Accept-Language";
|
||||
public const string HttpHeaderAcceptRanges = "Accept-Ranges";
|
||||
public const string HttpHeaderAge = "Age";
|
||||
public const string HttpHeaderAllow = "Allow";
|
||||
public const string HttpHeaderAuthorization = "Authorization";
|
||||
public const string HttpHeaderCacheControl = "Cache-Control";
|
||||
public const string HttpHeaderConnection = "Connection";
|
||||
public const string HttpHeaderContentEncoding = "Content-Encoding";
|
||||
public const string HttpHeaderContentLanguage = "Content-Language";
|
||||
public const string HttpHeaderContentLength = "Content-Length";
|
||||
public const string HttpHeaderContentLocation = "Content-Location";
|
||||
public const string HttpHeaderContentMD5 = "Content-MD5";
|
||||
public const string HttpHeaderContentRange = "Content-Range";
|
||||
public const string HttpHeaderContentType = "Content-Type";
|
||||
public const string HttpHeaderDate = "Date";
|
||||
public const string HttpHeaderETag = "ETag";
|
||||
public const string HttpHeaderExpect = "Expect";
|
||||
public const string HttpHeaderExpires = "Expires";
|
||||
public const string HttpHeaderFrom = "From";
|
||||
public const string HttpHeaderHost = "Host";
|
||||
public const string HttpHeaderIfMatch = "If-Match";
|
||||
public const string HttpHeaderIfModifiedSince = "If-Modified-Since";
|
||||
public const string HttpHeaderIfNoneMatch = "If-None-Match";
|
||||
public const string HttpHeaderIfRange = "If-Range";
|
||||
public const string HttpHeaderIfUnmodifiedSince = "If-Unmodified-Since";
|
||||
public const string HttpHeaderLastModified = "Last-Modified";
|
||||
public const string HttpHeaderLocation = "Location";
|
||||
public const string HttpHeaderMaxForwards = "Max-Forwards";
|
||||
public const string HttpHeaderPragma = "Pragma";
|
||||
public const string HttpHeaderProxyAuthenticate = "Proxy-Authenticate";
|
||||
public const string HttpHeaderProxyAuthorization = "Proxy-Authorization";
|
||||
public const string HttpHeaderRange = "Range";
|
||||
public const string HttpHeaderReferer = "Referer";
|
||||
public const string HttpHeaderRetryAfter = "Retry-After";
|
||||
public const string HttpHeaderServer = "Server";
|
||||
public const string HttpHeaderTE = "TE";
|
||||
public const string HttpHeaderTrailer = "Trailer";
|
||||
public const string HttpHeaderTransferEncoding = "Transfer-Encoding";
|
||||
public const string HttpHeaderUpgrade = "Upgrade";
|
||||
public const string HttpHeaderUserAgent = "User-Agent";
|
||||
public const string HttpHeaderVary = "Vary";
|
||||
public const string HttpHeaderVia = "Via";
|
||||
public const string HttpHeaderWarning = "Warning";
|
||||
public const string HttpHeaderWWWAuthenticate = "WWW-Authenticate";
|
||||
|
||||
/// Utility routines
|
||||
|
||||
public static string StringToBase64(string str)
|
||||
{
|
||||
try
|
||||
{
|
||||
byte[] encData_byte = new byte[str.Length];
|
||||
encData_byte = Util.UTF8.GetBytes(str);
|
||||
return Convert.ToBase64String(encData_byte);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return String.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
public static string Base64ToString(string str)
|
||||
{
|
||||
try
|
||||
{
|
||||
return Util.Base64ToString(str);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return String.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
private const string hvals = "0123456789abcdef";
|
||||
|
||||
public static int Hex2Int(string hex)
|
||||
{
|
||||
int val = 0;
|
||||
int sum = 0;
|
||||
string tmp = null;
|
||||
|
||||
if (hex != null)
|
||||
{
|
||||
tmp = hex.ToLower();
|
||||
for (int i = 0; i < tmp.Length; i++)
|
||||
{
|
||||
val = hvals.IndexOf(tmp[i]);
|
||||
if (val == -1)
|
||||
break;
|
||||
sum *= 16;
|
||||
sum += val;
|
||||
}
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
// Nonce management
|
||||
|
||||
public static string NonceGenerator()
|
||||
{
|
||||
return StringToBase64(CreationDate + Guid.NewGuid().ToString());
|
||||
}
|
||||
|
||||
// Dump the specified data stream
|
||||
|
||||
public static void Dump(byte[] data)
|
||||
{
|
||||
char[] buffer = new char[DumpLineSize];
|
||||
int cc = 0;
|
||||
|
||||
for (int i = 0; i < data.Length; i++)
|
||||
{
|
||||
if (i % DumpLineSize == 0) Console.Write("\n{0}: ",i.ToString("d8"));
|
||||
|
||||
if (i % 4 == 0) Console.Write(" ");
|
||||
|
||||
Console.Write("{0}",data[i].ToString("x2"));
|
||||
|
||||
if (data[i] < 127 && data[i] > 31)
|
||||
buffer[i % DumpLineSize] = (char) data[i];
|
||||
else
|
||||
buffer[i % DumpLineSize] = '.';
|
||||
|
||||
cc++;
|
||||
|
||||
if (i != 0 && (i + 1) % DumpLineSize == 0)
|
||||
{
|
||||
Console.Write(" |"+(new String(buffer))+"|");
|
||||
cc = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Finish off any incomplete line
|
||||
|
||||
if (cc != 0)
|
||||
{
|
||||
for (int i = cc ; i < DumpLineSize; i++)
|
||||
{
|
||||
if (i % 4 == 0) Console.Write(" ");
|
||||
Console.Write(" ");
|
||||
buffer[i % DumpLineSize] = ' ';
|
||||
}
|
||||
Console.WriteLine(" |"+(new String(buffer))+"|");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.Write("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Local exception type
|
||||
|
||||
public class RestException : Exception
|
||||
{
|
||||
internal int statusCode;
|
||||
internal string statusDesc;
|
||||
internal string httpmethod;
|
||||
internal string httppath;
|
||||
|
||||
public RestException(string msg) : base(msg)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,860 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Servers;
|
||||
using OpenSim.Framework.Servers.HttpServer;
|
||||
using OpenSim.Services.Interfaces;
|
||||
|
||||
namespace OpenSim.ApplicationPlugins.Rest.Inventory
|
||||
{
|
||||
|
||||
public class RestAppearanceServices : IRest
|
||||
{
|
||||
// private static readonly int PARM_USERID = 0;
|
||||
|
||||
// private static readonly int PARM_PATH = 1;
|
||||
|
||||
// private bool enabled = false;
|
||||
private string qPrefix = "appearance";
|
||||
|
||||
/// <summary>
|
||||
/// The constructor makes sure that the service prefix is absolute
|
||||
/// and the registers the service handler and the allocator.
|
||||
/// </summary>
|
||||
|
||||
public RestAppearanceServices()
|
||||
{
|
||||
Rest.Log.InfoFormat("{0} User appearance services initializing", MsgId);
|
||||
Rest.Log.InfoFormat("{0} Using REST Implementation Version {1}", MsgId, Rest.Version);
|
||||
|
||||
// If a relative path was specified for the handler's domain,
|
||||
// add the standard prefix to make it absolute, e.g. /admin
|
||||
|
||||
if (!qPrefix.StartsWith(Rest.UrlPathSeparator))
|
||||
{
|
||||
Rest.Log.InfoFormat("{0} Domain is relative, adding absolute prefix", MsgId);
|
||||
qPrefix = String.Format("{0}{1}{2}", Rest.Prefix, Rest.UrlPathSeparator, qPrefix);
|
||||
qPrefix = String.Format("{0}{1}{2}", Rest.Prefix, Rest.UrlPathSeparator, qPrefix);
|
||||
Rest.Log.InfoFormat("{0} Domain is now <{1}>", MsgId, qPrefix);
|
||||
}
|
||||
|
||||
// Register interface using the absolute URI.
|
||||
|
||||
Rest.Plugin.AddPathHandler(DoAppearance,qPrefix,Allocate);
|
||||
|
||||
// Activate if everything went OK
|
||||
|
||||
// enabled = true;
|
||||
|
||||
Rest.Log.InfoFormat("{0} User appearance services initialization complete", MsgId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Post-construction, pre-enabled initialization opportunity
|
||||
/// Not currently exploited.
|
||||
/// </summary>
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called by the plug-in to halt service processing. Local processing is
|
||||
/// disabled.
|
||||
/// </summary>
|
||||
|
||||
public void Close()
|
||||
{
|
||||
// enabled = false;
|
||||
Rest.Log.InfoFormat("{0} User appearance services closing down", MsgId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This property is declared locally because it is used a lot and
|
||||
/// brevity is nice.
|
||||
/// </summary>
|
||||
|
||||
internal string MsgId
|
||||
{
|
||||
get { return Rest.MsgId; }
|
||||
}
|
||||
|
||||
#region Interface
|
||||
|
||||
/// <summary>
|
||||
/// The plugin (RestHandler) calls this method to allocate the request
|
||||
/// state carrier for a new request. It is destroyed when the request
|
||||
/// completes. All request-instance specific state is kept here. This
|
||||
/// is registered when this service provider is registered.
|
||||
/// </summary>
|
||||
/// <param name=request>Inbound HTTP request information</param>
|
||||
/// <param name=response>Outbound HTTP request information</param>
|
||||
/// <param name=qPrefix>REST service domain prefix</param>
|
||||
/// <returns>A RequestData instance suitable for this service</returns>
|
||||
|
||||
private RequestData Allocate(OSHttpRequest request, OSHttpResponse response, string prefix)
|
||||
{
|
||||
return (RequestData) new AppearanceRequestData(request, response, prefix);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method is registered with the handler when this service provider
|
||||
/// is initialized. It is called whenever the plug-in identifies this service
|
||||
/// provider as the best match for a given request.
|
||||
/// It handles all aspects of inventory REST processing, i.e. /admin/inventory
|
||||
/// </summary>
|
||||
/// <param name=hdata>A consolidated HTTP request work area</param>
|
||||
|
||||
private void DoAppearance(RequestData hdata)
|
||||
{
|
||||
// !!! REFACTORIMG PROBLEM. This needs rewriting for 0.7
|
||||
|
||||
//AppearanceRequestData rdata = (AppearanceRequestData) hdata;
|
||||
|
||||
//Rest.Log.DebugFormat("{0} DoAppearance ENTRY", MsgId);
|
||||
|
||||
//// If we're disabled, do nothing.
|
||||
|
||||
//if (!enabled)
|
||||
//{
|
||||
// return;
|
||||
//}
|
||||
|
||||
//// Now that we know this is a serious attempt to
|
||||
//// access inventory data, we should find out who
|
||||
//// is asking, and make sure they are authorized
|
||||
//// to do so. We need to validate the caller's
|
||||
//// identity before revealing anything about the
|
||||
//// status quo. Authenticate throws an exception
|
||||
//// via Fail if no identity information is present.
|
||||
////
|
||||
//// With the present HTTP server we can't use the
|
||||
//// builtin authentication mechanisms because they
|
||||
//// would be enforced for all in-bound requests.
|
||||
//// Instead we look at the headers ourselves and
|
||||
//// handle authentication directly.
|
||||
|
||||
//try
|
||||
//{
|
||||
// if (!rdata.IsAuthenticated)
|
||||
// {
|
||||
// rdata.Fail(Rest.HttpStatusCodeNotAuthorized,String.Format("user \"{0}\" could not be authenticated", rdata.userName));
|
||||
// }
|
||||
//}
|
||||
//catch (RestException e)
|
||||
//{
|
||||
// if (e.statusCode == Rest.HttpStatusCodeNotAuthorized)
|
||||
// {
|
||||
// Rest.Log.WarnFormat("{0} User not authenticated", MsgId);
|
||||
// Rest.Log.DebugFormat("{0} Authorization header: {1}", MsgId, rdata.request.Headers.Get("Authorization"));
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// Rest.Log.ErrorFormat("{0} User authentication failed", MsgId);
|
||||
// Rest.Log.DebugFormat("{0} Authorization header: {1}", MsgId, rdata.request.Headers.Get("Authorization"));
|
||||
// }
|
||||
// throw (e);
|
||||
//}
|
||||
|
||||
//Rest.Log.DebugFormat("{0} Authenticated {1}", MsgId, rdata.userName);
|
||||
|
||||
//// We can only get here if we are authorized
|
||||
////
|
||||
//// The requestor may have specified an UUID or
|
||||
//// a conjoined FirstName LastName string. We'll
|
||||
//// try both. If we fail with the first, UUID,
|
||||
//// attempt, we try the other. As an example, the
|
||||
//// URI for a valid inventory request might be:
|
||||
////
|
||||
//// http://<host>:<port>/admin/inventory/Arthur Dent
|
||||
////
|
||||
//// Indicating that this is an inventory request for
|
||||
//// an avatar named Arthur Dent. This is ALL that is
|
||||
//// required to designate a GET for an entire
|
||||
//// inventory.
|
||||
////
|
||||
|
||||
//// Do we have at least a user agent name?
|
||||
|
||||
//if (rdata.Parameters.Length < 1)
|
||||
//{
|
||||
// Rest.Log.WarnFormat("{0} Appearance: No user agent identifier specified", MsgId);
|
||||
// rdata.Fail(Rest.HttpStatusCodeBadRequest, "no user identity specified");
|
||||
//}
|
||||
|
||||
//// The first parameter MUST be the agent identification, either an UUID
|
||||
//// or a space-separated First-name Last-Name specification. We check for
|
||||
//// an UUID first, if anyone names their character using a valid UUID
|
||||
//// that identifies another existing avatar will cause this a problem...
|
||||
|
||||
//try
|
||||
//{
|
||||
// rdata.uuid = new UUID(rdata.Parameters[PARM_USERID]);
|
||||
// Rest.Log.DebugFormat("{0} UUID supplied", MsgId);
|
||||
// rdata.userProfile = Rest.UserServices.GetUserProfile(rdata.uuid);
|
||||
//}
|
||||
//catch
|
||||
//{
|
||||
// string[] names = rdata.Parameters[PARM_USERID].Split(Rest.CA_SPACE);
|
||||
// if (names.Length == 2)
|
||||
// {
|
||||
// Rest.Log.DebugFormat("{0} Agent Name supplied [2]", MsgId);
|
||||
// rdata.userProfile = Rest.UserServices.GetUserProfile(names[0],names[1]);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// Rest.Log.WarnFormat("{0} A Valid UUID or both first and last names must be specified", MsgId);
|
||||
// rdata.Fail(Rest.HttpStatusCodeBadRequest, "invalid user identity");
|
||||
// }
|
||||
//}
|
||||
|
||||
//// If the user profile is null then either the server is broken, or the
|
||||
//// user is not known. We always assume the latter case.
|
||||
|
||||
//if (rdata.userProfile != null)
|
||||
//{
|
||||
// Rest.Log.DebugFormat("{0} User profile obtained for agent {1} {2}",
|
||||
// MsgId, rdata.userProfile.FirstName, rdata.userProfile.SurName);
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// Rest.Log.WarnFormat("{0} No user profile for {1}", MsgId, rdata.path);
|
||||
// rdata.Fail(Rest.HttpStatusCodeNotFound, "unrecognized user identity");
|
||||
//}
|
||||
|
||||
//// If we get to here, then we have effectively validated the user's
|
||||
|
||||
//switch (rdata.method)
|
||||
//{
|
||||
// case Rest.HEAD : // Do the processing, set the status code, suppress entity
|
||||
// DoGet(rdata);
|
||||
// rdata.buffer = null;
|
||||
// break;
|
||||
|
||||
// case Rest.GET : // Do the processing, set the status code, return entity
|
||||
// DoGet(rdata);
|
||||
// break;
|
||||
|
||||
// case Rest.PUT : // Update named element
|
||||
// DoUpdate(rdata);
|
||||
// break;
|
||||
|
||||
// case Rest.POST : // Add new information to identified context.
|
||||
// DoExtend(rdata);
|
||||
// break;
|
||||
|
||||
// case Rest.DELETE : // Delete information
|
||||
// DoDelete(rdata);
|
||||
// break;
|
||||
|
||||
// default :
|
||||
// Rest.Log.WarnFormat("{0} Method {1} not supported for {2}",
|
||||
// MsgId, rdata.method, rdata.path);
|
||||
// rdata.Fail(Rest.HttpStatusCodeMethodNotAllowed,
|
||||
// String.Format("{0} not supported", rdata.method));
|
||||
// break;
|
||||
//}
|
||||
}
|
||||
|
||||
#endregion Interface
|
||||
|
||||
#region method-specific processing
|
||||
|
||||
/// <summary>
|
||||
/// This method implements GET processing for user's appearance.
|
||||
/// </summary>
|
||||
/// <param name=rdata>HTTP service request work area</param>
|
||||
|
||||
// private void DoGet(AppearanceRequestData rdata)
|
||||
// {
|
||||
// AvatarData adata = Rest.AvatarServices.GetAvatar(rdata.userProfile.ID);
|
||||
//
|
||||
// if (adata == null)
|
||||
// {
|
||||
// rdata.Fail(Rest.HttpStatusCodeNoContent,
|
||||
// String.Format("appearance data not found for user {0} {1}",
|
||||
// rdata.userProfile.FirstName, rdata.userProfile.SurName));
|
||||
// }
|
||||
// rdata.userAppearance = adata.ToAvatarAppearance(rdata.userProfile.ID);
|
||||
//
|
||||
// rdata.initXmlWriter();
|
||||
//
|
||||
// FormatUserAppearance(rdata);
|
||||
//
|
||||
// // Indicate a successful request
|
||||
//
|
||||
// rdata.Complete();
|
||||
//
|
||||
// // Send the response to the user. The body will be implicitly
|
||||
// // constructed from the result of the XML writer.
|
||||
//
|
||||
// rdata.Respond(String.Format("Appearance {0} Normal completion", rdata.method));
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// POST adds NEW information to the user profile database.
|
||||
/// This effectively resets the appearance before applying those
|
||||
/// characteristics supplied in the request.
|
||||
/// </summary>
|
||||
|
||||
// private void DoExtend(AppearanceRequestData rdata)
|
||||
// {
|
||||
//
|
||||
// bool created = false;
|
||||
// bool modified = false;
|
||||
// string newnode = String.Empty;
|
||||
//
|
||||
// Rest.Log.DebugFormat("{0} POST ENTRY", MsgId);
|
||||
//
|
||||
// //AvatarAppearance old = Rest.AvatarServices.GetUserAppearance(rdata.userProfile.ID);
|
||||
//
|
||||
// rdata.userAppearance = new AvatarAppearance();
|
||||
//
|
||||
// // Although the following behavior is admitted by HTTP I am becoming
|
||||
// // increasingly doubtful that it is appropriate for REST. If I attempt to
|
||||
// // add a new record, and it already exists, then it seems to me that the
|
||||
// // attempt should fail, rather than update the existing record.
|
||||
// AvatarData adata = null;
|
||||
// if (GetUserAppearance(rdata))
|
||||
// {
|
||||
// modified = rdata.userAppearance != null;
|
||||
// created = !modified;
|
||||
// adata = new AvatarData(rdata.userAppearance);
|
||||
// Rest.AvatarServices.SetAvatar(rdata.userProfile.ID, adata);
|
||||
// // Rest.UserServices.UpdateUserProfile(rdata.userProfile);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// created = true;
|
||||
// adata = new AvatarData(rdata.userAppearance);
|
||||
// Rest.AvatarServices.SetAvatar(rdata.userProfile.ID, adata);
|
||||
// // Rest.UserServices.UpdateUserProfile(rdata.userProfile);
|
||||
// }
|
||||
//
|
||||
// if (created)
|
||||
// {
|
||||
// newnode = String.Format("{0} {1}", rdata.userProfile.FirstName,
|
||||
// rdata.userProfile.SurName);
|
||||
// // Must include a location header with a URI that identifies the new resource.
|
||||
//
|
||||
// rdata.AddHeader(Rest.HttpHeaderLocation,String.Format("http://{0}{1}:{2}{3}{4}",
|
||||
// rdata.hostname,rdata.port,rdata.path,Rest.UrlPathSeparator, newnode));
|
||||
// rdata.Complete(Rest.HttpStatusCodeCreated);
|
||||
//
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// if (modified)
|
||||
// {
|
||||
// rdata.Complete(Rest.HttpStatusCodeOK);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// rdata.Complete(Rest.HttpStatusCodeNoContent);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// rdata.Respond(String.Format("Appearance {0} : Normal completion", rdata.method));
|
||||
//
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// This updates the user's appearance. not all aspects need to be provided,
|
||||
/// only those supplied will be changed.
|
||||
/// </summary>
|
||||
|
||||
// private void DoUpdate(AppearanceRequestData rdata)
|
||||
// {
|
||||
//
|
||||
// // REFACTORING PROBLEM This was commented out. It doesn't work for 0.7
|
||||
//
|
||||
// //bool created = false;
|
||||
// //bool modified = false;
|
||||
//
|
||||
//
|
||||
// //rdata.userAppearance = Rest.AvatarServices.GetUserAppearance(rdata.userProfile.ID);
|
||||
//
|
||||
// //// If the user exists then this is considered a modification regardless
|
||||
// //// of what may, or may not be, specified in the payload.
|
||||
//
|
||||
// //if (rdata.userAppearance != null)
|
||||
// //{
|
||||
// // modified = true;
|
||||
// // Rest.AvatarServices.UpdateUserAppearance(rdata.userProfile.ID, rdata.userAppearance);
|
||||
// // Rest.UserServices.UpdateUserProfile(rdata.userProfile);
|
||||
// //}
|
||||
//
|
||||
// //if (created)
|
||||
// //{
|
||||
// // rdata.Complete(Rest.HttpStatusCodeCreated);
|
||||
// //}
|
||||
// //else
|
||||
// //{
|
||||
// // if (modified)
|
||||
// // {
|
||||
// // rdata.Complete(Rest.HttpStatusCodeOK);
|
||||
// // }
|
||||
// // else
|
||||
// // {
|
||||
// // rdata.Complete(Rest.HttpStatusCodeNoContent);
|
||||
// // }
|
||||
// //}
|
||||
//
|
||||
// rdata.Respond(String.Format("Appearance {0} : Normal completion", rdata.method));
|
||||
//
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// Delete the specified user's appearance. This actually performs a reset
|
||||
/// to the default avatar appearance, if the info is already there.
|
||||
/// Existing ownership is preserved. All prior updates are lost and can not
|
||||
/// be recovered.
|
||||
/// </summary>
|
||||
// private void DoDelete(AppearanceRequestData rdata)
|
||||
// {
|
||||
// AvatarData adata = Rest.AvatarServices.GetAvatar(rdata.userProfile.ID);
|
||||
//
|
||||
// if (adata != null)
|
||||
// {
|
||||
// AvatarAppearance old = adata.ToAvatarAppearance(rdata.userProfile.ID);
|
||||
// rdata.userAppearance = new AvatarAppearance();
|
||||
// rdata.userAppearance.Owner = old.Owner;
|
||||
// adata = new AvatarData(rdata.userAppearance);
|
||||
//
|
||||
// Rest.AvatarServices.SetAvatar(rdata.userProfile.ID, adata);
|
||||
//
|
||||
// rdata.Complete();
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
//
|
||||
// rdata.Complete(Rest.HttpStatusCodeNoContent);
|
||||
// }
|
||||
//
|
||||
// rdata.Respond(String.Format("Appearance {0} : Normal completion", rdata.method));
|
||||
// }
|
||||
|
||||
#endregion method-specific processing
|
||||
|
||||
private bool GetUserAppearance(AppearanceRequestData rdata)
|
||||
{
|
||||
|
||||
XmlReader xml;
|
||||
bool indata = false;
|
||||
|
||||
rdata.initXmlReader();
|
||||
xml = rdata.reader;
|
||||
|
||||
while (xml.Read())
|
||||
{
|
||||
switch (xml.NodeType)
|
||||
{
|
||||
case XmlNodeType.Element :
|
||||
switch (xml.Name)
|
||||
{
|
||||
case "Appearance" :
|
||||
if (xml.MoveToAttribute("Height"))
|
||||
{
|
||||
rdata.userAppearance.AvatarHeight = (float) Convert.ToDouble(xml.Value);
|
||||
indata = true;
|
||||
}
|
||||
// if (xml.MoveToAttribute("Owner"))
|
||||
// {
|
||||
// rdata.userAppearance.Owner = (UUID)xml.Value;
|
||||
// indata = true;
|
||||
// }
|
||||
if (xml.MoveToAttribute("Serial"))
|
||||
{
|
||||
rdata.userAppearance.Serial = Convert.ToInt32(xml.Value);
|
||||
indata = true;
|
||||
}
|
||||
break;
|
||||
/*
|
||||
case "Body" :
|
||||
if (xml.MoveToAttribute("Item"))
|
||||
{
|
||||
rdata.userAppearance.BodyItem = (UUID)xml.Value;
|
||||
indata = true;
|
||||
}
|
||||
if (xml.MoveToAttribute("Asset"))
|
||||
{
|
||||
rdata.userAppearance.BodyAsset = (UUID)xml.Value;
|
||||
indata = true;
|
||||
}
|
||||
break;
|
||||
case "Skin" :
|
||||
if (xml.MoveToAttribute("Item"))
|
||||
{
|
||||
rdata.userAppearance.SkinItem = (UUID)xml.Value;
|
||||
indata = true;
|
||||
}
|
||||
if (xml.MoveToAttribute("Asset"))
|
||||
{
|
||||
rdata.userAppearance.SkinAsset = (UUID)xml.Value;
|
||||
indata = true;
|
||||
}
|
||||
break;
|
||||
case "Hair" :
|
||||
if (xml.MoveToAttribute("Item"))
|
||||
{
|
||||
rdata.userAppearance.HairItem = (UUID)xml.Value;
|
||||
indata = true;
|
||||
}
|
||||
if (xml.MoveToAttribute("Asset"))
|
||||
{
|
||||
rdata.userAppearance.HairAsset = (UUID)xml.Value;
|
||||
indata = true;
|
||||
}
|
||||
break;
|
||||
case "Eyes" :
|
||||
if (xml.MoveToAttribute("Item"))
|
||||
{
|
||||
rdata.userAppearance.EyesItem = (UUID)xml.Value;
|
||||
indata = true;
|
||||
}
|
||||
if (xml.MoveToAttribute("Asset"))
|
||||
{
|
||||
rdata.userAppearance.EyesAsset = (UUID)xml.Value;
|
||||
indata = true;
|
||||
}
|
||||
break;
|
||||
case "Shirt" :
|
||||
if (xml.MoveToAttribute("Item"))
|
||||
{
|
||||
rdata.userAppearance.ShirtItem = (UUID)xml.Value;
|
||||
indata = true;
|
||||
}
|
||||
if (xml.MoveToAttribute("Asset"))
|
||||
{
|
||||
rdata.userAppearance.ShirtAsset = (UUID)xml.Value;
|
||||
indata = true;
|
||||
}
|
||||
break;
|
||||
case "Pants" :
|
||||
if (xml.MoveToAttribute("Item"))
|
||||
{
|
||||
rdata.userAppearance.PantsItem = (UUID)xml.Value;
|
||||
indata = true;
|
||||
}
|
||||
if (xml.MoveToAttribute("Asset"))
|
||||
{
|
||||
rdata.userAppearance.PantsAsset = (UUID)xml.Value;
|
||||
indata = true;
|
||||
}
|
||||
break;
|
||||
case "Shoes" :
|
||||
if (xml.MoveToAttribute("Item"))
|
||||
{
|
||||
rdata.userAppearance.ShoesItem = (UUID)xml.Value;
|
||||
indata = true;
|
||||
}
|
||||
if (xml.MoveToAttribute("Asset"))
|
||||
{
|
||||
rdata.userAppearance.ShoesAsset = (UUID)xml.Value;
|
||||
indata = true;
|
||||
}
|
||||
break;
|
||||
case "Socks" :
|
||||
if (xml.MoveToAttribute("Item"))
|
||||
{
|
||||
rdata.userAppearance.SocksItem = (UUID)xml.Value;
|
||||
indata = true;
|
||||
}
|
||||
if (xml.MoveToAttribute("Asset"))
|
||||
{
|
||||
rdata.userAppearance.SocksAsset = (UUID)xml.Value;
|
||||
indata = true;
|
||||
}
|
||||
break;
|
||||
case "Jacket" :
|
||||
if (xml.MoveToAttribute("Item"))
|
||||
{
|
||||
rdata.userAppearance.JacketItem = (UUID)xml.Value;
|
||||
indata = true;
|
||||
}
|
||||
if (xml.MoveToAttribute("Asset"))
|
||||
{
|
||||
rdata.userAppearance.JacketAsset = (UUID)xml.Value;
|
||||
indata = true;
|
||||
}
|
||||
break;
|
||||
case "Gloves" :
|
||||
if (xml.MoveToAttribute("Item"))
|
||||
{
|
||||
rdata.userAppearance.GlovesItem = (UUID)xml.Value;
|
||||
indata = true;
|
||||
}
|
||||
if (xml.MoveToAttribute("Asset"))
|
||||
{
|
||||
rdata.userAppearance.GlovesAsset = (UUID)xml.Value;
|
||||
indata = true;
|
||||
}
|
||||
break;
|
||||
case "UnderShirt" :
|
||||
if (xml.MoveToAttribute("Item"))
|
||||
{
|
||||
rdata.userAppearance.UnderShirtItem = (UUID)xml.Value;
|
||||
indata = true;
|
||||
}
|
||||
if (xml.MoveToAttribute("Asset"))
|
||||
{
|
||||
rdata.userAppearance.UnderShirtAsset = (UUID)xml.Value;
|
||||
indata = true;
|
||||
}
|
||||
break;
|
||||
case "UnderPants" :
|
||||
if (xml.MoveToAttribute("Item"))
|
||||
{
|
||||
rdata.userAppearance.UnderPantsItem = (UUID)xml.Value;
|
||||
indata = true;
|
||||
}
|
||||
if (xml.MoveToAttribute("Asset"))
|
||||
{
|
||||
rdata.userAppearance.UnderPantsAsset = (UUID)xml.Value;
|
||||
indata = true;
|
||||
}
|
||||
break;
|
||||
case "Skirt" :
|
||||
if (xml.MoveToAttribute("Item"))
|
||||
{
|
||||
rdata.userAppearance.SkirtItem = (UUID)xml.Value;
|
||||
indata = true;
|
||||
}
|
||||
if (xml.MoveToAttribute("Asset"))
|
||||
{
|
||||
rdata.userAppearance.SkirtAsset = (UUID)xml.Value;
|
||||
indata = true;
|
||||
}
|
||||
break;
|
||||
*/
|
||||
case "Attachment" :
|
||||
{
|
||||
|
||||
int ap;
|
||||
UUID asset;
|
||||
UUID item;
|
||||
|
||||
if (xml.MoveToAttribute("AtPoint"))
|
||||
{
|
||||
ap = Convert.ToInt32(xml.Value);
|
||||
if (xml.MoveToAttribute("Asset"))
|
||||
{
|
||||
asset = new UUID(xml.Value);
|
||||
if (xml.MoveToAttribute("Asset"))
|
||||
{
|
||||
item = new UUID(xml.Value);
|
||||
rdata.userAppearance.SetAttachment(ap, item, asset);
|
||||
indata = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "Texture" :
|
||||
if (xml.MoveToAttribute("Default"))
|
||||
{
|
||||
rdata.userAppearance.Texture = new Primitive.TextureEntry(new UUID(xml.Value));
|
||||
indata = true;
|
||||
}
|
||||
break;
|
||||
case "Face" :
|
||||
{
|
||||
uint index;
|
||||
if (xml.MoveToAttribute("Index"))
|
||||
{
|
||||
index = Convert.ToUInt32(xml.Value);
|
||||
if (xml.MoveToAttribute("Id"))
|
||||
{
|
||||
rdata.userAppearance.Texture.CreateFace(index).TextureID = new UUID(xml.Value);
|
||||
indata = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "VisualParameters" :
|
||||
{
|
||||
xml.ReadContentAsBase64(rdata.userAppearance.VisualParams,
|
||||
0, rdata.userAppearance.VisualParams.Length);
|
||||
indata = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return indata;
|
||||
|
||||
}
|
||||
|
||||
private void FormatPart(AppearanceRequestData rdata, string part, UUID item, UUID asset)
|
||||
{
|
||||
if (item != UUID.Zero || asset != UUID.Zero)
|
||||
{
|
||||
rdata.writer.WriteStartElement(part);
|
||||
if (item != UUID.Zero)
|
||||
{
|
||||
rdata.writer.WriteAttributeString("Item",item.ToString());
|
||||
}
|
||||
|
||||
if (asset != UUID.Zero)
|
||||
{
|
||||
rdata.writer.WriteAttributeString("Asset",asset.ToString());
|
||||
}
|
||||
rdata.writer.WriteEndElement();
|
||||
}
|
||||
}
|
||||
|
||||
private void FormatUserAppearance(AppearanceRequestData rdata)
|
||||
{
|
||||
|
||||
Rest.Log.DebugFormat("{0} FormatUserAppearance", MsgId);
|
||||
|
||||
if (rdata.userAppearance != null)
|
||||
{
|
||||
|
||||
Rest.Log.DebugFormat("{0} FormatUserAppearance: appearance object exists", MsgId);
|
||||
rdata.writer.WriteStartElement("Appearance");
|
||||
|
||||
rdata.writer.WriteAttributeString("Height", rdata.userAppearance.AvatarHeight.ToString());
|
||||
// if (rdata.userAppearance.Owner != UUID.Zero)
|
||||
// rdata.writer.WriteAttributeString("Owner", rdata.userAppearance.Owner.ToString());
|
||||
rdata.writer.WriteAttributeString("Serial", rdata.userAppearance.Serial.ToString());
|
||||
|
||||
/*
|
||||
FormatPart(rdata, "Body", rdata.userAppearance.BodyItem, rdata.userAppearance.BodyAsset);
|
||||
FormatPart(rdata, "Skin", rdata.userAppearance.SkinItem, rdata.userAppearance.SkinAsset);
|
||||
FormatPart(rdata, "Hair", rdata.userAppearance.HairItem, rdata.userAppearance.HairAsset);
|
||||
FormatPart(rdata, "Eyes", rdata.userAppearance.EyesItem, rdata.userAppearance.EyesAsset);
|
||||
|
||||
FormatPart(rdata, "Shirt", rdata.userAppearance.ShirtItem, rdata.userAppearance.ShirtAsset);
|
||||
FormatPart(rdata, "Pants", rdata.userAppearance.PantsItem, rdata.userAppearance.PantsAsset);
|
||||
FormatPart(rdata, "Skirt", rdata.userAppearance.SkirtItem, rdata.userAppearance.SkirtAsset);
|
||||
FormatPart(rdata, "Shoes", rdata.userAppearance.ShoesItem, rdata.userAppearance.ShoesAsset);
|
||||
FormatPart(rdata, "Socks", rdata.userAppearance.SocksItem, rdata.userAppearance.SocksAsset);
|
||||
|
||||
FormatPart(rdata, "Jacket", rdata.userAppearance.JacketItem, rdata.userAppearance.JacketAsset);
|
||||
FormatPart(rdata, "Gloves", rdata.userAppearance.GlovesItem, rdata.userAppearance.GlovesAsset);
|
||||
|
||||
FormatPart(rdata, "UnderShirt", rdata.userAppearance.UnderShirtItem, rdata.userAppearance.UnderShirtAsset);
|
||||
FormatPart(rdata, "UnderPants", rdata.userAppearance.UnderPantsItem, rdata.userAppearance.UnderPantsAsset);
|
||||
*/
|
||||
Rest.Log.DebugFormat("{0} FormatUserAppearance: Formatting attachments", MsgId);
|
||||
|
||||
rdata.writer.WriteStartElement("Attachments");
|
||||
List<AvatarAttachment> attachments = rdata.userAppearance.GetAttachments();
|
||||
foreach (AvatarAttachment attach in attachments)
|
||||
{
|
||||
rdata.writer.WriteStartElement("Attachment");
|
||||
rdata.writer.WriteAttributeString("AtPoint", attach.AttachPoint.ToString());
|
||||
rdata.writer.WriteAttributeString("Item", attach.ItemID.ToString());
|
||||
rdata.writer.WriteAttributeString("Asset", attach.AssetID.ToString());
|
||||
rdata.writer.WriteEndElement();
|
||||
}
|
||||
rdata.writer.WriteEndElement();
|
||||
|
||||
Primitive.TextureEntry texture = rdata.userAppearance.Texture;
|
||||
|
||||
if (texture != null && (texture.DefaultTexture != null || texture.FaceTextures != null))
|
||||
{
|
||||
Rest.Log.DebugFormat("{0} FormatUserAppearance: Formatting textures", MsgId);
|
||||
|
||||
rdata.writer.WriteStartElement("Texture");
|
||||
|
||||
if (texture.DefaultTexture != null)
|
||||
{
|
||||
Rest.Log.DebugFormat("{0} FormatUserAppearance: Formatting default texture", MsgId);
|
||||
rdata.writer.WriteAttributeString("Default",
|
||||
texture.DefaultTexture.TextureID.ToString());
|
||||
}
|
||||
|
||||
if (texture.FaceTextures != null)
|
||||
{
|
||||
|
||||
Rest.Log.DebugFormat("{0} FormatUserAppearance: Formatting face textures", MsgId);
|
||||
|
||||
for (int i=0; i<texture.FaceTextures.Length;i++)
|
||||
{
|
||||
if (texture.FaceTextures[i] != null)
|
||||
{
|
||||
rdata.writer.WriteStartElement("Face");
|
||||
rdata.writer.WriteAttributeString("Index", i.ToString());
|
||||
rdata.writer.WriteAttributeString("Id",
|
||||
texture.FaceTextures[i].TextureID.ToString());
|
||||
rdata.writer.WriteEndElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rdata.writer.WriteEndElement();
|
||||
}
|
||||
|
||||
Rest.Log.DebugFormat("{0} FormatUserAppearance: Formatting visual parameters", MsgId);
|
||||
|
||||
rdata.writer.WriteStartElement("VisualParameters");
|
||||
rdata.writer.WriteBase64(rdata.userAppearance.VisualParams,0,
|
||||
rdata.userAppearance.VisualParams.Length);
|
||||
rdata.writer.WriteEndElement();
|
||||
rdata.writer.WriteFullEndElement();
|
||||
}
|
||||
|
||||
Rest.Log.DebugFormat("{0} FormatUserAppearance: completed", MsgId);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#region appearance RequestData extension
|
||||
|
||||
internal class AppearanceRequestData : RequestData
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// These are the inventory specific request/response state
|
||||
/// extensions.
|
||||
/// </summary>
|
||||
|
||||
internal UUID uuid = UUID.Zero;
|
||||
internal UserProfileData userProfile = null;
|
||||
internal AvatarAppearance userAppearance = null;
|
||||
|
||||
internal AppearanceRequestData(OSHttpRequest request, OSHttpResponse response, string prefix)
|
||||
: base(request, response, prefix)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endregion Appearance RequestData extension
|
||||
|
||||
}
|
||||
}
|
||||
383
OpenSim/ApplicationPlugins/Rest/Inventory/RestAssetServices.cs
Normal file
383
OpenSim/ApplicationPlugins/Rest/Inventory/RestAssetServices.cs
Normal file
@@ -0,0 +1,383 @@
|
||||
/*
|
||||
* 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.Xml;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Servers;
|
||||
using OpenSim.Framework.Servers.HttpServer;
|
||||
|
||||
namespace OpenSim.ApplicationPlugins.Rest.Inventory
|
||||
{
|
||||
public class RestAssetServices : IRest
|
||||
{
|
||||
private bool enabled = false;
|
||||
private string qPrefix = "assets";
|
||||
|
||||
// A simple constructor is used to handle any once-only
|
||||
// initialization of working classes.
|
||||
|
||||
public RestAssetServices()
|
||||
{
|
||||
Rest.Log.InfoFormat("{0} Asset services initializing", MsgId);
|
||||
Rest.Log.InfoFormat("{0} Using REST Implementation Version {1}", MsgId, Rest.Version);
|
||||
|
||||
// If the handler specifies a relative path for its domain
|
||||
// then we must add the standard absolute prefix, e.g. /admin
|
||||
|
||||
if (!qPrefix.StartsWith(Rest.UrlPathSeparator))
|
||||
{
|
||||
Rest.Log.InfoFormat("{0} Prefixing domain name ({1})", MsgId, qPrefix);
|
||||
qPrefix = String.Format("{0}{1}{2}", Rest.Prefix, Rest.UrlPathSeparator, qPrefix);
|
||||
Rest.Log.InfoFormat("{0} Fully qualified domain name is <{1}>", MsgId, qPrefix);
|
||||
}
|
||||
|
||||
// Register interface using the fully-qualified prefix
|
||||
|
||||
Rest.Plugin.AddPathHandler(DoAsset, qPrefix, Allocate);
|
||||
|
||||
// Activate if all went OK
|
||||
|
||||
enabled = true;
|
||||
|
||||
Rest.Log.InfoFormat("{0} Asset services initialization complete", MsgId);
|
||||
}
|
||||
|
||||
// Post-construction, pre-enabled initialization opportunity
|
||||
// Not currently exploited.
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
}
|
||||
|
||||
// Called by the plug-in to halt REST processing. Local processing is
|
||||
// disabled, and control blocks until all current processing has
|
||||
// completed. No new processing will be started
|
||||
|
||||
public void Close()
|
||||
{
|
||||
enabled = false;
|
||||
Rest.Log.InfoFormat("{0} Asset services ({1}) closing down", MsgId, qPrefix);
|
||||
}
|
||||
|
||||
// Properties
|
||||
|
||||
internal string MsgId
|
||||
{
|
||||
get { return Rest.MsgId; }
|
||||
}
|
||||
|
||||
#region Interface
|
||||
|
||||
private RequestData Allocate(OSHttpRequest request, OSHttpResponse response, string prefix)
|
||||
{
|
||||
return (RequestData) new AssetRequestData(request, response, prefix);
|
||||
}
|
||||
|
||||
// Asset Handler
|
||||
|
||||
private void DoAsset(RequestData rparm)
|
||||
{
|
||||
if (!enabled) return;
|
||||
|
||||
AssetRequestData rdata = (AssetRequestData) rparm;
|
||||
|
||||
Rest.Log.DebugFormat("{0} REST Asset handler ({1}) ENTRY", MsgId, qPrefix);
|
||||
|
||||
// Now that we know this is a serious attempt to
|
||||
// access inventory data, we should find out who
|
||||
// is asking, and make sure they are authorized
|
||||
// to do so. We need to validate the caller's
|
||||
// identity before revealing anything about the
|
||||
// status quo. Authenticate throws an exception
|
||||
// via Fail if no identity information is present.
|
||||
//
|
||||
// With the present HTTP server we can't use the
|
||||
// builtin authentication mechanisms because they
|
||||
// would be enforced for all in-bound requests.
|
||||
// Instead we look at the headers ourselves and
|
||||
// handle authentication directly.
|
||||
|
||||
try
|
||||
{
|
||||
if (!rdata.IsAuthenticated)
|
||||
{
|
||||
rdata.Fail(Rest.HttpStatusCodeNotAuthorized, String.Format("user \"{0}\" could not be authenticated"));
|
||||
}
|
||||
}
|
||||
catch (RestException e)
|
||||
{
|
||||
if (e.statusCode == Rest.HttpStatusCodeNotAuthorized)
|
||||
{
|
||||
Rest.Log.WarnFormat("{0} User not authenticated", MsgId);
|
||||
Rest.Log.DebugFormat("{0} Authorization header: {1}", MsgId,
|
||||
rdata.request.Headers.Get("Authorization"));
|
||||
}
|
||||
else
|
||||
{
|
||||
Rest.Log.ErrorFormat("{0} User authentication failed", MsgId);
|
||||
Rest.Log.DebugFormat("{0} Authorization header: {1}", MsgId,
|
||||
rdata.request.Headers.Get("Authorization"));
|
||||
}
|
||||
throw (e);
|
||||
}
|
||||
|
||||
// Remove the prefix and what's left are the parameters. If we don't have
|
||||
// the parameters we need, fail the request. Parameters do NOT include
|
||||
// any supplied query values.
|
||||
|
||||
if (rdata.Parameters.Length > 0)
|
||||
{
|
||||
switch (rdata.method)
|
||||
{
|
||||
case "get" :
|
||||
DoGet(rdata);
|
||||
break;
|
||||
case "put" :
|
||||
DoPut(rdata);
|
||||
break;
|
||||
case "post" :
|
||||
DoPost(rdata);
|
||||
break;
|
||||
case "delete" :
|
||||
default :
|
||||
Rest.Log.WarnFormat("{0} Asset: Method not supported: {1}",
|
||||
MsgId, rdata.method);
|
||||
rdata.Fail(Rest.HttpStatusCodeBadRequest,String.Format("method <{0}> not supported", rdata.method));
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Rest.Log.WarnFormat("{0} Asset: No agent information provided", MsgId);
|
||||
rdata.Fail(Rest.HttpStatusCodeBadRequest, "no agent information provided");
|
||||
}
|
||||
|
||||
Rest.Log.DebugFormat("{0} REST Asset handler EXIT", MsgId);
|
||||
}
|
||||
|
||||
#endregion Interface
|
||||
|
||||
/// <summary>
|
||||
/// The only parameter we recognize is a UUID.If an asset with this identification is
|
||||
/// found, it's content, base-64 encoded, is returned to the client.
|
||||
/// </summary>
|
||||
|
||||
private void DoGet(AssetRequestData rdata)
|
||||
{
|
||||
Rest.Log.DebugFormat("{0} REST Asset handler, Method = <{1}> ENTRY", MsgId, rdata.method);
|
||||
|
||||
if (rdata.Parameters.Length == 1)
|
||||
{
|
||||
UUID uuid = new UUID(rdata.Parameters[0]);
|
||||
AssetBase asset = Rest.AssetServices.Get(uuid.ToString());
|
||||
|
||||
if (asset != null)
|
||||
{
|
||||
Rest.Log.DebugFormat("{0} Asset located <{1}>", MsgId, rdata.Parameters[0]);
|
||||
|
||||
rdata.initXmlWriter();
|
||||
|
||||
rdata.writer.WriteStartElement(String.Empty,"Asset",String.Empty);
|
||||
|
||||
rdata.writer.WriteAttributeString("id", asset.ID);
|
||||
rdata.writer.WriteAttributeString("name", asset.Name);
|
||||
rdata.writer.WriteAttributeString("desc", asset.Description);
|
||||
rdata.writer.WriteAttributeString("type", asset.Type.ToString());
|
||||
rdata.writer.WriteAttributeString("local", asset.Local.ToString());
|
||||
rdata.writer.WriteAttributeString("temporary", asset.Temporary.ToString());
|
||||
|
||||
rdata.writer.WriteBase64(asset.Data,0,asset.Data.Length);
|
||||
|
||||
rdata.writer.WriteFullEndElement();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
Rest.Log.DebugFormat("{0} Invalid parameters: <{1}>", MsgId, rdata.path);
|
||||
rdata.Fail(Rest.HttpStatusCodeNotFound, "invalid parameters");
|
||||
}
|
||||
}
|
||||
|
||||
rdata.Complete();
|
||||
rdata.Respond(String.Format("Asset <{0}> : Normal completion", rdata.method));
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// UPDATE existing item, if it exists. URI identifies the item in question.
|
||||
/// The only parameter we recognize is a UUID. The enclosed asset data (base-64 encoded)
|
||||
/// is decoded and stored in the database, identified by the supplied UUID.
|
||||
/// </summary>
|
||||
private void DoPut(AssetRequestData rdata)
|
||||
{
|
||||
bool modified = false;
|
||||
bool created = false;
|
||||
|
||||
AssetBase asset = null;
|
||||
|
||||
Rest.Log.DebugFormat("{0} REST Asset handler, Method = <{1}> ENTRY", MsgId, rdata.method);
|
||||
|
||||
if (rdata.Parameters.Length == 1)
|
||||
{
|
||||
|
||||
rdata.initXmlReader();
|
||||
XmlReader xml = rdata.reader;
|
||||
|
||||
if (!xml.ReadToFollowing("Asset"))
|
||||
{
|
||||
Rest.Log.DebugFormat("{0} Invalid request data: <{1}>", MsgId, rdata.path);
|
||||
rdata.Fail(Rest.HttpStatusCodeBadRequest,"invalid request data");
|
||||
}
|
||||
|
||||
UUID uuid = new UUID(rdata.Parameters[0]);
|
||||
asset = Rest.AssetServices.Get(uuid.ToString());
|
||||
|
||||
modified = (asset != null);
|
||||
created = !modified;
|
||||
|
||||
asset = new AssetBase(uuid, xml.GetAttribute("name"), SByte.Parse(xml.GetAttribute("type")), UUID.Zero.ToString());
|
||||
asset.Description = xml.GetAttribute("desc");
|
||||
asset.Local = Int32.Parse(xml.GetAttribute("local")) != 0;
|
||||
asset.Temporary = Int32.Parse(xml.GetAttribute("temporary")) != 0;
|
||||
asset.Data = Convert.FromBase64String(xml.ReadElementContentAsString("Asset", ""));
|
||||
|
||||
if (asset.ID != rdata.Parameters[0])
|
||||
{
|
||||
Rest.Log.WarnFormat("{0} URI and payload disagree on UUID U:{1} vs P:{2}",
|
||||
MsgId, rdata.Parameters[0], asset.ID);
|
||||
}
|
||||
|
||||
Rest.AssetServices.Store(asset);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
Rest.Log.DebugFormat("{0} Invalid parameters: <{1}>", MsgId, rdata.path);
|
||||
rdata.Fail(Rest.HttpStatusCodeNotFound, "invalid parameters");
|
||||
}
|
||||
|
||||
if (created)
|
||||
{
|
||||
rdata.appendStatus(String.Format("<p> Created asset {0}, UUID {1} <p>", asset.Name, asset.FullID));
|
||||
rdata.Complete(Rest.HttpStatusCodeCreated);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (modified)
|
||||
{
|
||||
rdata.appendStatus(String.Format("<p> Modified asset {0}, UUID {1} <p>", asset.Name, asset.FullID));
|
||||
rdata.Complete(Rest.HttpStatusCodeOK);
|
||||
}
|
||||
else
|
||||
{
|
||||
rdata.Complete(Rest.HttpStatusCodeNoContent);
|
||||
}
|
||||
}
|
||||
|
||||
rdata.Respond(String.Format("Asset {0} : Normal completion", rdata.method));
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// CREATE new item, replace if it exists. URI identifies the context for the item in question.
|
||||
/// No parameters are required for POST, just thepayload.
|
||||
/// </summary>
|
||||
|
||||
private void DoPost(AssetRequestData rdata)
|
||||
{
|
||||
|
||||
bool modified = false;
|
||||
bool created = false;
|
||||
|
||||
Rest.Log.DebugFormat("{0} REST Asset handler, Method = <{1}> ENTRY", MsgId, rdata.method);
|
||||
|
||||
if (rdata.Parameters.Length != 0)
|
||||
{
|
||||
Rest.Log.WarnFormat("{0} Parameters ignored <{1}>", MsgId, rdata.path);
|
||||
Rest.Log.InfoFormat("{0} POST of an asset has no parameters", MsgId, rdata.path);
|
||||
}
|
||||
|
||||
rdata.initXmlReader();
|
||||
XmlReader xml = rdata.reader;
|
||||
|
||||
if (!xml.ReadToFollowing("Asset"))
|
||||
{
|
||||
Rest.Log.DebugFormat("{0} Invalid request data: <{1}>", MsgId, rdata.path);
|
||||
rdata.Fail(Rest.HttpStatusCodeBadRequest,"invalid request data");
|
||||
}
|
||||
|
||||
UUID uuid = new UUID(xml.GetAttribute("id"));
|
||||
AssetBase asset = Rest.AssetServices.Get(uuid.ToString());
|
||||
|
||||
modified = (asset != null);
|
||||
created = !modified;
|
||||
|
||||
asset = new AssetBase(uuid, xml.GetAttribute("name"), SByte.Parse(xml.GetAttribute("type")), UUID.Zero.ToString());
|
||||
asset.Description = xml.GetAttribute("desc");
|
||||
asset.Local = Int32.Parse(xml.GetAttribute("local")) != 0;
|
||||
asset.Temporary = Int32.Parse(xml.GetAttribute("temporary")) != 0;
|
||||
asset.Data = Convert.FromBase64String(xml.ReadElementContentAsString("Asset", ""));
|
||||
|
||||
Rest.AssetServices.Store(asset);
|
||||
|
||||
if (created)
|
||||
{
|
||||
rdata.appendStatus(String.Format("<p> Created asset {0}, UUID {1} <p>", asset.Name, asset.FullID));
|
||||
rdata.Complete(Rest.HttpStatusCodeCreated);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (modified)
|
||||
{
|
||||
rdata.appendStatus(String.Format("<p> Modified asset {0}, UUID {1} <p>", asset.Name, asset.FullID));
|
||||
rdata.Complete(Rest.HttpStatusCodeOK);
|
||||
}
|
||||
else
|
||||
{
|
||||
rdata.Complete(Rest.HttpStatusCodeNoContent);
|
||||
}
|
||||
}
|
||||
|
||||
rdata.Respond(String.Format("Asset {0} : Normal completion", rdata.method));
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asset processing has no special data area requirements.
|
||||
/// </summary>
|
||||
|
||||
internal class AssetRequestData : RequestData
|
||||
{
|
||||
internal AssetRequestData(OSHttpRequest request, OSHttpResponse response, string prefix)
|
||||
: base(request, response, prefix)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
448
OpenSim/ApplicationPlugins/Rest/Inventory/RestFileServices.cs
Normal file
448
OpenSim/ApplicationPlugins/Rest/Inventory/RestFileServices.cs
Normal file
@@ -0,0 +1,448 @@
|
||||
/*
|
||||
* 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.Xml;
|
||||
using System.IO;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Servers;
|
||||
using OpenSim.Framework.Servers.HttpServer;
|
||||
|
||||
namespace OpenSim.ApplicationPlugins.Rest.Inventory
|
||||
{
|
||||
public class RestFileServices : IRest
|
||||
{
|
||||
private bool enabled = false;
|
||||
private string qPrefix = "files";
|
||||
|
||||
// A simple constructor is used to handle any once-only
|
||||
// initialization of working classes.
|
||||
|
||||
public RestFileServices()
|
||||
{
|
||||
Rest.Log.InfoFormat("{0} File services initializing", MsgId);
|
||||
Rest.Log.InfoFormat("{0} Using REST Implementation Version {1}", MsgId, Rest.Version);
|
||||
|
||||
// If the handler specifies a relative path for its domain
|
||||
// then we must add the standard absolute prefix, e.g. /admin
|
||||
|
||||
if (!qPrefix.StartsWith(Rest.UrlPathSeparator))
|
||||
{
|
||||
Rest.Log.InfoFormat("{0} Prefixing domain name ({1})", MsgId, qPrefix);
|
||||
qPrefix = String.Format("{0}{1}{2}", Rest.Prefix, Rest.UrlPathSeparator, qPrefix);
|
||||
Rest.Log.InfoFormat("{0} Fully qualified domain name is <{1}>", MsgId, qPrefix);
|
||||
}
|
||||
|
||||
// Register interface using the fully-qualified prefix
|
||||
|
||||
Rest.Plugin.AddPathHandler(DoFile, qPrefix, Allocate);
|
||||
|
||||
// Activate if all went OK
|
||||
|
||||
enabled = true;
|
||||
|
||||
Rest.Log.InfoFormat("{0} File services initialization complete", MsgId);
|
||||
}
|
||||
|
||||
// Post-construction, pre-enabled initialization opportunity
|
||||
// Not currently exploited.
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
}
|
||||
|
||||
// Called by the plug-in to halt REST processing. Local processing is
|
||||
// disabled, and control blocks until all current processing has
|
||||
// completed. No new processing will be started
|
||||
|
||||
public void Close()
|
||||
{
|
||||
enabled = false;
|
||||
Rest.Log.InfoFormat("{0} File services ({1}) closing down", MsgId, qPrefix);
|
||||
}
|
||||
|
||||
// Properties
|
||||
|
||||
internal string MsgId
|
||||
{
|
||||
get { return Rest.MsgId; }
|
||||
}
|
||||
|
||||
#region Interface
|
||||
|
||||
private RequestData Allocate(OSHttpRequest request, OSHttpResponse response, string prefix)
|
||||
{
|
||||
return (RequestData) new FileRequestData(request, response, prefix);
|
||||
}
|
||||
|
||||
// Asset Handler
|
||||
|
||||
private void DoFile(RequestData rparm)
|
||||
{
|
||||
if (!enabled) return;
|
||||
|
||||
FileRequestData rdata = (FileRequestData) rparm;
|
||||
|
||||
Rest.Log.DebugFormat("{0} REST File handler ({1}) ENTRY", MsgId, qPrefix);
|
||||
|
||||
// Now that we know this is a serious attempt to
|
||||
// access file data, we should find out who
|
||||
// is asking, and make sure they are authorized
|
||||
// to do so. We need to validate the caller's
|
||||
// identity before revealing anything about the
|
||||
// status quo. Authenticate throws an exception
|
||||
// via Fail if no identity information is present.
|
||||
//
|
||||
// With the present HTTP server we can't use the
|
||||
// builtin authentication mechanisms because they
|
||||
// would be enforced for all in-bound requests.
|
||||
// Instead we look at the headers ourselves and
|
||||
// handle authentication directly.
|
||||
|
||||
try
|
||||
{
|
||||
if (!rdata.IsAuthenticated)
|
||||
{
|
||||
rdata.Fail(Rest.HttpStatusCodeNotAuthorized, String.Format("user \"{0}\" could not be authenticated"));
|
||||
}
|
||||
}
|
||||
catch (RestException e)
|
||||
{
|
||||
if (e.statusCode == Rest.HttpStatusCodeNotAuthorized)
|
||||
{
|
||||
Rest.Log.WarnFormat("{0} User not authenticated", MsgId);
|
||||
Rest.Log.DebugFormat("{0} Authorization header: {1}", MsgId,
|
||||
rdata.request.Headers.Get("Authorization"));
|
||||
}
|
||||
else
|
||||
{
|
||||
Rest.Log.ErrorFormat("{0} User authentication failed", MsgId);
|
||||
Rest.Log.DebugFormat("{0} Authorization header: {1}", MsgId,
|
||||
rdata.request.Headers.Get("Authorization"));
|
||||
}
|
||||
throw (e);
|
||||
}
|
||||
|
||||
// Remove the prefix and what's left are the parameters. If we don't have
|
||||
// the parameters we need, fail the request. Parameters do NOT include
|
||||
// any supplied query values.
|
||||
|
||||
if (rdata.Parameters.Length > 0)
|
||||
{
|
||||
switch (rdata.method)
|
||||
{
|
||||
case "get" :
|
||||
DoGet(rdata);
|
||||
break;
|
||||
case "put" :
|
||||
DoPut(rdata);
|
||||
break;
|
||||
case "post" :
|
||||
DoPost(rdata);
|
||||
break;
|
||||
case "delete" :
|
||||
DoDelete(rdata);
|
||||
break;
|
||||
default :
|
||||
Rest.Log.WarnFormat("{0} File: Method not supported: {1}",
|
||||
MsgId, rdata.method);
|
||||
rdata.Fail(Rest.HttpStatusCodeBadRequest,String.Format("method <{0}> not supported", rdata.method));
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Rest.Log.WarnFormat("{0} File: No agent information provided", MsgId);
|
||||
rdata.Fail(Rest.HttpStatusCodeBadRequest, "no agent information provided");
|
||||
}
|
||||
|
||||
Rest.Log.DebugFormat("{0} REST File handler EXIT", MsgId);
|
||||
|
||||
}
|
||||
|
||||
#endregion Interface
|
||||
|
||||
/// <summary>
|
||||
/// The only parameter we recognize is a UUID.If an asset with this identification is
|
||||
/// found, it's content, base-64 encoded, is returned to the client.
|
||||
/// </summary>
|
||||
|
||||
private void DoGet(FileRequestData rdata)
|
||||
{
|
||||
|
||||
string path = String.Empty;
|
||||
|
||||
Rest.Log.DebugFormat("{0} REST File handler, Method = <{1}> ENTRY", MsgId, rdata.method);
|
||||
|
||||
if (rdata.Parameters.Length > 1)
|
||||
{
|
||||
try
|
||||
{
|
||||
path = rdata.path.Substring(rdata.Parameters[0].Length+qPrefix.Length+2);
|
||||
if (File.Exists(path))
|
||||
{
|
||||
Rest.Log.DebugFormat("{0} File located <{1}>", MsgId, path);
|
||||
Byte[] data = File.ReadAllBytes(path);
|
||||
rdata.initXmlWriter();
|
||||
rdata.writer.WriteStartElement(String.Empty,"File",String.Empty);
|
||||
rdata.writer.WriteAttributeString("name", path);
|
||||
rdata.writer.WriteBase64(data,0,data.Length);
|
||||
rdata.writer.WriteFullEndElement();
|
||||
}
|
||||
else
|
||||
{
|
||||
Rest.Log.DebugFormat("{0} Invalid parameters: <{1}>", MsgId, path);
|
||||
rdata.Fail(Rest.HttpStatusCodeNotFound, String.Format("invalid parameters : {0}", path));
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Rest.Log.DebugFormat("{0} Invalid parameters: <{1}>", MsgId, e.Message);
|
||||
rdata.Fail(Rest.HttpStatusCodeNotFound, String.Format("invalid parameters : {0} {1}",
|
||||
path, e.Message));
|
||||
}
|
||||
}
|
||||
|
||||
rdata.Complete();
|
||||
rdata.Respond(String.Format("File <{0}> : Normal completion", rdata.method));
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// UPDATE existing item, if it exists. URI identifies the item in question.
|
||||
/// The only parameter we recognize is a UUID. The enclosed asset data (base-64 encoded)
|
||||
/// is decoded and stored in the database, identified by the supplied UUID.
|
||||
/// </summary>
|
||||
private void DoPut(FileRequestData rdata)
|
||||
{
|
||||
bool modified = false;
|
||||
bool created = false;
|
||||
string path = String.Empty;
|
||||
|
||||
Rest.Log.DebugFormat("{0} REST File handler, Method = <{1}> ENTRY", MsgId, rdata.method);
|
||||
|
||||
if (rdata.Parameters.Length > 1)
|
||||
{
|
||||
try
|
||||
{
|
||||
path = rdata.path.Substring(rdata.Parameters[0].Length+qPrefix.Length+2);
|
||||
bool maymod = File.Exists(path);
|
||||
|
||||
rdata.initXmlReader();
|
||||
XmlReader xml = rdata.reader;
|
||||
|
||||
if (!xml.ReadToFollowing("File"))
|
||||
{
|
||||
Rest.Log.DebugFormat("{0} Invalid request data: <{1}>", MsgId, rdata.path);
|
||||
rdata.Fail(Rest.HttpStatusCodeBadRequest,"invalid request data");
|
||||
}
|
||||
|
||||
Byte[] data = Convert.FromBase64String(xml.ReadElementContentAsString("File", ""));
|
||||
|
||||
File.WriteAllBytes(path,data);
|
||||
modified = maymod;
|
||||
created = ! maymod;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Rest.Log.DebugFormat("{0} Exception during file processing : {1}", MsgId,
|
||||
e.Message);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Rest.Log.DebugFormat("{0} Invalid parameters: <{1}>", MsgId, rdata.path);
|
||||
rdata.Fail(Rest.HttpStatusCodeNotFound, "invalid parameters");
|
||||
}
|
||||
|
||||
if (created)
|
||||
{
|
||||
rdata.appendStatus(String.Format("<p> Created file {0} <p>", path));
|
||||
rdata.Complete(Rest.HttpStatusCodeCreated);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (modified)
|
||||
{
|
||||
rdata.appendStatus(String.Format("<p> Modified file {0} <p>", path));
|
||||
rdata.Complete(Rest.HttpStatusCodeOK);
|
||||
}
|
||||
else
|
||||
{
|
||||
rdata.Complete(Rest.HttpStatusCodeNoContent);
|
||||
}
|
||||
}
|
||||
|
||||
rdata.Respond(String.Format("File {0} : Normal completion", rdata.method));
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// CREATE new item, replace if it exists. URI identifies the context for the item in question.
|
||||
/// No parameters are required for POST, just thepayload.
|
||||
/// </summary>
|
||||
|
||||
private void DoPost(FileRequestData rdata)
|
||||
{
|
||||
|
||||
bool modified = false;
|
||||
bool created = false;
|
||||
string path = String.Empty;
|
||||
|
||||
Rest.Log.DebugFormat("{0} REST File handler, Method = <{1}> ENTRY", MsgId, rdata.method);
|
||||
|
||||
if (rdata.Parameters.Length > 1)
|
||||
{
|
||||
try
|
||||
{
|
||||
path = rdata.path.Substring(rdata.Parameters[0].Length+qPrefix.Length+2);
|
||||
bool maymod = File.Exists(path);
|
||||
|
||||
rdata.initXmlReader();
|
||||
XmlReader xml = rdata.reader;
|
||||
|
||||
if (!xml.ReadToFollowing("File"))
|
||||
{
|
||||
Rest.Log.DebugFormat("{0} Invalid request data: <{1}>", MsgId, rdata.path);
|
||||
rdata.Fail(Rest.HttpStatusCodeBadRequest,"invalid request data");
|
||||
}
|
||||
|
||||
Byte[] data = Convert.FromBase64String(xml.ReadElementContentAsString("File", ""));
|
||||
|
||||
File.WriteAllBytes(path,data);
|
||||
modified = maymod;
|
||||
created = ! maymod;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Rest.Log.DebugFormat("{0} Exception during file processing : {1}", MsgId,
|
||||
e.Message);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Rest.Log.DebugFormat("{0} Invalid parameters: <{1}>", MsgId, rdata.path);
|
||||
rdata.Fail(Rest.HttpStatusCodeNotFound, "invalid parameters");
|
||||
}
|
||||
|
||||
if (created)
|
||||
{
|
||||
rdata.appendStatus(String.Format("<p> Created file {0} <p>", path));
|
||||
rdata.Complete(Rest.HttpStatusCodeCreated);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (modified)
|
||||
{
|
||||
rdata.appendStatus(String.Format("<p> Modified file {0} <p>", path));
|
||||
rdata.Complete(Rest.HttpStatusCodeOK);
|
||||
}
|
||||
else
|
||||
{
|
||||
rdata.Complete(Rest.HttpStatusCodeNoContent);
|
||||
}
|
||||
}
|
||||
|
||||
rdata.Respond(String.Format("File {0} : Normal completion", rdata.method));
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// CREATE new item, replace if it exists. URI identifies the context for the item in question.
|
||||
/// No parameters are required for POST, just thepayload.
|
||||
/// </summary>
|
||||
|
||||
private void DoDelete(FileRequestData rdata)
|
||||
{
|
||||
|
||||
bool modified = false;
|
||||
bool created = false;
|
||||
string path = String.Empty;
|
||||
|
||||
Rest.Log.DebugFormat("{0} REST File handler, Method = <{1}> ENTRY", MsgId, rdata.method);
|
||||
|
||||
if (rdata.Parameters.Length > 1)
|
||||
{
|
||||
try
|
||||
{
|
||||
path = rdata.path.Substring(rdata.Parameters[0].Length+qPrefix.Length+2);
|
||||
|
||||
if (File.Exists(path))
|
||||
{
|
||||
File.Delete(path);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Rest.Log.DebugFormat("{0} Exception during file processing : {1}", MsgId,
|
||||
e.Message);
|
||||
rdata.Fail(Rest.HttpStatusCodeNotFound, String.Format("invalid parameters : {0} {1}",
|
||||
path, e.Message));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Rest.Log.DebugFormat("{0} Invalid parameters: <{1}>", MsgId, rdata.path);
|
||||
rdata.Fail(Rest.HttpStatusCodeNotFound, "invalid parameters");
|
||||
}
|
||||
|
||||
if (created)
|
||||
{
|
||||
rdata.appendStatus(String.Format("<p> Created file {0} <p>", path));
|
||||
rdata.Complete(Rest.HttpStatusCodeCreated);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (modified)
|
||||
{
|
||||
rdata.appendStatus(String.Format("<p> Modified file {0} <p>", path));
|
||||
rdata.Complete(Rest.HttpStatusCodeOK);
|
||||
}
|
||||
else
|
||||
{
|
||||
rdata.Complete(Rest.HttpStatusCodeNoContent);
|
||||
}
|
||||
}
|
||||
|
||||
rdata.Respond(String.Format("File {0} : Normal completion", rdata.method));
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// File processing has no special data area requirements.
|
||||
/// </summary>
|
||||
|
||||
internal class FileRequestData : RequestData
|
||||
{
|
||||
internal FileRequestData(OSHttpRequest request, OSHttpResponse response, string prefix)
|
||||
: base(request, response, prefix)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
658
OpenSim/ApplicationPlugins/Rest/Inventory/RestHandler.cs
Normal file
658
OpenSim/ApplicationPlugins/Rest/Inventory/RestHandler.cs
Normal file
@@ -0,0 +1,658 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using OpenSim.Framework.Servers;
|
||||
using OpenSim.Framework.Servers.HttpServer;
|
||||
|
||||
namespace OpenSim.ApplicationPlugins.Rest.Inventory
|
||||
{
|
||||
/// <remarks>
|
||||
/// The class signature reveals the roles that RestHandler plays.
|
||||
///
|
||||
/// [1] It is a sub-class of RestPlugin. It inherits and extends
|
||||
/// the functionality of this class, constraining it to the
|
||||
/// specific needs of this REST implementation. This relates
|
||||
/// to the plug-in mechanism supported by OpenSim, the specifics
|
||||
/// of which are mostly hidden by RestPlugin.
|
||||
/// [2] IRestHandler describes the interface that this class
|
||||
/// exports to service implementations. This is the services
|
||||
/// management interface.
|
||||
/// [3] IHttpAgentHandler describes the interface that is exported
|
||||
/// to the BaseHttpServer in support of this particular HTTP
|
||||
/// processing model. This is the request interface of the
|
||||
/// handler.
|
||||
/// </remarks>
|
||||
|
||||
public class RestHandler : RestPlugin, IRestHandler, IHttpAgentHandler
|
||||
{
|
||||
// Handler tables: both stream and REST are supported. The path handlers and their
|
||||
// respective allocators are stored in separate tables.
|
||||
|
||||
internal Dictionary<string,RestMethodHandler> pathHandlers = new Dictionary<string,RestMethodHandler>();
|
||||
internal Dictionary<string,RestMethodAllocator> pathAllocators = new Dictionary<string,RestMethodAllocator>();
|
||||
internal Dictionary<string,RestStreamHandler> streamHandlers = new Dictionary<string,RestStreamHandler>();
|
||||
|
||||
#region local static state
|
||||
|
||||
private static bool handlersLoaded = false;
|
||||
private static List<Type> classes = new List<Type>();
|
||||
private static List<IRest> handlers = new List<IRest>();
|
||||
private static Type[] parms = new Type[0];
|
||||
private static Object[] args = new Object[0];
|
||||
|
||||
/// <summary>
|
||||
/// This static initializer scans the ASSEMBLY for classes that
|
||||
/// export the IRest interface and builds a list of them. These
|
||||
/// are later activated by the handler. To add a new handler it
|
||||
/// is only necessary to create a new services class that implements
|
||||
/// the IRest interface, and recompile the handler. This gives
|
||||
/// all of the build-time flexibility of a modular approach
|
||||
/// while not introducing yet-another module loader. Note that
|
||||
/// multiple assembles can still be built, each with its own set
|
||||
/// of handlers. Examples of services classes are RestInventoryServices
|
||||
/// and RestSkeleton.
|
||||
/// </summary>
|
||||
|
||||
static RestHandler()
|
||||
{
|
||||
Module[] mods = Assembly.GetExecutingAssembly().GetModules();
|
||||
|
||||
foreach (Module m in mods)
|
||||
{
|
||||
Type[] types = m.GetTypes();
|
||||
foreach (Type t in types)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (t.GetInterface("IRest") != null)
|
||||
{
|
||||
classes.Add(t);
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
Rest.Log.WarnFormat("[STATIC-HANDLER]: #0 Error scanning {1}", t);
|
||||
Rest.Log.InfoFormat("[STATIC-HANDLER]: #0 {1} is not included", t);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion local static state
|
||||
|
||||
#region local instance state
|
||||
|
||||
/// <summary>
|
||||
/// This routine loads all of the handlers discovered during
|
||||
/// instance initialization.
|
||||
/// A table of all loaded and successfully constructed handlers
|
||||
/// is built, and this table is then used by the constructor to
|
||||
/// initialize each of the handlers in turn.
|
||||
/// NOTE: The loading process does not automatically imply that
|
||||
/// the handler has registered any kind of an interface, that
|
||||
/// may be (optionally) done by the handler either during
|
||||
/// construction, or during initialization.
|
||||
///
|
||||
/// I was not able to make this code work within a constructor
|
||||
/// so it is isolated within this method.
|
||||
/// </summary>
|
||||
|
||||
private void LoadHandlers()
|
||||
{
|
||||
lock (handlers)
|
||||
{
|
||||
if (!handlersLoaded)
|
||||
{
|
||||
ConstructorInfo ci;
|
||||
Object ht;
|
||||
|
||||
foreach (Type t in classes)
|
||||
{
|
||||
try
|
||||
{
|
||||
ci = t.GetConstructor(parms);
|
||||
ht = ci.Invoke(args);
|
||||
handlers.Add((IRest)ht);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Rest.Log.WarnFormat("{0} Unable to load {1} : {2}", MsgId, t, e.Message);
|
||||
}
|
||||
}
|
||||
handlersLoaded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion local instance state
|
||||
|
||||
#region overriding properties
|
||||
|
||||
// These properties override definitions
|
||||
// in the base class.
|
||||
|
||||
// Name is used to differentiate the message header.
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "HANDLER"; }
|
||||
}
|
||||
|
||||
// Used to partition the .ini configuration space.
|
||||
|
||||
public override string ConfigName
|
||||
{
|
||||
get { return "RestHandler"; }
|
||||
}
|
||||
|
||||
// We have to rename these because we want
|
||||
// to be able to share the values with other
|
||||
// classes in our assembly and the base
|
||||
// names are protected.
|
||||
|
||||
public string MsgId
|
||||
{
|
||||
get { return base.MsgID; }
|
||||
}
|
||||
|
||||
public string RequestId
|
||||
{
|
||||
get { return base.RequestID; }
|
||||
}
|
||||
|
||||
#endregion overriding properties
|
||||
|
||||
#region overriding methods
|
||||
|
||||
/// <summary>
|
||||
/// This method is called by OpenSimMain immediately after loading the
|
||||
/// plugin and after basic server setup, but before running any server commands.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Note that entries MUST be added to the active configuration files before
|
||||
/// the plugin can be enabled.
|
||||
/// </remarks>
|
||||
|
||||
public override void Initialise(OpenSimBase openSim)
|
||||
{
|
||||
try
|
||||
{
|
||||
// This plugin will only be enabled if the broader
|
||||
// REST plugin mechanism is enabled.
|
||||
|
||||
//Rest.Log.InfoFormat("{0} Plugin is initializing", MsgId);
|
||||
|
||||
base.Initialise(openSim);
|
||||
|
||||
// IsEnabled is implemented by the base class and
|
||||
// reflects an overall RestPlugin status
|
||||
|
||||
if (!IsEnabled)
|
||||
{
|
||||
//Rest.Log.WarnFormat("{0} Plugins are disabled", MsgId);
|
||||
return;
|
||||
}
|
||||
|
||||
Rest.Log.InfoFormat("{0} Rest <{1}> plugin will be enabled", MsgId, Name);
|
||||
Rest.Log.InfoFormat("{0} Configuration parameters read from <{1}>", MsgId, ConfigName);
|
||||
|
||||
// These are stored in static variables to make
|
||||
// them easy to reach from anywhere in the assembly.
|
||||
|
||||
Rest.main = openSim;
|
||||
if (Rest.main == null)
|
||||
throw new Exception("OpenSim base pointer is null");
|
||||
|
||||
Rest.Plugin = this;
|
||||
Rest.Config = Config;
|
||||
Rest.Prefix = Prefix;
|
||||
Rest.GodKey = GodKey;
|
||||
Rest.Authenticate = Rest.Config.GetBoolean("authenticate", Rest.Authenticate);
|
||||
Rest.Scheme = Rest.Config.GetString("auth-scheme", Rest.Scheme);
|
||||
Rest.Secure = Rest.Config.GetBoolean("secured", Rest.Secure);
|
||||
Rest.ExtendedEscape = Rest.Config.GetBoolean("extended-escape", Rest.ExtendedEscape);
|
||||
Rest.Realm = Rest.Config.GetString("realm", Rest.Realm);
|
||||
Rest.DumpAsset = Rest.Config.GetBoolean("dump-asset", Rest.DumpAsset);
|
||||
Rest.Fill = Rest.Config.GetBoolean("path-fill", Rest.Fill);
|
||||
Rest.DumpLineSize = Rest.Config.GetInt("dump-line-size", Rest.DumpLineSize);
|
||||
Rest.FlushEnabled = Rest.Config.GetBoolean("flush-on-error", Rest.FlushEnabled);
|
||||
|
||||
// Note: Odd spacing is required in the following strings
|
||||
|
||||
Rest.Log.InfoFormat("{0} Authentication is {1}required", MsgId,
|
||||
(Rest.Authenticate ? "" : "not "));
|
||||
|
||||
Rest.Log.InfoFormat("{0} Security is {1}enabled", MsgId,
|
||||
(Rest.Secure ? "" : "not "));
|
||||
|
||||
Rest.Log.InfoFormat("{0} Extended URI escape processing is {1}enabled", MsgId,
|
||||
(Rest.ExtendedEscape ? "" : "not "));
|
||||
|
||||
Rest.Log.InfoFormat("{0} Dumping of asset data is {1}enabled", MsgId,
|
||||
(Rest.DumpAsset ? "" : "not "));
|
||||
|
||||
// The supplied prefix MUST be absolute
|
||||
|
||||
if (Rest.Prefix.Substring(0,1) != Rest.UrlPathSeparator)
|
||||
{
|
||||
Rest.Log.WarnFormat("{0} Prefix <{1}> is not absolute and must be", MsgId, Rest.Prefix);
|
||||
Rest.Log.InfoFormat("{0} Prefix changed to </{1}>", MsgId, Rest.Prefix);
|
||||
Rest.Prefix = String.Format("{0}{1}", Rest.UrlPathSeparator, Rest.Prefix);
|
||||
}
|
||||
|
||||
// If data dumping is requested, report on the chosen line
|
||||
// length.
|
||||
|
||||
if (Rest.DumpAsset)
|
||||
{
|
||||
Rest.Log.InfoFormat("{0} Dump {1} bytes per line", MsgId, Rest.DumpLineSize);
|
||||
}
|
||||
|
||||
// Load all of the handlers present in the
|
||||
// assembly
|
||||
|
||||
// In principle, as we're an application plug-in,
|
||||
// most of what needs to be done could be done using
|
||||
// static resources, however the Open Sim plug-in
|
||||
// model makes this an instance, so that's what we
|
||||
// need to be.
|
||||
// There is only one Communications manager per
|
||||
// server, and by inference, only one each of the
|
||||
// user, asset, and inventory servers. So we can cache
|
||||
// those using a static initializer.
|
||||
// We move all of this processing off to another
|
||||
// services class to minimize overlap between function
|
||||
// and infrastructure.
|
||||
|
||||
LoadHandlers();
|
||||
|
||||
// The intention of a post construction initializer
|
||||
// is to allow for setup that is dependent upon other
|
||||
// activities outside of the agency.
|
||||
|
||||
foreach (IRest handler in handlers)
|
||||
{
|
||||
try
|
||||
{
|
||||
handler.Initialize();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Rest.Log.ErrorFormat("{0} initialization error: {1}", MsgId, e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
// Now that everything is setup we can proceed to
|
||||
// add THIS agent to the HTTP server's handler list
|
||||
|
||||
if (!AddAgentHandler(Rest.Name,this))
|
||||
{
|
||||
Rest.Log.ErrorFormat("{0} Unable to activate handler interface", MsgId);
|
||||
foreach (IRest handler in handlers)
|
||||
{
|
||||
handler.Close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Rest.Log.ErrorFormat("{0} Plugin initialization has failed: {1}", MsgId, e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// In the interests of efficiency, and because we cannot determine whether
|
||||
/// or not this instance will actually be harvested, we clobber the only
|
||||
/// anchoring reference to the working state for this plug-in. What the
|
||||
/// call to close does is irrelevant to this class beyond knowing that it
|
||||
/// can nullify the reference when it returns.
|
||||
/// To make sure everything is copacetic we make sure the primary interface
|
||||
/// is disabled by deleting the handler from the HTTP server tables.
|
||||
/// </summary>
|
||||
|
||||
public override void Close()
|
||||
{
|
||||
Rest.Log.InfoFormat("{0} Plugin is terminating", MsgId);
|
||||
|
||||
try
|
||||
{
|
||||
RemoveAgentHandler(Rest.Name, this);
|
||||
}
|
||||
catch (KeyNotFoundException){}
|
||||
|
||||
foreach (IRest handler in handlers)
|
||||
{
|
||||
handler.Close();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion overriding methods
|
||||
|
||||
#region interface methods
|
||||
|
||||
/// <summary>
|
||||
/// This method is called by the HTTP server to match an incoming
|
||||
/// request. It scans all of the strings registered by the
|
||||
/// underlying handlers and looks for the best match. It returns
|
||||
/// true if a match is found.
|
||||
/// The matching process could be made arbitrarily complex.
|
||||
/// Note: The match is case-insensitive.
|
||||
/// </summary>
|
||||
|
||||
public bool Match(OSHttpRequest request, OSHttpResponse response)
|
||||
{
|
||||
|
||||
string path = request.RawUrl.ToLower();
|
||||
|
||||
// Rest.Log.DebugFormat("{0} Match ENTRY", MsgId);
|
||||
|
||||
try
|
||||
{
|
||||
foreach (string key in pathHandlers.Keys)
|
||||
{
|
||||
// Rest.Log.DebugFormat("{0} Match testing {1} against agent prefix <{2}>", MsgId, path, key);
|
||||
|
||||
// Note that Match will not necessarily find the handler that will
|
||||
// actually be used - it does no test for the "closest" fit. It
|
||||
// simply reflects that at least one possible handler exists.
|
||||
|
||||
if (path.StartsWith(key))
|
||||
{
|
||||
// Rest.Log.DebugFormat("{0} Matched prefix <{1}>", MsgId, key);
|
||||
|
||||
// This apparently odd evaluation is needed to prevent a match
|
||||
// on anything other than a URI token boundary. Otherwise we
|
||||
// may match on URL's that were not intended for this handler.
|
||||
|
||||
return (path.Length == key.Length ||
|
||||
path.Substring(key.Length, 1) == Rest.UrlPathSeparator);
|
||||
}
|
||||
}
|
||||
|
||||
path = String.Format("{0}{1}{2}", request.HttpMethod, Rest.UrlMethodSeparator, path);
|
||||
|
||||
foreach (string key in streamHandlers.Keys)
|
||||
{
|
||||
// Rest.Log.DebugFormat("{0} Match testing {1} against stream prefix <{2}>", MsgId, path, key);
|
||||
|
||||
// Note that Match will not necessarily find the handler that will
|
||||
// actually be used - it does no test for the "closest" fit. It
|
||||
// simply reflects that at least one possible handler exists.
|
||||
|
||||
if (path.StartsWith(key))
|
||||
{
|
||||
// Rest.Log.DebugFormat("{0} Matched prefix <{1}>", MsgId, key);
|
||||
|
||||
// This apparently odd evaluation is needed to prevent a match
|
||||
// on anything other than a URI token boundary. Otherwise we
|
||||
// may match on URL's that were not intended for this handler.
|
||||
|
||||
return (path.Length == key.Length ||
|
||||
path.Substring(key.Length, 1) == Rest.UrlPathSeparator);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Rest.Log.ErrorFormat("{0} matching exception for path <{1}> : {2}", MsgId, path, e.Message);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is called by the HTTP server once the handler has indicated
|
||||
/// that it is able to handle the request.
|
||||
/// Preconditions:
|
||||
/// [1] request != null and is a valid request object
|
||||
/// [2] response != null and is a valid response object
|
||||
/// Behavior is undefined if preconditions are not satisfied.
|
||||
/// </summary>
|
||||
|
||||
public bool Handle(OSHttpRequest request, OSHttpResponse response)
|
||||
{
|
||||
bool handled;
|
||||
base.MsgID = base.RequestID;
|
||||
|
||||
// Debug only
|
||||
|
||||
if (Rest.DEBUG)
|
||||
{
|
||||
Rest.Log.DebugFormat("{0} ENTRY", MsgId);
|
||||
Rest.Log.DebugFormat("{0} Agent: {1}", MsgId, request.UserAgent);
|
||||
Rest.Log.DebugFormat("{0} Method: {1}", MsgId, request.HttpMethod);
|
||||
|
||||
for (int i = 0; i < request.Headers.Count; i++)
|
||||
{
|
||||
Rest.Log.DebugFormat("{0} Header [{1}] : <{2}> = <{3}>",
|
||||
MsgId, i, request.Headers.GetKey(i), request.Headers.Get(i));
|
||||
}
|
||||
Rest.Log.DebugFormat("{0} URI: {1}", MsgId, request.RawUrl);
|
||||
}
|
||||
|
||||
// If a path handler worked we're done, otherwise try any
|
||||
// available stream handlers too.
|
||||
|
||||
try
|
||||
{
|
||||
handled = (FindPathHandler(request, response) ||
|
||||
FindStreamHandler(request, response));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// A raw exception indicates that something we weren't expecting has
|
||||
// happened. This should always reflect a shortcoming in the plugin,
|
||||
// or a failure to satisfy the preconditions. It should not reflect
|
||||
// an error in the request itself. Under such circumstances the state
|
||||
// of the request cannot be determined and we are obliged to mark it
|
||||
// as 'handled'.
|
||||
|
||||
Rest.Log.ErrorFormat("{0} Plugin error: {1}", MsgId, e.Message);
|
||||
handled = true;
|
||||
}
|
||||
|
||||
Rest.Log.DebugFormat("{0} EXIT", MsgId);
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
#endregion interface methods
|
||||
|
||||
/// <summary>
|
||||
/// If there is a stream handler registered that can handle the
|
||||
/// request, then fine. If the request is not matched, do
|
||||
/// nothing.
|
||||
/// Note: The selection is case-insensitive
|
||||
/// </summary>
|
||||
|
||||
private bool FindStreamHandler(OSHttpRequest request, OSHttpResponse response)
|
||||
{
|
||||
RequestData rdata = new RequestData(request, response, String.Empty);
|
||||
|
||||
string bestMatch = String.Empty;
|
||||
string path = String.Format("{0}:{1}", rdata.method, rdata.path).ToLower();
|
||||
|
||||
Rest.Log.DebugFormat("{0} Checking for stream handler for <{1}>", MsgId, path);
|
||||
|
||||
if (!IsEnabled)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (string pattern in streamHandlers.Keys)
|
||||
{
|
||||
if (path.StartsWith(pattern))
|
||||
{
|
||||
if (pattern.Length > bestMatch.Length)
|
||||
{
|
||||
bestMatch = pattern;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Handle using the best match available
|
||||
|
||||
if (bestMatch.Length > 0)
|
||||
{
|
||||
Rest.Log.DebugFormat("{0} Stream-based handler matched with <{1}>", MsgId, bestMatch);
|
||||
RestStreamHandler handler = streamHandlers[bestMatch];
|
||||
rdata.buffer = handler.Handle(rdata.path, rdata.request.InputStream, rdata.request, rdata.response);
|
||||
rdata.AddHeader(rdata.response.ContentType,handler.ContentType);
|
||||
rdata.Respond("FindStreamHandler Completion");
|
||||
}
|
||||
|
||||
return rdata.handled;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add a stream handler for the designated HTTP method and path prefix.
|
||||
/// If the handler is not enabled, the request is ignored. If the path
|
||||
/// does not start with the REST prefix, it is added. If method-qualified
|
||||
/// 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)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!path.StartsWith(Rest.Prefix))
|
||||
{
|
||||
path = String.Format("{0}{1}", Rest.Prefix, path);
|
||||
}
|
||||
|
||||
path = String.Format("{0}{1}{2}", httpMethod, Rest.UrlMethodSeparator, path);
|
||||
|
||||
// Conditionally add to the list
|
||||
|
||||
if (!streamHandlers.ContainsKey(path))
|
||||
{
|
||||
streamHandlers.Add(path, new RestStreamHandler(httpMethod, path, method));
|
||||
Rest.Log.DebugFormat("{0} Added handler for {1}", MsgId, path);
|
||||
}
|
||||
else
|
||||
{
|
||||
Rest.Log.WarnFormat("{0} Ignoring duplicate handler for {1}", MsgId, path);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Given the supplied request/response, if the handler is enabled, the inbound
|
||||
/// information is used to match an entry in the active path handler tables, using
|
||||
/// the method-qualified path information. If a match is found, then the handler is
|
||||
/// invoked. The result is the boolean result of the handler, or false if no
|
||||
/// handler was located. The boolean indicates whether or not the request has been
|
||||
/// handled, not whether or not the request was successful - that information is in
|
||||
/// the response.
|
||||
/// Note: The selection process is case-insensitive
|
||||
/// </summary>
|
||||
|
||||
internal bool FindPathHandler(OSHttpRequest request, OSHttpResponse response)
|
||||
{
|
||||
RequestData rdata = null;
|
||||
string bestMatch = null;
|
||||
|
||||
if (!IsEnabled)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Conditionally add to the list
|
||||
|
||||
Rest.Log.DebugFormat("{0} Checking for path handler for <{1}>", MsgId, request.RawUrl);
|
||||
|
||||
foreach (string pattern in pathHandlers.Keys)
|
||||
{
|
||||
if (request.RawUrl.ToLower().StartsWith(pattern))
|
||||
{
|
||||
if (String.IsNullOrEmpty(bestMatch) || pattern.Length > bestMatch.Length)
|
||||
{
|
||||
bestMatch = pattern;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!String.IsNullOrEmpty(bestMatch))
|
||||
{
|
||||
rdata = pathAllocators[bestMatch](request, response, bestMatch);
|
||||
|
||||
Rest.Log.DebugFormat("{0} Path based REST handler matched with <{1}>", MsgId, bestMatch);
|
||||
|
||||
try
|
||||
{
|
||||
pathHandlers[bestMatch](rdata);
|
||||
}
|
||||
|
||||
// A plugin generated error indicates a request-related error
|
||||
// that has been handled by the plugin.
|
||||
|
||||
catch (RestException r)
|
||||
{
|
||||
Rest.Log.WarnFormat("{0} Request failed: {1}", MsgId, r.Message);
|
||||
}
|
||||
}
|
||||
|
||||
return (rdata == null) ? false : rdata.handled;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A method handler and a request allocator are stored using the designated
|
||||
/// path as a key. If an entry already exists, it is replaced by the new one.
|
||||
/// </summary>
|
||||
|
||||
public void AddPathHandler(RestMethodHandler mh, string path, RestMethodAllocator ra)
|
||||
{
|
||||
if (!IsEnabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (pathHandlers.ContainsKey(path))
|
||||
{
|
||||
Rest.Log.DebugFormat("{0} Replacing handler for <${1}>", MsgId, path);
|
||||
pathHandlers.Remove(path);
|
||||
}
|
||||
|
||||
if (pathAllocators.ContainsKey(path))
|
||||
{
|
||||
Rest.Log.DebugFormat("{0} Replacing allocator for <${1}>", MsgId, path);
|
||||
pathAllocators.Remove(path);
|
||||
}
|
||||
|
||||
Rest.Log.DebugFormat("{0} Adding path handler for {1}", MsgId, path);
|
||||
|
||||
pathHandlers.Add(path, mh);
|
||||
pathAllocators.Add(path, ra);
|
||||
}
|
||||
}
|
||||
}
|
||||
2343
OpenSim/ApplicationPlugins/Rest/Inventory/RestInventoryServices.cs
Normal file
2343
OpenSim/ApplicationPlugins/Rest/Inventory/RestInventoryServices.cs
Normal file
File diff suppressed because it is too large
Load Diff
246
OpenSim/ApplicationPlugins/Rest/Inventory/RestTestServices.cs
Normal file
246
OpenSim/ApplicationPlugins/Rest/Inventory/RestTestServices.cs
Normal file
@@ -0,0 +1,246 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using OpenSim.Framework.Servers;
|
||||
using OpenSim.Framework.Servers.HttpServer;
|
||||
|
||||
namespace OpenSim.ApplicationPlugins.Rest.Inventory
|
||||
{
|
||||
public class RestTestServices : IRest
|
||||
{
|
||||
private bool enabled = false;
|
||||
private string qPrefix = "test";
|
||||
|
||||
// A simple constructor is used to handle any once-only
|
||||
// initialization of working classes.
|
||||
|
||||
public RestTestServices()
|
||||
{
|
||||
Rest.Log.InfoFormat("{0} Test services initializing", MsgId);
|
||||
Rest.Log.InfoFormat("{0} Using REST Implementation Version {1}", MsgId, Rest.Version);
|
||||
|
||||
// If a relative path was specified, make it absolute by adding
|
||||
// the standard prefix, e.g. /admin
|
||||
|
||||
if (!qPrefix.StartsWith(Rest.UrlPathSeparator))
|
||||
{
|
||||
Rest.Log.InfoFormat("{0} Domain is relative, adding absolute prefix", MsgId);
|
||||
qPrefix = String.Format("{0}{1}{2}", Rest.Prefix, Rest.UrlPathSeparator, qPrefix);
|
||||
Rest.Log.InfoFormat("{0} Domain is now <{1}>", MsgId, qPrefix);
|
||||
}
|
||||
|
||||
// Load test cases
|
||||
|
||||
loadTests();
|
||||
foreach (ITest test in tests)
|
||||
{
|
||||
test.Initialize();
|
||||
}
|
||||
|
||||
// Register interface
|
||||
|
||||
Rest.Plugin.AddPathHandler(DoTests,qPrefix,Allocate);
|
||||
|
||||
// Activate
|
||||
|
||||
enabled = true;
|
||||
|
||||
Rest.Log.InfoFormat("{0} Test services initialization complete", MsgId);
|
||||
}
|
||||
|
||||
// Post-construction, pre-enabled initialization opportunity
|
||||
// Not currently exploited.
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
}
|
||||
|
||||
// Called by the plug-in to halt REST processing. Local processing is
|
||||
// disabled, and control blocks until all current processing has
|
||||
// completed. No new processing will be started
|
||||
|
||||
public void Close()
|
||||
{
|
||||
enabled = false;
|
||||
foreach (ITest test in tests)
|
||||
{
|
||||
test.Close();
|
||||
}
|
||||
Rest.Log.InfoFormat("{0} Test services closing down", MsgId);
|
||||
}
|
||||
|
||||
// Properties
|
||||
|
||||
internal string MsgId
|
||||
{
|
||||
get { return Rest.MsgId; }
|
||||
}
|
||||
|
||||
#region Interface
|
||||
|
||||
private RequestData Allocate(OSHttpRequest request, OSHttpResponse response, string prefix)
|
||||
{
|
||||
return new RequestData(request, response, prefix);
|
||||
}
|
||||
|
||||
// Inventory Handler
|
||||
|
||||
private void DoTests(RequestData rdata)
|
||||
{
|
||||
if (!enabled)
|
||||
return;
|
||||
|
||||
// Now that we know this is a serious attempt to
|
||||
// access inventory data, we should find out who
|
||||
// is asking, and make sure they are authorized
|
||||
// to do so. We need to validate the caller's
|
||||
// identity before revealing anything about the
|
||||
// status quo. Authenticate throws an exception
|
||||
// via Fail if no identity information is present.
|
||||
//
|
||||
// With the present HTTP server we can't use the
|
||||
// builtin authentication mechanisms because they
|
||||
// would be enforced for all in-bound requests.
|
||||
// Instead we look at the headers ourselves and
|
||||
// handle authentication directly.
|
||||
|
||||
try
|
||||
{
|
||||
if (!rdata.IsAuthenticated)
|
||||
{
|
||||
rdata.Fail(Rest.HttpStatusCodeNotAuthorized,
|
||||
String.Format("user \"{0}\" could not be authenticated", rdata.userName));
|
||||
}
|
||||
}
|
||||
catch (RestException e)
|
||||
{
|
||||
if (e.statusCode == Rest.HttpStatusCodeNotAuthorized)
|
||||
{
|
||||
Rest.Log.WarnFormat("{0} User not authenticated", MsgId);
|
||||
Rest.Log.DebugFormat("{0} Authorization header: {1}", MsgId, rdata.request.Headers.Get("Authorization"));
|
||||
}
|
||||
else
|
||||
{
|
||||
Rest.Log.ErrorFormat("{0} User authentication failed", MsgId);
|
||||
Rest.Log.DebugFormat("{0} Authorization header: {1}", MsgId, rdata.request.Headers.Get("Authorization"));
|
||||
}
|
||||
throw (e);
|
||||
}
|
||||
|
||||
// Check that a test was specified
|
||||
|
||||
if (rdata.Parameters.Length < 1)
|
||||
{
|
||||
Rest.Log.DebugFormat("{0} Insufficient parameters", MsgId);
|
||||
rdata.Fail(Rest.HttpStatusCodeBadRequest, "not enough parameters");
|
||||
}
|
||||
|
||||
// Select the test
|
||||
|
||||
foreach (ITest test in tests)
|
||||
{
|
||||
if (!rdata.handled)
|
||||
test.Execute(rdata);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Interface
|
||||
|
||||
private static bool testsLoaded = false;
|
||||
private static List<Type> classes = new List<Type>();
|
||||
private static List<ITest> tests = new List<ITest>();
|
||||
private static Type[] parms = new Type[0];
|
||||
private static Object[] args = new Object[0];
|
||||
|
||||
static RestTestServices()
|
||||
{
|
||||
Module[] mods = Assembly.GetExecutingAssembly().GetModules();
|
||||
foreach (Module m in mods)
|
||||
{
|
||||
Type[] types = m.GetTypes();
|
||||
foreach (Type t in types)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (t.GetInterface("ITest") != null)
|
||||
{
|
||||
classes.Add(t);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Rest.Log.WarnFormat("[STATIC-TEST] Unable to include test {0} : {1}", t, e.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This routine loads all of the handlers discovered during
|
||||
/// instance initialization. Each handler is responsible for
|
||||
/// registering itself with this handler.
|
||||
/// I was not able to make this code work in a constructor.
|
||||
/// </summary>
|
||||
|
||||
private void loadTests()
|
||||
{
|
||||
lock (tests)
|
||||
{
|
||||
if (!testsLoaded)
|
||||
{
|
||||
|
||||
ConstructorInfo ci;
|
||||
Object ht;
|
||||
|
||||
foreach (Type t in classes)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (t.GetInterface("ITest") != null)
|
||||
{
|
||||
ci = t.GetConstructor(parms);
|
||||
ht = ci.Invoke(args);
|
||||
tests.Add((ITest)ht);
|
||||
Rest.Log.InfoFormat("{0} Test {1} added", MsgId, t);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Rest.Log.WarnFormat("{0} Unable to load test {1} : {2}", MsgId, t, e.Message);
|
||||
}
|
||||
}
|
||||
testsLoaded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
46
OpenSim/ApplicationPlugins/Rest/Inventory/tests/ITest.cs
Normal file
46
OpenSim/ApplicationPlugins/Rest/Inventory/tests/ITest.cs
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OpenSim.ApplicationPlugins.Rest.Inventory
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// This interface represents the boundary between the general purpose
|
||||
/// REST plugin handling, and the functionally specific handlers. The
|
||||
/// handler knows only to initialzie and terminate all such handlers
|
||||
/// that it finds.
|
||||
/// </summary>
|
||||
|
||||
internal interface ITest
|
||||
{
|
||||
void Initialize();
|
||||
void Execute(RequestData rdata);
|
||||
void Close();
|
||||
}
|
||||
|
||||
}
|
||||
204
OpenSim/ApplicationPlugins/Rest/Inventory/tests/Remote.cs
Normal file
204
OpenSim/ApplicationPlugins/Rest/Inventory/tests/Remote.cs
Normal file
@@ -0,0 +1,204 @@
|
||||
/*
|
||||
* 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.Region.Framework.Scenes;
|
||||
|
||||
namespace OpenSim.ApplicationPlugins.Rest.Inventory.Tests
|
||||
{
|
||||
public class Remote : ITest
|
||||
{
|
||||
private static readonly int PARM_TESTID = 0;
|
||||
private static readonly int PARM_COMMAND = 1;
|
||||
|
||||
private static readonly int PARM_MOVE_AVATAR = 2;
|
||||
private static readonly int PARM_MOVE_X = 3;
|
||||
private static readonly int PARM_MOVE_Y = 4;
|
||||
private static readonly int PARM_MOVE_Z = 5;
|
||||
|
||||
private bool enabled = false;
|
||||
|
||||
// No constructor code is required.
|
||||
|
||||
public Remote()
|
||||
{
|
||||
Rest.Log.InfoFormat("{0} Remote services constructor", MsgId);
|
||||
}
|
||||
|
||||
// Post-construction, pre-enabled initialization opportunity
|
||||
// Not currently exploited.
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
enabled = true;
|
||||
Rest.Log.InfoFormat("{0} Remote services initialized", MsgId);
|
||||
}
|
||||
|
||||
// Called by the plug-in to halt REST processing. Local processing is
|
||||
// disabled, and control blocks until all current processing has
|
||||
// completed. No new processing will be started
|
||||
|
||||
public void Close()
|
||||
{
|
||||
enabled = false;
|
||||
Rest.Log.InfoFormat("{0} Remote services closing down", MsgId);
|
||||
}
|
||||
|
||||
// Properties
|
||||
|
||||
internal string MsgId
|
||||
{
|
||||
get { return Rest.MsgId; }
|
||||
}
|
||||
|
||||
// Remote Handler
|
||||
// Key information of interest here is the Parameters array, each
|
||||
// entry represents an element of the URI, with element zero being
|
||||
// the
|
||||
|
||||
public void Execute(RequestData rdata)
|
||||
{
|
||||
if (!enabled) return;
|
||||
|
||||
// If we can't relate to what's there, leave it for others.
|
||||
|
||||
if (rdata.Parameters.Length == 0 || rdata.Parameters[PARM_TESTID] != "remote")
|
||||
return;
|
||||
|
||||
Rest.Log.DebugFormat("{0} REST Remote handler ENTRY", MsgId);
|
||||
|
||||
// Remove the prefix and what's left are the parameters. If we don't have
|
||||
// the parameters we need, fail the request. Parameters do NOT include
|
||||
// any supplied query values.
|
||||
|
||||
if (rdata.Parameters.Length > 1)
|
||||
{
|
||||
switch (rdata.Parameters[PARM_COMMAND].ToLower())
|
||||
{
|
||||
case "move" :
|
||||
DoMove(rdata);
|
||||
break;
|
||||
default :
|
||||
DoHelp(rdata);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DoHelp(rdata);
|
||||
}
|
||||
}
|
||||
|
||||
private void DoHelp(RequestData rdata)
|
||||
{
|
||||
rdata.body = Help;
|
||||
rdata.Complete();
|
||||
rdata.Respond("Help");
|
||||
}
|
||||
|
||||
private void DoMove(RequestData rdata)
|
||||
{
|
||||
if (rdata.Parameters.Length < 6)
|
||||
{
|
||||
Rest.Log.WarnFormat("{0} Move: No movement information provided", MsgId);
|
||||
rdata.Fail(Rest.HttpStatusCodeBadRequest, "no movement information provided");
|
||||
}
|
||||
else
|
||||
{
|
||||
string[] names = rdata.Parameters[PARM_MOVE_AVATAR].Split(Rest.CA_SPACE);
|
||||
ScenePresence presence = null;
|
||||
Scene scene = null;
|
||||
|
||||
if (names.Length != 2)
|
||||
{
|
||||
rdata.Fail(Rest.HttpStatusCodeBadRequest,
|
||||
String.Format("invalid avatar name: <{0}>",rdata.Parameters[PARM_MOVE_AVATAR]));
|
||||
}
|
||||
|
||||
Rest.Log.WarnFormat("{0} '{1}' command received for {2} {3}",
|
||||
MsgId, rdata.Parameters[0], names[0], names[1]);
|
||||
|
||||
// The first parameter should be an avatar name, look for the
|
||||
// avatar in the known regions first.
|
||||
|
||||
Rest.main.SceneManager.ForEachScene(delegate(Scene s)
|
||||
{
|
||||
s.ForEachRootScenePresence(delegate(ScenePresence sp)
|
||||
{
|
||||
if (sp.Firstname == names[0] && sp.Lastname == names[1])
|
||||
{
|
||||
scene = s;
|
||||
presence = sp;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
if (presence != null)
|
||||
{
|
||||
Rest.Log.DebugFormat("{0} Move : Avatar {1} located in region {2}",
|
||||
MsgId, rdata.Parameters[PARM_MOVE_AVATAR], scene.RegionInfo.RegionName);
|
||||
|
||||
try
|
||||
{
|
||||
float x = Convert.ToSingle(rdata.Parameters[PARM_MOVE_X]);
|
||||
float y = Convert.ToSingle(rdata.Parameters[PARM_MOVE_Y]);
|
||||
float z = Convert.ToSingle(rdata.Parameters[PARM_MOVE_Z]);
|
||||
Vector3 vector = new Vector3(x, y, z);
|
||||
presence.MoveToTarget(vector, false, false);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
rdata.Fail(Rest.HttpStatusCodeBadRequest,
|
||||
String.Format("invalid parameters: {0}", e.Message));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rdata.Fail(Rest.HttpStatusCodeBadRequest,
|
||||
String.Format("avatar {0} not present", rdata.Parameters[PARM_MOVE_AVATAR]));
|
||||
}
|
||||
|
||||
rdata.Complete();
|
||||
rdata.Respond("OK");
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly string Help =
|
||||
"<html>"
|
||||
+ "<head><title>Remote Command Usage</title></head>"
|
||||
+ "<body>"
|
||||
+ "<p>Supported commands are:</p>"
|
||||
+ "<dl>"
|
||||
+ "<dt>move/avatar-name/x/y/z</dt>"
|
||||
+ "<dd>moves the specified avatar to another location</dd>"
|
||||
+ "</dl>"
|
||||
+ "</body>"
|
||||
+ "</html>"
|
||||
;
|
||||
}
|
||||
}
|
||||
228
OpenSim/ApplicationPlugins/Rest/Regions/GETHandler.cs
Normal file
228
OpenSim/ApplicationPlugins/Rest/Regions/GETHandler.cs
Normal file
@@ -0,0 +1,228 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Xml.Serialization;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Servers;
|
||||
using OpenSim.Framework.Servers.HttpServer;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
|
||||
namespace OpenSim.ApplicationPlugins.Rest.Regions
|
||||
{
|
||||
public partial class RestRegionPlugin : RestPlugin
|
||||
{
|
||||
#region GET methods
|
||||
public string GetHandler(string request, string path, string param,
|
||||
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
||||
{
|
||||
// foreach (string h in httpRequest.Headers.AllKeys)
|
||||
// foreach (string v in httpRequest.Headers.GetValues(h))
|
||||
// m_log.DebugFormat("{0} IsGod: {1} -> {2}", MsgID, h, v);
|
||||
|
||||
MsgID = RequestID;
|
||||
m_log.DebugFormat("{0} GET path {1} param {2}", MsgID, path, param);
|
||||
|
||||
try
|
||||
{
|
||||
// param empty: regions list
|
||||
if (String.IsNullOrEmpty(param)) return GetHandlerRegions(httpResponse);
|
||||
|
||||
// param not empty: specific region
|
||||
return GetHandlerRegion(httpResponse, param);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return Failure(httpResponse, OSHttpStatusCode.ServerErrorInternalError, "GET", e);
|
||||
}
|
||||
}
|
||||
|
||||
public string GetHandlerRegions(IOSHttpResponse httpResponse)
|
||||
{
|
||||
RestXmlWriter rxw = new RestXmlWriter(new StringWriter());
|
||||
|
||||
rxw.WriteStartElement(String.Empty, "regions", String.Empty);
|
||||
foreach (Scene s in App.SceneManager.Scenes)
|
||||
{
|
||||
rxw.WriteStartElement(String.Empty, "uuid", String.Empty);
|
||||
rxw.WriteString(s.RegionInfo.RegionID.ToString());
|
||||
rxw.WriteEndElement();
|
||||
}
|
||||
rxw.WriteEndElement();
|
||||
|
||||
return rxw.ToString();
|
||||
}
|
||||
|
||||
protected string ShortRegionInfo(string key, string value)
|
||||
{
|
||||
RestXmlWriter rxw = new RestXmlWriter(new StringWriter());
|
||||
|
||||
if (String.IsNullOrEmpty(value) ||
|
||||
String.IsNullOrEmpty(key)) return null;
|
||||
|
||||
rxw.WriteStartElement(String.Empty, "region", String.Empty);
|
||||
rxw.WriteStartElement(String.Empty, key, String.Empty);
|
||||
rxw.WriteString(value);
|
||||
rxw.WriteEndDocument();
|
||||
|
||||
return rxw.ToString();
|
||||
}
|
||||
|
||||
public string GetHandlerRegion(IOSHttpResponse httpResponse, string param)
|
||||
{
|
||||
// be resilient and don't get confused by a terminating '/'
|
||||
param = param.TrimEnd(new char[]{'/'});
|
||||
string[] comps = param.Split('/');
|
||||
UUID regionID = (UUID)comps[0];
|
||||
|
||||
m_log.DebugFormat("{0} GET region UUID {1}", MsgID, regionID.ToString());
|
||||
|
||||
if (UUID.Zero == regionID) throw new Exception("missing region ID");
|
||||
|
||||
Scene scene = null;
|
||||
App.SceneManager.TryGetScene(regionID, out scene);
|
||||
if (null == scene) return Failure(httpResponse, OSHttpStatusCode.ClientErrorNotFound,
|
||||
"GET", "cannot find region {0}", regionID.ToString());
|
||||
|
||||
RegionDetails details = new RegionDetails(scene.RegionInfo);
|
||||
|
||||
// m_log.DebugFormat("{0} GET comps {1}", MsgID, comps.Length);
|
||||
// for (int i = 0; i < comps.Length; i++) m_log.DebugFormat("{0} GET comps[{1}] >{2}<", MsgID, i, comps[i]);
|
||||
|
||||
if (1 == comps.Length)
|
||||
{
|
||||
// complete region details requested
|
||||
RestXmlWriter rxw = new RestXmlWriter(new StringWriter());
|
||||
XmlSerializer xs = new XmlSerializer(typeof(RegionDetails));
|
||||
xs.Serialize(rxw, details, _xmlNs);
|
||||
return rxw.ToString();
|
||||
}
|
||||
|
||||
if (2 == comps.Length)
|
||||
{
|
||||
string resp = ShortRegionInfo(comps[1], details[comps[1]]);
|
||||
if (null != resp) return resp;
|
||||
|
||||
// m_log.DebugFormat("{0} GET comps advanced: >{1}<", MsgID, comps[1]);
|
||||
|
||||
// check for {terrain,stats,prims}
|
||||
switch (comps[1].ToLower())
|
||||
{
|
||||
case "terrain":
|
||||
return RegionTerrain(httpResponse, scene);
|
||||
|
||||
case "stats":
|
||||
return RegionStats(httpResponse, scene);
|
||||
|
||||
case "prims":
|
||||
return RegionPrims(httpResponse, scene, Vector3.Zero, Vector3.Zero);
|
||||
}
|
||||
}
|
||||
|
||||
if (3 == comps.Length)
|
||||
{
|
||||
switch (comps[1].ToLower())
|
||||
{
|
||||
case "prims":
|
||||
string[] subregion = comps[2].Split(',');
|
||||
if (subregion.Length == 6)
|
||||
{
|
||||
Vector3 min, max;
|
||||
try
|
||||
{
|
||||
min = new Vector3((float)Double.Parse(subregion[0], Culture.NumberFormatInfo), (float)Double.Parse(subregion[1], Culture.NumberFormatInfo), (float)Double.Parse(subregion[2], Culture.NumberFormatInfo));
|
||||
max = new Vector3((float)Double.Parse(subregion[3], Culture.NumberFormatInfo), (float)Double.Parse(subregion[4], Culture.NumberFormatInfo), (float)Double.Parse(subregion[5], Culture.NumberFormatInfo));
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return Failure(httpResponse, OSHttpStatusCode.ClientErrorBadRequest,
|
||||
"GET", "invalid subregion parameter");
|
||||
}
|
||||
return RegionPrims(httpResponse, scene, min, max);
|
||||
}
|
||||
else
|
||||
{
|
||||
return Failure(httpResponse, OSHttpStatusCode.ClientErrorBadRequest,
|
||||
"GET", "invalid subregion parameter");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Failure(httpResponse, OSHttpStatusCode.ClientErrorBadRequest,
|
||||
"GET", "too many parameters {0}", param);
|
||||
}
|
||||
#endregion GET methods
|
||||
|
||||
protected string RegionTerrain(IOSHttpResponse httpResponse, Scene scene)
|
||||
{
|
||||
httpResponse.SendChunked = true;
|
||||
httpResponse.ContentType = "text/xml";
|
||||
|
||||
return scene.Heightmap.SaveToXmlString();
|
||||
//return Failure(httpResponse, OSHttpStatusCode.ServerErrorNotImplemented,
|
||||
// "GET", "terrain not implemented");
|
||||
}
|
||||
|
||||
protected string RegionStats(IOSHttpResponse httpResponse, Scene scene)
|
||||
{
|
||||
int users = scene.GetRootAgentCount();
|
||||
int objects = scene.Entities.Count - users;
|
||||
|
||||
RestXmlWriter rxw = new RestXmlWriter(new StringWriter());
|
||||
|
||||
rxw.WriteStartElement(String.Empty, "region", String.Empty);
|
||||
rxw.WriteStartElement(String.Empty, "stats", String.Empty);
|
||||
|
||||
rxw.WriteStartElement(String.Empty, "users", String.Empty);
|
||||
rxw.WriteString(users.ToString());
|
||||
rxw.WriteEndElement();
|
||||
|
||||
rxw.WriteStartElement(String.Empty, "objects", String.Empty);
|
||||
rxw.WriteString(objects.ToString());
|
||||
rxw.WriteEndElement();
|
||||
|
||||
rxw.WriteEndDocument();
|
||||
|
||||
return rxw.ToString();
|
||||
}
|
||||
|
||||
protected string RegionPrims(IOSHttpResponse httpResponse, Scene scene, Vector3 min, Vector3 max)
|
||||
{
|
||||
httpResponse.SendChunked = true;
|
||||
httpResponse.ContentType = "text/xml";
|
||||
|
||||
IRegionSerialiserModule serialiser = scene.RequestModuleInterface<IRegionSerialiserModule>();
|
||||
if (serialiser != null)
|
||||
serialiser.SavePrimsToXml2(scene, new StreamWriter(httpResponse.OutputStream), min, max);
|
||||
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
136
OpenSim/ApplicationPlugins/Rest/Regions/GETRegionInfoHandler.cs
Normal file
136
OpenSim/ApplicationPlugins/Rest/Regions/GETRegionInfoHandler.cs
Normal file
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Xml.Serialization;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework.Servers;
|
||||
using OpenSim.Framework.Servers.HttpServer;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
|
||||
namespace OpenSim.ApplicationPlugins.Rest.Regions
|
||||
{
|
||||
public partial class RestRegionPlugin : RestPlugin
|
||||
{
|
||||
#region GET methods
|
||||
public string GetRegionInfoHandler(string request, string path, string param,
|
||||
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
||||
{
|
||||
// foreach (string h in httpRequest.Headers.AllKeys)
|
||||
// foreach (string v in httpRequest.Headers.GetValues(h))
|
||||
// m_log.DebugFormat("{0} IsGod: {1} -> {2}", MsgID, h, v);
|
||||
|
||||
MsgID = RequestID;
|
||||
m_log.DebugFormat("{0} GET path {1} param {2}", MsgID, path, param);
|
||||
|
||||
try
|
||||
{
|
||||
// param empty: regions list
|
||||
// if (String.IsNullOrEmpty(param))
|
||||
return GetRegionInfoHandlerRegions(httpResponse);
|
||||
|
||||
// // param not empty: specific region
|
||||
// return GetRegionInfoHandlerRegion(httpResponse, param);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return Failure(httpResponse, OSHttpStatusCode.ServerErrorInternalError, "GET", e);
|
||||
}
|
||||
}
|
||||
|
||||
public string GetRegionInfoHandlerRegions(IOSHttpResponse httpResponse)
|
||||
{
|
||||
RestXmlWriter rxw = new RestXmlWriter(new StringWriter());
|
||||
|
||||
// regions info
|
||||
rxw.WriteStartElement(String.Empty, "regions", String.Empty);
|
||||
{
|
||||
// regions info: number of regions
|
||||
rxw.WriteStartAttribute(String.Empty, "number", String.Empty);
|
||||
rxw.WriteValue(App.SceneManager.Scenes.Count);
|
||||
rxw.WriteEndAttribute();
|
||||
|
||||
// regions info: max number of regions
|
||||
rxw.WriteStartAttribute(String.Empty, "max", String.Empty);
|
||||
if (App.ConfigSource.Source.Configs["RemoteAdmin"] != null)
|
||||
{
|
||||
rxw.WriteValue(App.ConfigSource.Source.Configs["RemoteAdmin"].GetInt("region_limit", -1));
|
||||
}
|
||||
else
|
||||
{
|
||||
rxw.WriteValue(-1);
|
||||
}
|
||||
rxw.WriteEndAttribute();
|
||||
|
||||
// regions info: region
|
||||
foreach (Scene s in App.SceneManager.Scenes)
|
||||
{
|
||||
rxw.WriteStartElement(String.Empty, "region", String.Empty);
|
||||
|
||||
rxw.WriteStartAttribute(String.Empty, "uuid", String.Empty);
|
||||
rxw.WriteString(s.RegionInfo.RegionID.ToString());
|
||||
rxw.WriteEndAttribute();
|
||||
|
||||
rxw.WriteStartAttribute(String.Empty, "name", String.Empty);
|
||||
rxw.WriteString(s.RegionInfo.RegionName);
|
||||
rxw.WriteEndAttribute();
|
||||
|
||||
rxw.WriteStartAttribute(String.Empty, "x", String.Empty);
|
||||
rxw.WriteValue(s.RegionInfo.RegionLocX);
|
||||
rxw.WriteEndAttribute();
|
||||
|
||||
rxw.WriteStartAttribute(String.Empty, "y", String.Empty);
|
||||
rxw.WriteValue(s.RegionInfo.RegionLocY);
|
||||
rxw.WriteEndAttribute();
|
||||
|
||||
rxw.WriteStartAttribute(String.Empty, "external_hostname", String.Empty);
|
||||
rxw.WriteString(s.RegionInfo.ExternalHostName);
|
||||
rxw.WriteEndAttribute();
|
||||
|
||||
rxw.WriteStartAttribute(String.Empty, "ip", String.Empty);
|
||||
rxw.WriteString(s.RegionInfo.InternalEndPoint.ToString());
|
||||
rxw.WriteEndAttribute();
|
||||
|
||||
int users = s.GetRootAgentCount();
|
||||
rxw.WriteStartAttribute(String.Empty, "avatars", String.Empty);
|
||||
rxw.WriteValue(users);
|
||||
rxw.WriteEndAttribute();
|
||||
|
||||
rxw.WriteStartAttribute(String.Empty, "objects", String.Empty);
|
||||
rxw.WriteValue(s.Entities.Count - users);
|
||||
rxw.WriteEndAttribute();
|
||||
|
||||
rxw.WriteEndElement();
|
||||
}
|
||||
}
|
||||
return rxw.ToString();
|
||||
}
|
||||
#endregion GET methods
|
||||
}
|
||||
}
|
||||
122
OpenSim/ApplicationPlugins/Rest/Regions/POSTHandler.cs
Normal file
122
OpenSim/ApplicationPlugins/Rest/Regions/POSTHandler.cs
Normal file
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework.Servers;
|
||||
using OpenSim.Framework.Servers.HttpServer;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
|
||||
namespace OpenSim.ApplicationPlugins.Rest.Regions
|
||||
{
|
||||
public partial class RestRegionPlugin : RestPlugin
|
||||
{
|
||||
#region POST methods
|
||||
|
||||
public string PostHandler(string request, string path, string param,
|
||||
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
||||
{
|
||||
// foreach (string h in httpRequest.Headers.AllKeys)
|
||||
// foreach (string v in httpRequest.Headers.GetValues(h))
|
||||
// m_log.DebugFormat("{0} IsGod: {1} -> {2}", MsgID, h, v);
|
||||
|
||||
MsgID = RequestID;
|
||||
m_log.DebugFormat("{0} POST path {1} param {2}", MsgID, path, param);
|
||||
|
||||
try
|
||||
{
|
||||
// param empty: new region post
|
||||
if (!IsGod(httpRequest))
|
||||
// XXX: this needs to be turned into a FailureUnauthorized(...)
|
||||
return Failure(httpResponse, OSHttpStatusCode.ClientErrorUnauthorized,
|
||||
"GET", "you are not god");
|
||||
|
||||
if (String.IsNullOrEmpty(param)) return CreateRegion(httpRequest, httpResponse);
|
||||
|
||||
// Parse region ID and other parameters
|
||||
param = param.TrimEnd(new char[] {'/'});
|
||||
string[] comps = param.Split('/');
|
||||
UUID regionID = (UUID) comps[0];
|
||||
|
||||
m_log.DebugFormat("{0} POST region UUID {1}", MsgID, regionID.ToString());
|
||||
if (UUID.Zero == regionID) throw new Exception("missing region ID");
|
||||
|
||||
Scene scene = null;
|
||||
App.SceneManager.TryGetScene(regionID, out scene);
|
||||
if (null == scene)
|
||||
return Failure(httpResponse, OSHttpStatusCode.ClientErrorNotFound,
|
||||
"POST", "cannot find region {0}", regionID.ToString());
|
||||
|
||||
if (2 == comps.Length)
|
||||
{
|
||||
// check for {prims}
|
||||
switch (comps[1].ToLower())
|
||||
{
|
||||
case "prims":
|
||||
return LoadPrims(request, httpRequest, httpResponse, scene);
|
||||
}
|
||||
}
|
||||
|
||||
return Failure(httpResponse, OSHttpStatusCode.ClientErrorNotFound,
|
||||
"POST", "url {0} not supported", param);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return Failure(httpResponse, OSHttpStatusCode.ServerErrorInternalError, "POST", e);
|
||||
}
|
||||
}
|
||||
|
||||
public string CreateRegion(IOSHttpRequest request, IOSHttpResponse response)
|
||||
{
|
||||
RestXmlWriter rxw = new RestXmlWriter(new StringWriter());
|
||||
|
||||
rxw.WriteStartElement(String.Empty, "regions", String.Empty);
|
||||
foreach (Scene s in App.SceneManager.Scenes)
|
||||
{
|
||||
rxw.WriteStartElement(String.Empty, "uuid", String.Empty);
|
||||
rxw.WriteString(s.RegionInfo.RegionID.ToString());
|
||||
rxw.WriteEndElement();
|
||||
}
|
||||
rxw.WriteEndElement();
|
||||
|
||||
return rxw.ToString();
|
||||
}
|
||||
|
||||
public string LoadPrims(string requestBody, IOSHttpRequest request, IOSHttpResponse response, Scene scene)
|
||||
{
|
||||
IRegionSerialiserModule serialiser = scene.RequestModuleInterface<IRegionSerialiserModule>();
|
||||
if (serialiser != null)
|
||||
serialiser.LoadPrimsFromXml2(scene, new StringReader(requestBody), true);
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
#endregion POST methods
|
||||
}
|
||||
}
|
||||
98
OpenSim/ApplicationPlugins/Rest/Regions/RegionDetails.cs
Normal file
98
OpenSim/ApplicationPlugins/Rest/Regions/RegionDetails.cs
Normal file
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* 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.Xml.Serialization;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
|
||||
namespace OpenSim.ApplicationPlugins.Rest.Regions
|
||||
{
|
||||
[XmlRoot(ElementName="region", IsNullable = false)]
|
||||
public class RegionDetails
|
||||
{
|
||||
public string region_name;
|
||||
public string region_id;
|
||||
public uint region_x;
|
||||
public uint region_y;
|
||||
public string region_owner;
|
||||
public string region_owner_id;
|
||||
public uint region_http_port;
|
||||
public uint region_port;
|
||||
public string region_server_uri;
|
||||
public string region_external_hostname;
|
||||
|
||||
public RegionDetails()
|
||||
{
|
||||
}
|
||||
|
||||
public RegionDetails(RegionInfo regInfo)
|
||||
{
|
||||
region_name = regInfo.RegionName;
|
||||
region_id = regInfo.RegionID.ToString();
|
||||
region_x = regInfo.RegionLocX;
|
||||
region_y = regInfo.RegionLocY;
|
||||
region_owner_id = regInfo.EstateSettings.EstateOwner.ToString();
|
||||
region_http_port = regInfo.HttpPort;
|
||||
region_server_uri = regInfo.ServerURI;
|
||||
region_external_hostname = regInfo.ExternalHostName;
|
||||
|
||||
Uri uri = new Uri(region_server_uri);
|
||||
region_port = (uint)uri.Port;
|
||||
}
|
||||
|
||||
public string this[string idx]
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (idx.ToLower())
|
||||
{
|
||||
case "name":
|
||||
return region_name;
|
||||
case "id":
|
||||
return region_id;
|
||||
case "location":
|
||||
return String.Format("<x>{0}</x><y>{1}</y>", region_x, region_y);
|
||||
case "owner":
|
||||
return region_owner;
|
||||
case "owner_id":
|
||||
return region_owner_id;
|
||||
case "http_port":
|
||||
return region_http_port.ToString();
|
||||
case "server_uri":
|
||||
return region_server_uri;
|
||||
case "external_hostname":
|
||||
case "hostname":
|
||||
return region_external_hostname;
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<Addin id="OpenSim.ApplicationPlugins.Rest.Regions" version="0.1">
|
||||
<Runtime>
|
||||
<Import assembly="OpenSim.ApplicationPlugins.Rest.Regions.dll"/>
|
||||
</Runtime>
|
||||
<Dependencies>
|
||||
<Addin id="OpenSim" version="0.5" />
|
||||
</Dependencies>
|
||||
<Extension path = "/OpenSim/Startup">
|
||||
<Plugin id="RestRegions" type="OpenSim.ApplicationPlugins.Rest.Regions.RestRegionPlugin" />
|
||||
</Extension>
|
||||
</Addin>
|
||||
@@ -26,73 +26,69 @@
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
using System.Xml.Schema;
|
||||
using System.Xml.Serialization;
|
||||
using OpenMetaverse;
|
||||
using OpenMetaverse.StructuredData;
|
||||
|
||||
namespace OpenSim.Framework
|
||||
namespace OpenSim.ApplicationPlugins.Rest.Regions
|
||||
{
|
||||
/// <summary>
|
||||
/// This class stores and retrieves dynamic objects.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Experimental - DO NOT USE. Does not yet have namespace support.
|
||||
/// </remarks>
|
||||
public class DOMap
|
||||
public partial class RestRegionPlugin : RestPlugin
|
||||
{
|
||||
private IDictionary<string, object> m_map;
|
||||
|
||||
public void Add(string ns, string objName, object dynObj)
|
||||
private static XmlSerializerNamespaces _xmlNs;
|
||||
|
||||
static RestRegionPlugin()
|
||||
{
|
||||
DAMap.ValidateNamespace(ns);
|
||||
|
||||
lock (this)
|
||||
{
|
||||
if (m_map == null)
|
||||
m_map = new Dictionary<string, object>();
|
||||
|
||||
m_map.Add(objName, dynObj);
|
||||
}
|
||||
_xmlNs = new XmlSerializerNamespaces();
|
||||
_xmlNs.Add(String.Empty, String.Empty);
|
||||
}
|
||||
|
||||
public bool ContainsKey(string key)
|
||||
#region overriding properties
|
||||
public override string Name
|
||||
{
|
||||
return Get(key) != null;
|
||||
get { return "REGION"; }
|
||||
}
|
||||
|
||||
public override string ConfigName
|
||||
{
|
||||
get { return "RestRegionPlugin"; }
|
||||
}
|
||||
#endregion overriding properties
|
||||
|
||||
#region overriding methods
|
||||
/// <summary>
|
||||
/// Get a dynamic object
|
||||
/// This method is called by OpenSimMain immediately after loading the
|
||||
/// plugin and after basic server setup, but before running any server commands.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Not providing an index method so that users can't casually overwrite each other's objects.
|
||||
/// Note that entries MUST be added to the active configuration files before
|
||||
/// the plugin can be enabled.
|
||||
/// </remarks>
|
||||
/// <param name='key'></param>
|
||||
public object Get(string key)
|
||||
public override void Initialise(OpenSimBase openSim)
|
||||
{
|
||||
lock (this)
|
||||
try
|
||||
{
|
||||
if (m_map == null)
|
||||
return null;
|
||||
else
|
||||
return m_map[key];
|
||||
base.Initialise(openSim);
|
||||
if (!IsEnabled)
|
||||
{
|
||||
//m_log.WarnFormat("{0} Rest Plugins are disabled", MsgID);
|
||||
return;
|
||||
}
|
||||
|
||||
m_log.InfoFormat("{0} REST region plugin enabled", MsgID);
|
||||
|
||||
// add REST method handlers
|
||||
AddRestStreamHandler("GET", "/regions/", GetHandler);
|
||||
AddRestStreamHandler("POST", "/regions/", PostHandler);
|
||||
AddRestStreamHandler("GET", "/regioninfo/", GetRegionInfoHandler);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.WarnFormat("{0} Initialization failed: {1}", MsgID, e.Message);
|
||||
m_log.DebugFormat("{0} Initialization failed: {1}", MsgID, e.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public bool Remove(string key)
|
||||
public override void Close()
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
if (m_map == null)
|
||||
return false;
|
||||
else
|
||||
return m_map.Remove(key);
|
||||
}
|
||||
}
|
||||
#endregion overriding methods
|
||||
}
|
||||
}
|
||||
}
|
||||
415
OpenSim/ApplicationPlugins/Rest/RestPlugin.cs
Normal file
415
OpenSim/ApplicationPlugins/Rest/RestPlugin.cs
Normal file
@@ -0,0 +1,415 @@
|
||||
/*
|
||||
* 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.IO;
|
||||
using System.Reflection;
|
||||
using System.Xml;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Servers;
|
||||
using OpenSim.Framework.Servers.HttpServer;
|
||||
|
||||
namespace OpenSim.ApplicationPlugins.Rest
|
||||
{
|
||||
public abstract class RestPlugin : IApplicationPlugin
|
||||
{
|
||||
#region properties
|
||||
|
||||
protected static readonly ILog m_log =
|
||||
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private IConfig _config; // Configuration source: Rest Plugins
|
||||
private IConfig _pluginConfig; // Configuration source: Plugin specific
|
||||
private OpenSimBase _app; // The 'server'
|
||||
private BaseHttpServer _httpd; // The server's RPC interface
|
||||
private string _prefix; // URL prefix below
|
||||
// which all REST URLs
|
||||
// are living
|
||||
// private StringWriter _sw = null;
|
||||
// private RestXmlWriter _xw = null;
|
||||
|
||||
private string _godkey;
|
||||
private int _reqk;
|
||||
|
||||
[ThreadStatic]
|
||||
private static string _threadRequestID = String.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Return an ever increasing request ID for logging
|
||||
/// </summary>
|
||||
protected string RequestID
|
||||
{
|
||||
get { return _reqk++.ToString(); }
|
||||
set { _reqk = Convert.ToInt32(value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Thread-constant message IDs for logging.
|
||||
/// </summary>
|
||||
protected string MsgID
|
||||
{
|
||||
get { return String.Format("[REST-{0}] #{1}", Name, _threadRequestID); }
|
||||
set { _threadRequestID = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if Rest Plugins are enabled.
|
||||
/// </summary>
|
||||
public bool PluginsAreEnabled
|
||||
{
|
||||
get { return null != _config; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if specific Rest Plugin is enabled.
|
||||
/// </summary>
|
||||
public bool IsEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
return (null != _pluginConfig) && _pluginConfig.GetBoolean("enabled", false);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// OpenSimMain application
|
||||
/// </summary>
|
||||
public OpenSimBase App
|
||||
{
|
||||
get { return _app; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// RPC server
|
||||
/// </summary>
|
||||
public BaseHttpServer HttpServer
|
||||
{
|
||||
get { return _httpd; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// URL prefix to use for all REST handlers
|
||||
/// </summary>
|
||||
public string Prefix
|
||||
{
|
||||
get { return _prefix; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Access to GOD password string
|
||||
/// </summary>
|
||||
protected string GodKey
|
||||
{
|
||||
get { return _godkey; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configuration of the plugin
|
||||
/// </summary>
|
||||
public IConfig Config
|
||||
{
|
||||
get { return _pluginConfig; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Name of the plugin
|
||||
/// </summary>
|
||||
public abstract string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Return the config section name
|
||||
/// </summary>
|
||||
public abstract string ConfigName { get; }
|
||||
|
||||
// public XmlTextWriter XmlWriter
|
||||
// {
|
||||
// get
|
||||
// {
|
||||
// if (null == _xw)
|
||||
// {
|
||||
// _sw = new StringWriter();
|
||||
// _xw = new RestXmlWriter(_sw);
|
||||
// _xw.Formatting = Formatting.Indented;
|
||||
// }
|
||||
// return _xw;
|
||||
// }
|
||||
// }
|
||||
|
||||
// public string XmlWriterResult
|
||||
// {
|
||||
// get
|
||||
// {
|
||||
// _xw.Flush();
|
||||
// _xw.Close();
|
||||
// _xw = null;
|
||||
|
||||
// return _sw.ToString();
|
||||
// }
|
||||
// }
|
||||
|
||||
#endregion properties
|
||||
|
||||
#region methods
|
||||
|
||||
// TODO: required by IPlugin, but likely not at all right
|
||||
private string m_version = "0.0";
|
||||
|
||||
public string Version
|
||||
{
|
||||
get { return m_version; }
|
||||
}
|
||||
|
||||
public void Initialise()
|
||||
{
|
||||
m_log.Info("[RESTPLUGIN]: " + Name + " cannot be default-initialized!");
|
||||
throw new PluginNotInitialisedException(Name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method is called by OpenSimMain immediately after loading the
|
||||
/// plugin and after basic server setup, but before running any server commands.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Note that entries MUST be added to the active configuration files before
|
||||
/// the plugin can be enabled.
|
||||
/// </remarks>
|
||||
public virtual void Initialise(OpenSimBase openSim)
|
||||
{
|
||||
RequestID = "0";
|
||||
MsgID = RequestID;
|
||||
|
||||
try
|
||||
{
|
||||
if ((_config = openSim.ConfigSource.Source.Configs["RestPlugins"]) == null)
|
||||
{
|
||||
m_log.WarnFormat("{0} Rest Plugins not configured", MsgID);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_config.GetBoolean("enabled", false))
|
||||
{
|
||||
//m_log.WarnFormat("{0} Rest Plugins are disabled", MsgID);
|
||||
return;
|
||||
}
|
||||
|
||||
_app = openSim;
|
||||
_httpd = openSim.HttpServer;
|
||||
|
||||
// Retrieve GOD key value, if any.
|
||||
_godkey = _config.GetString("god_key", String.Empty);
|
||||
|
||||
// Retrive prefix if any.
|
||||
_prefix = _config.GetString("prefix", "/admin");
|
||||
|
||||
// Get plugin specific config
|
||||
_pluginConfig = openSim.ConfigSource.Source.Configs[ConfigName];
|
||||
|
||||
m_log.InfoFormat("{0} Rest Plugins Enabled", MsgID);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// we can safely ignore this, as it just means that
|
||||
// the key lookup in Configs failed, which signals to
|
||||
// us that noone is interested in our services...they
|
||||
// don't know what they are missing out on...
|
||||
// NOTE: Under the present OpenSimulator implementation it is
|
||||
// not possible for the openSimulator pointer to be null. However
|
||||
// were the implementation to be changed, this could
|
||||
// result in a silent initialization failure. Harmless
|
||||
// except for lack of function and lack of any
|
||||
// diagnostic indication as to why. The same is true if
|
||||
// the HTTP server reference is bad.
|
||||
// We should at least issue a message...
|
||||
m_log.WarnFormat("{0} Initialization failed: {1}", MsgID, e.Message);
|
||||
m_log.DebugFormat("{0} Initialization failed: {1}", MsgID, e.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void PostInitialise()
|
||||
{
|
||||
}
|
||||
|
||||
private List<RestStreamHandler> _handlers = new List<RestStreamHandler>();
|
||||
private Dictionary<string, IHttpAgentHandler> _agents = new Dictionary<string, IHttpAgentHandler>();
|
||||
|
||||
/// <summary>
|
||||
/// Add a REST stream handler to the underlying HTTP server.
|
||||
/// </summary>
|
||||
/// <param name="httpMethod">GET/PUT/POST/DELETE or
|
||||
/// similar</param>
|
||||
/// <param name="path">URL prefix</param>
|
||||
/// <param name="method">RestMethod handler doing the actual work</param>
|
||||
public virtual void AddRestStreamHandler(string httpMethod, string path, RestMethod method)
|
||||
{
|
||||
if (!IsEnabled) return;
|
||||
|
||||
if (!path.StartsWith(_prefix))
|
||||
{
|
||||
path = String.Format("{0}{1}", _prefix, path);
|
||||
}
|
||||
|
||||
RestStreamHandler h = new RestStreamHandler(httpMethod, path, method);
|
||||
_httpd.AddStreamHandler(h);
|
||||
_handlers.Add(h);
|
||||
|
||||
m_log.DebugFormat("{0} Added REST handler {1} {2}", MsgID, httpMethod, path);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add a powerful Agent handler to the underlying HTTP
|
||||
/// server.
|
||||
/// </summary>
|
||||
/// <param name="agentName">name of agent handler</param>
|
||||
/// <param name="handler">agent handler method</param>
|
||||
/// <returns>false when the plugin is disabled or the agent
|
||||
/// handler could not be added. Any generated exceptions are
|
||||
/// allowed to drop through to the caller, i.e. ArgumentException.
|
||||
/// </returns>
|
||||
public bool AddAgentHandler(string agentName, IHttpAgentHandler handler)
|
||||
{
|
||||
if (!IsEnabled) return false;
|
||||
_agents.Add(agentName, handler);
|
||||
return _httpd.AddAgentHandler(agentName, handler);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove a powerful Agent handler from the underlying HTTP
|
||||
/// server.
|
||||
/// </summary>
|
||||
/// <param name="agentName">name of agent handler</param>
|
||||
/// <param name="handler">agent handler method</param>
|
||||
/// <returns>false when the plugin is disabled or the agent
|
||||
/// handler could not be removed. Any generated exceptions are
|
||||
/// allowed to drop through to the caller, i.e. KeyNotFound.
|
||||
/// </returns>
|
||||
public bool RemoveAgentHandler(string agentName, IHttpAgentHandler handler)
|
||||
{
|
||||
if (!IsEnabled) return false;
|
||||
if (_agents[agentName] == handler)
|
||||
{
|
||||
_agents.Remove(agentName);
|
||||
return _httpd.RemoveAgentHandler(agentName, handler);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check whether the HTTP request came from god; that is, is
|
||||
/// the god_key as configured in the config section supplied
|
||||
/// via X-OpenSim-Godkey?
|
||||
/// </summary>
|
||||
/// <param name="request">HTTP request header</param>
|
||||
/// <returns>true when the HTTP request came from god.</returns>
|
||||
protected bool IsGod(IOSHttpRequest request)
|
||||
{
|
||||
string[] keys = request.Headers.GetValues("X-OpenSim-Godkey");
|
||||
if (null == keys) return false;
|
||||
|
||||
// we take the last key supplied
|
||||
return keys[keys.Length - 1] == _godkey;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks wether the X-OpenSim-Password value provided in the
|
||||
/// HTTP header is indeed the password on file for the avatar
|
||||
/// specified by the UUID
|
||||
/// </summary>
|
||||
protected bool IsVerifiedUser(IOSHttpRequest request, UUID uuid)
|
||||
{
|
||||
// XXX under construction
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clean up and remove all handlers that were added earlier.
|
||||
/// </summary>
|
||||
public virtual void Close()
|
||||
{
|
||||
foreach (RestStreamHandler h in _handlers)
|
||||
{
|
||||
_httpd.RemoveStreamHandler(h.HttpMethod, h.Path);
|
||||
}
|
||||
_handlers = null;
|
||||
foreach (KeyValuePair<string, IHttpAgentHandler> h in _agents)
|
||||
{
|
||||
_httpd.RemoveAgentHandler(h.Key, h.Value);
|
||||
}
|
||||
_agents = null;
|
||||
}
|
||||
|
||||
public virtual void Dispose()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return a failure message.
|
||||
/// </summary>
|
||||
/// <param name="method">origin of the failure message</param>
|
||||
/// <param name="message">failure message</param>
|
||||
/// <remarks>This should probably set a return code as
|
||||
/// well. (?)</remarks>
|
||||
protected string Failure(IOSHttpResponse response, OSHttpStatusCode status,
|
||||
string method, string format, params string[] msg)
|
||||
{
|
||||
string m = String.Format(format, msg);
|
||||
|
||||
response.StatusCode = (int) status;
|
||||
response.StatusDescription = m;
|
||||
|
||||
m_log.ErrorFormat("{0} {1} failed: {2}", MsgID, method, m);
|
||||
return String.Format("<error>{0}</error>", m);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return a failure message.
|
||||
/// </summary>
|
||||
/// <param name="method">origin of the failure message</param>
|
||||
/// <param name="e">exception causing the failure message</param>
|
||||
/// <remarks>This should probably set a return code as
|
||||
/// well. (?)</remarks>
|
||||
public string Failure(IOSHttpResponse response, OSHttpStatusCode status,
|
||||
string method, Exception e)
|
||||
{
|
||||
string m = String.Format("exception occurred: {0}", e.Message);
|
||||
|
||||
response.StatusCode = (int) status;
|
||||
response.StatusDescription = m;
|
||||
|
||||
m_log.DebugFormat("{0} {1} failed: {2}", MsgID, method, e.ToString());
|
||||
m_log.ErrorFormat("{0} {1} failed: {2}", MsgID, method, e.Message);
|
||||
|
||||
return String.Format("<error>{0}</error>", e.Message);
|
||||
}
|
||||
|
||||
#endregion methods
|
||||
}
|
||||
}
|
||||
@@ -25,35 +25,48 @@
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Data.MySQL;
|
||||
|
||||
using OpenMetaverse;
|
||||
using MySql.Data.MySqlClient;
|
||||
|
||||
namespace OpenSim.Data.MySQL
|
||||
namespace OpenSim.ApplicationPlugins.Rest
|
||||
{
|
||||
public class MySQLOfflineIMData : MySQLGenericTableHandler<OfflineIMData>, IOfflineIMData
|
||||
public class RestXmlWriter: XmlTextWriter
|
||||
{
|
||||
public MySQLOfflineIMData(string connectionString, string realm)
|
||||
: base(connectionString, realm, "IM_Store")
|
||||
private StringWriter m_sw = null;
|
||||
|
||||
public RestXmlWriter(StringWriter sw) : base(sw)
|
||||
{
|
||||
m_sw = sw;
|
||||
Formatting = Formatting.Indented;
|
||||
}
|
||||
|
||||
public RestXmlWriter(TextWriter textWriter) : base(textWriter)
|
||||
{
|
||||
}
|
||||
|
||||
public void DeleteOld()
|
||||
public RestXmlWriter(Stream stream)
|
||||
: this(stream, Encoding.UTF8)
|
||||
{
|
||||
using (MySqlCommand cmd = new MySqlCommand())
|
||||
{
|
||||
cmd.CommandText = String.Format("delete from {0} where TMStamp < NOW() - INTERVAL 2 WEEK", m_Realm);
|
||||
|
||||
ExecuteNonQuery(cmd);
|
||||
}
|
||||
}
|
||||
|
||||
public RestXmlWriter(Stream stream, Encoding enc) : base(stream, enc)
|
||||
{
|
||||
}
|
||||
|
||||
public override void WriteStartDocument()
|
||||
{
|
||||
}
|
||||
|
||||
public override void WriteStartDocument(bool standalone)
|
||||
{
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
Flush();
|
||||
Close();
|
||||
return m_sw.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
276
OpenSim/ApplicationPlugins/Rest/rest.xsd
Normal file
276
OpenSim/ApplicationPlugins/Rest/rest.xsd
Normal file
@@ -0,0 +1,276 @@
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||
|
||||
<xsd:annotation>
|
||||
<xsd:documentation xml:lang="en">
|
||||
Open Simulator Export/Import XML schema
|
||||
August 2008
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
|
||||
<!-- WARNING!!!
|
||||
This is currently a draft, it does not reflect
|
||||
what is exported, nor what will be understood
|
||||
on import. It is included as a working document
|
||||
and this comment will be removed at such time as
|
||||
the schema corresponds to reality.
|
||||
-->
|
||||
|
||||
<!--
|
||||
REST-related information
|
||||
Inventory data is always framed by an
|
||||
inventory element. Consists of zero or
|
||||
more elements representing either folders
|
||||
or items within those folders. The inventory
|
||||
element represents the "real" root folder.
|
||||
-->
|
||||
|
||||
<xsd:element name="inventory" type="inventory_ct" />
|
||||
|
||||
<!--
|
||||
The inventory complex type is just an arbitrary
|
||||
sequence of folders and items. In reality it is
|
||||
typically just folders. Both item and folder
|
||||
have corresponding complex types. It is distinct
|
||||
from folders insofar as it has no other defining
|
||||
attributes.
|
||||
-->
|
||||
|
||||
<xsd:complexType name="inventory_ct">
|
||||
<xsd:element name="folder" type="folder_ct" maxOccurs="unbounded"/>
|
||||
<xsd:element name="item" type="item_ct" maxOccurs="unbounded" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="folder_ct">
|
||||
<xsd:attribute name="UUID" type="uuid_st" />
|
||||
<xsd:attribute name="name" type="name_st" />
|
||||
<xsd:attribute name="type" type="folder_type_st" />
|
||||
<xsd:attribute name="description" type="xsd:string" /> <!-- added -->
|
||||
<xsd:attribute name="version" type="unsignedShort" />
|
||||
<xsd:attribute name="owner" type="uuid_st" />
|
||||
|
||||
<xsd:attribute name="creator" type="uuid_st" /> <!-- added -->
|
||||
<xsd:attribute name="creationdate" type="date_st" /> <!-- added -->
|
||||
|
||||
<xsd:attribute name="parent" type="uuid_st" />
|
||||
|
||||
<xsd:element name="permissions" type="permissions_ct" maxOccurs="unbounded" /> <!-- added -->
|
||||
<xsd:element name="folder" type="folder_ct" maxOccurs="unbounded" />
|
||||
<xsd:element name="item" type="item_ct" maxOccurs="unbounded" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="item_ct">
|
||||
<xsd:attribute name="UUID" type="uuid_st" />
|
||||
<xsd:attribute name="name" type="name_st" />
|
||||
<xsd:attribute name="type" type="inventory_type_st" />
|
||||
<xsd:attribute name="description" type="xsd:string" />
|
||||
<xsd:attribute name="version" type="unsignedShort" /> <!-- added -->
|
||||
<xsd:attribute name="owner" type="uuid_st" />
|
||||
|
||||
<xsd:attribute name="creator" type="uuid_st" />
|
||||
<xsd:attribute name="creationdate" type="date_st" />
|
||||
|
||||
<xsd:attribute name="folder" type="uuid_st" />
|
||||
<xsd:attribute name="groupid" type="uuid_st" />
|
||||
<xsd:attribute name="groupowned" type="xsd:boolean" />
|
||||
<xsd:attribute name="saletype" type="sale_st" />
|
||||
<xsd:attribute name="saleprice" type="xsd:decimal" />
|
||||
|
||||
<xsd:element name="permissions" type="permissions_ct" maxOccurs="unbounded" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="asset_ct">
|
||||
<xsd:attribute name="UUID" type="uuid_st" />
|
||||
<xsd:attribute name="name" type="name_st" />
|
||||
<xsd:attribute name="type" type="asset_type_st" />
|
||||
<xsd:attribute name="description" type="xsd:string" />
|
||||
<xsd:attribute name="version" type="unsignedShort" /> <!-- added -->
|
||||
<xsd:attribute name="owner" type="uuid_st" />
|
||||
|
||||
<xsd:attribute name="creator" type="uuid_st" />
|
||||
<xsd:attribute name="creationdate" type="date_st" />
|
||||
|
||||
<xsd:attribute name="temporary" type="xsd:boolean" />
|
||||
<xsd:attribute name="local" type="xsd:boolean" />
|
||||
<xsd:attribute name="inline" type="xsd:boolean" />
|
||||
</xsd:complexType>
|
||||
|
||||
<!-- Constrained Simple Data types -->
|
||||
|
||||
<!--
|
||||
We need to specify name as a simple type because on
|
||||
some platforms it is constrained by a certain length
|
||||
limitation. For completeness we indicate that whitespace
|
||||
should be preserved exactly as specified.
|
||||
-->
|
||||
|
||||
<xsd:simpleType name="name_st">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<whiteSpace value="preserve" />
|
||||
<minLength value="0" />
|
||||
<maxLength value="64" />
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
|
||||
<!--
|
||||
Type information in the folder is meant to indicate
|
||||
the preferred asset type for this folder. As such, that
|
||||
currently corresponds to the type values allowed for
|
||||
assets, however that is not mandated, so for
|
||||
now at least I'll represent this as a distinct
|
||||
enumeration.
|
||||
This seems inappropriate; it seems like the folder's
|
||||
content should reflect the InventoryType classifications
|
||||
rather than the asset types.
|
||||
-->
|
||||
|
||||
<xsd:simpleType name="folder_type_st">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="Texture" />
|
||||
<xsd:enumeration value="Sound" />
|
||||
<xsd:enumeration value="CallingCard" />
|
||||
<xsd:enumeration value="Landmark" />
|
||||
<xsd:enumeration value="Script" />
|
||||
<xsd:enumeration value="Clothing" />
|
||||
<xsd:enumeration value="Object" />
|
||||
<xsd:enumeration value="Notecard" />
|
||||
<xsd:enumeration value="LSLText" />
|
||||
<xsd:enumeration value="LSLByteCode" />
|
||||
<xsd:enumeration value="TextureTGA" />
|
||||
<xsd:enumeration value="BodyPart" />
|
||||
<xsd:enumeration value="SoundWAV" />
|
||||
<xsd:enumeration value="ImageTGA" />
|
||||
<xsd:enumeration value="ImageJPEG" />
|
||||
<xsd:enumeration value="Animation" />
|
||||
<xsd:enumeration value="Gesture" />
|
||||
<xsd:enumeration value="Simstate" />
|
||||
<xsd:enumeration value="Unknown" />
|
||||
<xsd:enumeration value="LostAndFoundFolder" />
|
||||
<xsd:enumeration value="SnapshotFolder" />
|
||||
<xsd:enumeration value="TrashFolder" />
|
||||
<xsd:enumeration value="Folder" />
|
||||
<xsd:enumeration value="RootFolder" />
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
|
||||
<!--
|
||||
Inventory item type designates an asset class, rather
|
||||
than a specific asset type. For example, "SnapShot"
|
||||
might include a number of asset types such as JPEG,
|
||||
TGA, etc.. This is not a consistent interpretation,
|
||||
classifications such as LostAndFound are meta-types
|
||||
relative to asset classes.
|
||||
|
||||
These types should be abstract and not be tied to a
|
||||
specific platform. A world's import facility should be
|
||||
responsible for mapping these to meaningful internal
|
||||
representations.
|
||||
|
||||
These types were based on information in:
|
||||
libsecondlife/InventoryManager.cs
|
||||
-->
|
||||
|
||||
<xsd:simpleType name="inventory_type_st">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="Texture" />
|
||||
<xsd:enumeration value="Sound" />
|
||||
<xsd:enumeration value="CallingCard" />
|
||||
<xsd:enumeration value="Landmark" />
|
||||
<xsd:enumeration value="Script" />
|
||||
<xsd:enumeration value="Clothing" />
|
||||
<xsd:enumeration value="Object" />
|
||||
<xsd:enumeration value="Notecard" />
|
||||
<xsd:enumeration value="LSL" />
|
||||
<xsd:enumeration value="LSLBytecode" />
|
||||
<xsd:enumeration value="TextureTGA" />
|
||||
<xsd:enumeration value="BodyPart" />
|
||||
<xsd:enumeration value="Snapshot" />
|
||||
<xsd:enumeration value="Attachment" />
|
||||
<xsd:enumeration value="Wearable" />
|
||||
<xsd:enumeration value="Animation" />
|
||||
<xsd:enumeration value="Gesture" />
|
||||
<xsd:enumeration value="Folder" />
|
||||
<xsd:enumeration value="Unknown" />
|
||||
<xsd:enumeration value="LostAndFound" />
|
||||
<xsd:enumeration value="Trash" />
|
||||
<xsd:enumeration value="Root" />
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
|
||||
<!--
|
||||
The asset types seem to be even more disarrayed than
|
||||
the inventory types. It seems to be little more than
|
||||
a reiteration of the inventory type information,
|
||||
which adds little or nothing to the overall data
|
||||
model.
|
||||
|
||||
Of course, given that these are drawn from the
|
||||
libsecondlife definitions, we aren't at liberty to
|
||||
simply redefine them in place. But the XML definitions
|
||||
here could be made more useful.
|
||||
|
||||
These types were based on information in:
|
||||
libsecondlife/AssetManager.cs
|
||||
-->
|
||||
|
||||
<xsd:simpleType name="asset_type_st">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="Texture" />
|
||||
<xsd:enumeration value="Sound" />
|
||||
<xsd:enumeration value="CallingCard" />
|
||||
<xsd:enumeration value="Landmark" />
|
||||
<xsd:enumeration value="Script" />
|
||||
<xsd:enumeration value="Clothing" />
|
||||
<xsd:enumeration value="Object" />
|
||||
<xsd:enumeration value="Notecard" />
|
||||
<xsd:enumeration value="LSLText" />
|
||||
<xsd:enumeration value="LSLByteCode" />
|
||||
<xsd:enumeration value="TextureTGA" />
|
||||
<xsd:enumeration value="BodyPart" />
|
||||
<xsd:enumeration value="SoundWAV" />
|
||||
<xsd:enumeration value="ImageTGA" />
|
||||
<xsd:enumeration value="ImageJPEG" />
|
||||
<xsd:enumeration value="Animation" />
|
||||
<xsd:enumeration value="Gesture" />
|
||||
<xsd:enumeration value="Simstate" />
|
||||
<xsd:enumeration value="Unknown" />
|
||||
<xsd:enumeration value="LostAndFoundFolder" />
|
||||
<xsd:enumeration value="SnapshotFolder" />
|
||||
<xsd:enumeration value="TrashFolder" />
|
||||
<xsd:enumeration value="Folder" />
|
||||
<xsd:enumeration value="RootFolder" />
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
|
||||
<!-- This is describing the apparent form of a UUID. If
|
||||
we ever want a more metaphysical definition we'll
|
||||
need to add to it.
|
||||
-->
|
||||
|
||||
<xsd:simpleType name="uuid_st">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:pattern value="[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
|
||||
<!-- This constrains the date representation. Currently
|
||||
it is simply an integer representing the elapsed
|
||||
?? since ??.
|
||||
-->
|
||||
|
||||
<xsd:simpleType name="date_st">
|
||||
<xsd:restriction base="xsd:positiveInteger">
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
|
||||
<!-- This constrains the representation of sale price.
|
||||
Currently it is a simple decimal with no unit
|
||||
specified.
|
||||
Issues: interoperability.
|
||||
-->
|
||||
|
||||
<xsd:simpleType name="sale_st">
|
||||
<xsd:restriction base="xsd:decimal">
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
|
||||
</xsd:schema>
|
||||
@@ -63,11 +63,7 @@ namespace OpenSim.Framework.Capabilities
|
||||
public string CapsObjectPath { get { return m_capsObjectPath; } }
|
||||
|
||||
private CapsHandlers m_capsHandlers;
|
||||
|
||||
private Dictionary<string, PollServiceEventArgs> m_pollServiceHandlers
|
||||
= new Dictionary<string, PollServiceEventArgs>();
|
||||
|
||||
private Dictionary<string, string> m_externalCapsHandlers = new Dictionary<string, string>();
|
||||
private Dictionary<string, string> m_externalCapsHandlers;
|
||||
|
||||
private IHttpServer m_httpListener;
|
||||
private UUID m_agentID;
|
||||
@@ -136,6 +132,7 @@ namespace OpenSim.Framework.Capabilities
|
||||
|
||||
m_agentID = agent;
|
||||
m_capsHandlers = new CapsHandlers(httpServer, httpListen, httpPort, (httpServer == null) ? false : httpServer.UseSSL);
|
||||
m_externalCapsHandlers = new Dictionary<string, string>();
|
||||
m_regionName = regionName;
|
||||
}
|
||||
|
||||
@@ -146,29 +143,8 @@ namespace OpenSim.Framework.Capabilities
|
||||
/// <param name="handler"></param>
|
||||
public void RegisterHandler(string capName, IRequestHandler handler)
|
||||
{
|
||||
//m_log.DebugFormat("[CAPS]: Registering handler for \"{0}\": path {1}", capName, handler.Path);
|
||||
m_capsHandlers[capName] = handler;
|
||||
}
|
||||
|
||||
public void RegisterPollHandler(string capName, PollServiceEventArgs pollServiceHandler)
|
||||
{
|
||||
m_pollServiceHandlers.Add(capName, pollServiceHandler);
|
||||
|
||||
m_httpListener.AddPollServiceHTTPHandler(pollServiceHandler.Url, pollServiceHandler);
|
||||
|
||||
// uint port = (MainServer.Instance == null) ? 0 : MainServer.Instance.Port;
|
||||
// string protocol = "http";
|
||||
// string hostName = m_httpListenerHostName;
|
||||
//
|
||||
// if (MainServer.Instance.UseSSL)
|
||||
// {
|
||||
// hostName = MainServer.Instance.SSLCommonName;
|
||||
// port = MainServer.Instance.SSLPort;
|
||||
// protocol = "https";
|
||||
// }
|
||||
|
||||
// RegisterHandler(
|
||||
// capName, String.Format("{0}://{1}:{2}{3}", protocol, hostName, port, pollServiceHandler.Url));
|
||||
//m_log.DebugFormat("[CAPS]: Registering handler for \"{0}\": path {1}", capName, handler.Path);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -187,70 +163,13 @@ namespace OpenSim.Framework.Capabilities
|
||||
/// </summary>
|
||||
public void DeregisterHandlers()
|
||||
{
|
||||
foreach (string capsName in m_capsHandlers.Caps)
|
||||
if (m_capsHandlers != null)
|
||||
{
|
||||
m_capsHandlers.Remove(capsName);
|
||||
}
|
||||
|
||||
foreach (PollServiceEventArgs handler in m_pollServiceHandlers.Values)
|
||||
{
|
||||
m_httpListener.RemovePollServiceHTTPHandler("", handler.Url);
|
||||
}
|
||||
}
|
||||
|
||||
public bool TryGetPollHandler(string name, out PollServiceEventArgs pollHandler)
|
||||
{
|
||||
return m_pollServiceHandlers.TryGetValue(name, out pollHandler);
|
||||
}
|
||||
|
||||
public Dictionary<string, PollServiceEventArgs> GetPollHandlers()
|
||||
{
|
||||
return new Dictionary<string, PollServiceEventArgs>(m_pollServiceHandlers);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return an LLSD-serializable Hashtable describing the
|
||||
/// capabilities and their handler details.
|
||||
/// </summary>
|
||||
/// <param name="excludeSeed">If true, then exclude the seed cap.</param>
|
||||
public Hashtable GetCapsDetails(bool excludeSeed, List<string> requestedCaps)
|
||||
{
|
||||
Hashtable caps = CapsHandlers.GetCapsDetails(excludeSeed, requestedCaps);
|
||||
|
||||
lock (m_pollServiceHandlers)
|
||||
{
|
||||
foreach (KeyValuePair <string, PollServiceEventArgs> kvp in m_pollServiceHandlers)
|
||||
foreach (string capsName in m_capsHandlers.Caps)
|
||||
{
|
||||
if (!requestedCaps.Contains(kvp.Key))
|
||||
continue;
|
||||
|
||||
string hostName = m_httpListenerHostName;
|
||||
uint port = (MainServer.Instance == null) ? 0 : MainServer.Instance.Port;
|
||||
string protocol = "http";
|
||||
|
||||
if (MainServer.Instance.UseSSL)
|
||||
{
|
||||
hostName = MainServer.Instance.SSLCommonName;
|
||||
port = MainServer.Instance.SSLPort;
|
||||
protocol = "https";
|
||||
}
|
||||
//
|
||||
// caps.RegisterHandler("FetchInventoryDescendents2", String.Format("{0}://{1}:{2}{3}", protocol, hostName, port, capUrl));
|
||||
|
||||
caps[kvp.Key] = string.Format("{0}://{1}:{2}{3}", protocol, hostName, port, kvp.Value.Url);
|
||||
m_capsHandlers.Remove(capsName);
|
||||
}
|
||||
}
|
||||
|
||||
// Add the external too
|
||||
foreach (KeyValuePair<string, string> kvp in ExternalCapsHandlers)
|
||||
{
|
||||
if (!requestedCaps.Contains(kvp.Key))
|
||||
continue;
|
||||
|
||||
caps[kvp.Key] = kvp.Value;
|
||||
}
|
||||
|
||||
return caps;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace OpenSim.Framework.Capabilities
|
||||
/// </summary>
|
||||
public class CapsHandlers
|
||||
{
|
||||
private Dictionary<string, IRequestHandler> m_capsHandlers = new Dictionary<string, IRequestHandler>();
|
||||
private Dictionary <string, IRequestHandler> m_capsHandlers = new Dictionary<string, IRequestHandler>();
|
||||
private IHttpServer m_httpListener;
|
||||
private string m_httpListenerHostName;
|
||||
private uint m_httpListenerPort;
|
||||
@@ -158,7 +158,7 @@ namespace OpenSim.Framework.Capabilities
|
||||
/// capabilities and their handler details.
|
||||
/// </summary>
|
||||
/// <param name="excludeSeed">If true, then exclude the seed cap.</param>
|
||||
public Hashtable GetCapsDetails(bool excludeSeed, List<string> requestedCaps)
|
||||
public Hashtable GetCapsDetails(bool excludeSeed)
|
||||
{
|
||||
Hashtable caps = new Hashtable();
|
||||
string protocol = "http://";
|
||||
@@ -175,26 +175,11 @@ namespace OpenSim.Framework.Capabilities
|
||||
if (excludeSeed && "SEED" == capsName)
|
||||
continue;
|
||||
|
||||
if (requestedCaps != null && !requestedCaps.Contains(capsName))
|
||||
continue;
|
||||
|
||||
caps[capsName] = baseUrl + m_capsHandlers[capsName].Path;
|
||||
}
|
||||
}
|
||||
|
||||
return caps;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a copy of the dictionary of all the HTTP cap handlers
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The dictionary copy. The key is the capability name, the value is the HTTP handler.
|
||||
/// </returns>
|
||||
public Dictionary<string, IRequestHandler> GetCapsHandlers()
|
||||
{
|
||||
lock (m_capsHandlers)
|
||||
return new Dictionary<string, IRequestHandler>(m_capsHandlers);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,116 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Web;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Capabilities;
|
||||
using OpenSim.Framework.Servers;
|
||||
using OpenSim.Framework.Servers.HttpServer;
|
||||
//using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using Caps = OpenSim.Framework.Capabilities.Caps;
|
||||
|
||||
namespace OpenSim.Capabilities.Handlers
|
||||
{
|
||||
public class AvatarPickerSearchHandler : BaseStreamHandler
|
||||
{
|
||||
private static readonly ILog m_log =
|
||||
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
private IPeople m_PeopleService;
|
||||
|
||||
public AvatarPickerSearchHandler(string path, IPeople peopleService, string name, string description)
|
||||
: base("GET", path, name, description)
|
||||
{
|
||||
m_PeopleService = peopleService;
|
||||
}
|
||||
|
||||
protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
||||
{
|
||||
// Try to parse the texture ID from the request URL
|
||||
NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query);
|
||||
string names = query.GetOne("names");
|
||||
string psize = query.GetOne("page_size");
|
||||
string pnumber = query.GetOne("page");
|
||||
|
||||
if (m_PeopleService == null)
|
||||
return FailureResponse(names, (int)System.Net.HttpStatusCode.InternalServerError, httpResponse);
|
||||
|
||||
if (string.IsNullOrEmpty(names) || names.Length < 3)
|
||||
return FailureResponse(names, (int)System.Net.HttpStatusCode.BadRequest, httpResponse);
|
||||
|
||||
m_log.DebugFormat("[AVATAR PICKER SEARCH]: search for {0}", names);
|
||||
|
||||
int page_size = (string.IsNullOrEmpty(psize) ? 500 : Int32.Parse(psize));
|
||||
int page_number = (string.IsNullOrEmpty(pnumber) ? 1 : Int32.Parse(pnumber));
|
||||
|
||||
// Full content request
|
||||
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.OK;
|
||||
//httpResponse.ContentLength = ??;
|
||||
httpResponse.ContentType = "application/llsd+xml";
|
||||
|
||||
List<UserData> users = m_PeopleService.GetUserData(names, page_size, page_number);
|
||||
|
||||
LLSDAvatarPicker osdReply = new LLSDAvatarPicker();
|
||||
osdReply.next_page_url = httpRequest.RawUrl;
|
||||
foreach (UserData u in users)
|
||||
osdReply.agents.Array.Add(ConvertUserData(u));
|
||||
|
||||
string reply = LLSDHelpers.SerialiseLLSDReply(osdReply);
|
||||
return System.Text.Encoding.UTF8.GetBytes(reply);
|
||||
}
|
||||
|
||||
private LLSDPerson ConvertUserData(UserData user)
|
||||
{
|
||||
LLSDPerson p = new LLSDPerson();
|
||||
p.legacy_first_name = user.FirstName;
|
||||
p.legacy_last_name = user.LastName;
|
||||
p.display_name = user.FirstName + " " + user.LastName;
|
||||
if (user.LastName.StartsWith("@"))
|
||||
p.username = user.FirstName.ToLower() + user.LastName.ToLower();
|
||||
else
|
||||
p.username = user.FirstName.ToLower() + "." + user.LastName.ToLower();
|
||||
p.id = user.Id;
|
||||
p.is_display_name_default = false;
|
||||
return p;
|
||||
}
|
||||
|
||||
private byte[] FailureResponse(string names, int statuscode, IOSHttpResponse httpResponse)
|
||||
{
|
||||
m_log.Error("[AVATAR PICKER SEARCH]: Error searching for " + names);
|
||||
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
|
||||
return System.Text.Encoding.UTF8.GetBytes(string.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -46,7 +46,7 @@ namespace OpenSim.Capabilities.Handlers
|
||||
{
|
||||
public class FetchInventory2Handler
|
||||
{
|
||||
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private IInventoryService m_inventoryService;
|
||||
|
||||
@@ -121,4 +121,4 @@ namespace OpenSim.Capabilities.Handlers
|
||||
return llsdItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ namespace OpenSim.Capabilities.Handlers
|
||||
m_assetService = assService;
|
||||
}
|
||||
|
||||
protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
||||
public override byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
||||
{
|
||||
// Try to parse the texture ID from the request URL
|
||||
NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query);
|
||||
@@ -85,7 +85,7 @@ namespace OpenSim.Capabilities.Handlers
|
||||
// m_log.DebugFormat("[GETTEXTURE]: Received request for texture id {0}", textureID);
|
||||
|
||||
string[] formats;
|
||||
if (!string.IsNullOrEmpty(format))
|
||||
if (format != null && format != string.Empty)
|
||||
{
|
||||
formats = new string[1] { format.ToLower() };
|
||||
}
|
||||
@@ -189,7 +189,6 @@ namespace OpenSim.Capabilities.Handlers
|
||||
|
||||
newTexture.Flags = AssetFlags.Collectable;
|
||||
newTexture.Temporary = true;
|
||||
newTexture.Local = true;
|
||||
m_assetService.Store(newTexture);
|
||||
WriteTextureData(httpRequest, httpResponse, newTexture, format);
|
||||
return true;
|
||||
@@ -224,9 +223,9 @@ namespace OpenSim.Capabilities.Handlers
|
||||
// sending back the last byte instead of an error status
|
||||
if (start >= texture.Data.Length)
|
||||
{
|
||||
// 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);
|
||||
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
|
||||
@@ -247,11 +246,6 @@ namespace OpenSim.Capabilities.Handlers
|
||||
}
|
||||
else
|
||||
{
|
||||
// Handle the case where no second range value was given. This is equivalent to requesting
|
||||
// the rest of the entity.
|
||||
if (end == -1)
|
||||
end = int.MaxValue;
|
||||
|
||||
end = Utils.Clamp(end, 0, texture.Data.Length - 1);
|
||||
start = Utils.Clamp(start, 0, end);
|
||||
int len = end - start + 1;
|
||||
@@ -305,43 +299,15 @@ namespace OpenSim.Capabilities.Handlers
|
||||
// texture.FullID, range, response.StatusCode, response.ContentLength, texture.Data.Length);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse a range header.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// As per http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html,
|
||||
/// this obeys range headers with two values (e.g. 533-4165) and no second value (e.g. 533-).
|
||||
/// Where there is no value, -1 is returned.
|
||||
/// FIXME: Need to cover the case where only a second value is specified (e.g. -4165), probably by returning -1
|
||||
/// for start.</remarks>
|
||||
/// <returns></returns>
|
||||
/// <param name='header'></param>
|
||||
/// <param name='start'>Start of the range. Undefined if this was not a number.</param>
|
||||
/// <param name='end'>End of the range. Will be -1 if no end specified. Undefined if there was a raw string but this was not a number.</param>
|
||||
private bool TryParseRange(string header, out int start, out int end)
|
||||
{
|
||||
start = end = 0;
|
||||
|
||||
if (header.StartsWith("bytes="))
|
||||
{
|
||||
string[] rangeValues = header.Substring(6).Split('-');
|
||||
|
||||
if (rangeValues.Length == 2)
|
||||
{
|
||||
if (!Int32.TryParse(rangeValues[0], out start))
|
||||
return false;
|
||||
|
||||
string rawEnd = rangeValues[1];
|
||||
|
||||
if (rawEnd == "")
|
||||
{
|
||||
end = -1;
|
||||
if (Int32.TryParse(rangeValues[0], out start) && Int32.TryParse(rangeValues[1], out end))
|
||||
return true;
|
||||
}
|
||||
else if (Int32.TryParse(rawEnd, out end))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ using OpenSim.Tests.Common.Mock;
|
||||
namespace OpenSim.Capabilities.Handlers.GetTexture.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class GetTextureHandlerTests : OpenSimTestCase
|
||||
public class GetTextureHandlerTests
|
||||
{
|
||||
[Test]
|
||||
public void TestTextureNotFound()
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("OpenSim.Capabilities.Handlers")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("http://opensimulator.org")]
|
||||
[assembly: AssemblyProduct("OpenSim")]
|
||||
[assembly: AssemblyCopyright("OpenSimulator developers")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("32350823-e1df-45e3-b7fa-0a58b4372433")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
[assembly: AssemblyVersion("0.8.0.*")]
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using Nini.Config;
|
||||
using OpenSim.Server.Base;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using OpenSim.Framework.Servers.HttpServer;
|
||||
using OpenSim.Server.Handlers.Base;
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace OpenSim.Capabilities.Handlers
|
||||
{
|
||||
public class UploadBakedTextureServerConnector : ServiceConnector
|
||||
{
|
||||
private IAssetService m_AssetService;
|
||||
private string m_ConfigName = "CapsService";
|
||||
|
||||
public UploadBakedTextureServerConnector(IConfigSource config, IHttpServer server, string configName) :
|
||||
base(config, server, configName)
|
||||
{
|
||||
if (configName != String.Empty)
|
||||
m_ConfigName = configName;
|
||||
|
||||
IConfig serverConfig = config.Configs[m_ConfigName];
|
||||
if (serverConfig == null)
|
||||
throw new Exception(String.Format("No section '{0}' in config file", m_ConfigName));
|
||||
|
||||
string assetService = serverConfig.GetString("AssetService", String.Empty);
|
||||
|
||||
if (assetService == String.Empty)
|
||||
throw new Exception("No AssetService in config file");
|
||||
|
||||
Object[] args = new Object[] { config };
|
||||
m_AssetService =
|
||||
ServerUtils.LoadPlugin<IAssetService>(assetService, args);
|
||||
|
||||
if (m_AssetService == null)
|
||||
throw new Exception(String.Format("Failed to load AssetService from {0}; config is {1}", assetService, m_ConfigName));
|
||||
|
||||
// NEED TO FIX THIS
|
||||
OpenSim.Framework.Capabilities.Caps caps = new OpenSim.Framework.Capabilities.Caps(server, "", server.Port, "", UUID.Zero, "");
|
||||
server.AddStreamHandler(new RestStreamHandler(
|
||||
"POST",
|
||||
"/CAPS/UploadBakedTexture/",
|
||||
new UploadBakedTextureHandler(caps, m_AssetService, true).UploadBakedTexture,
|
||||
"UploadBakedTexture",
|
||||
"Upload Baked Texture Capability"));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -163,7 +163,7 @@ namespace OpenSim.Capabilities.Handlers
|
||||
invFetch.owner_id, invFetch.folder_id, invFetch.owner_id,
|
||||
invFetch.fetch_folders, invFetch.fetch_items, invFetch.sort_order, out version, out descendents);
|
||||
|
||||
if (inv != null && inv.Folders != null)
|
||||
if (inv.Folders != null)
|
||||
{
|
||||
foreach (InventoryFolderBase invFolder in inv.Folders)
|
||||
{
|
||||
@@ -173,7 +173,7 @@ namespace OpenSim.Capabilities.Handlers
|
||||
descendents += inv.Folders.Count;
|
||||
}
|
||||
|
||||
if (inv != null && inv.Items != null)
|
||||
if (inv.Items != null)
|
||||
{
|
||||
foreach (InventoryItemBase invItem in inv.Items)
|
||||
{
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace OpenSim.Framework.Capabilities
|
||||
{
|
||||
[OSDMap]
|
||||
public class LLSDAvatarPicker
|
||||
{
|
||||
public string next_page_url;
|
||||
// an array of LLSDPerson
|
||||
public OSDArray agents = new OSDArray();
|
||||
}
|
||||
|
||||
[OSDMap]
|
||||
public class LLSDPerson
|
||||
{
|
||||
public string username;
|
||||
public string display_name;
|
||||
//'display_name_next_update':d"1970-01-01T00:00:00Z"
|
||||
public string legacy_first_name;
|
||||
public string legacy_last_name;
|
||||
public UUID id;
|
||||
public bool is_display_name_default;
|
||||
}
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace OpenSim.Framework.Capabilities
|
||||
{
|
||||
[OSDMap]
|
||||
public class LLSDEnvironmentRequest
|
||||
{
|
||||
public UUID messageID;
|
||||
public UUID regionID;
|
||||
}
|
||||
|
||||
[OSDMap]
|
||||
public class LLSDEnvironmentSetResponse
|
||||
{
|
||||
public UUID regionID;
|
||||
public UUID messageID;
|
||||
public Boolean success;
|
||||
public String fail_reason;
|
||||
}
|
||||
|
||||
public class EnvironmentSettings
|
||||
{
|
||||
/// <summary>
|
||||
/// generates a empty llsd settings response for viewer
|
||||
/// </summary>
|
||||
/// <param name="messageID">the message UUID</param>
|
||||
/// <param name="regionID">the region UUID</param>
|
||||
public static string EmptySettings(UUID messageID, UUID regionID)
|
||||
{
|
||||
OSDArray arr = new OSDArray();
|
||||
LLSDEnvironmentRequest msg = new LLSDEnvironmentRequest();
|
||||
msg.messageID = messageID;
|
||||
msg.regionID = regionID;
|
||||
arr.Array.Add(msg);
|
||||
return LLSDHelpers.SerialiseLLSDReply(arr);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -48,7 +48,7 @@ namespace OpenSim.Framework.Capabilities
|
||||
m_method = method;
|
||||
}
|
||||
|
||||
protected override byte[] ProcessRequest(string path, Stream request,
|
||||
public override byte[] Handle(string path, Stream request,
|
||||
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
||||
{
|
||||
//Encoding encoding = Util.UTF8;
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("OpenSim.Capabilities")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("http://opensimulator.org")]
|
||||
[assembly: AssemblyProduct("OpenSim")]
|
||||
[assembly: AssemblyCopyright("OpenSimulator developers")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("7d1a55b1-8fab-42ff-9c83-066a9cc34d76")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
[assembly: AssemblyVersion("0.7.6.*")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
@@ -1,33 +0,0 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("OpenSim.ConsoleClient")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("http://opensimulator.org")]
|
||||
[assembly: AssemblyProduct("OpenSim")]
|
||||
[assembly: AssemblyCopyright("OpenSimulator developers")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("8945df94-2e5e-475b-88fa-35a7cdde6fd7")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
[assembly: AssemblyVersion("0.7.6.*")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
@@ -44,6 +44,7 @@ namespace OpenSim.ConsoleClient
|
||||
ReplyDelegate action)
|
||||
{
|
||||
WebRequest request = WebRequest.Create(requestUrl);
|
||||
WebResponse response = null;
|
||||
|
||||
request.Method = "POST";
|
||||
|
||||
@@ -63,18 +64,16 @@ namespace OpenSim.ConsoleClient
|
||||
{
|
||||
string reply = String.Empty;
|
||||
|
||||
using (WebResponse response = request.EndGetResponse(ar))
|
||||
{
|
||||
try
|
||||
{
|
||||
using (Stream s = response.GetResponseStream())
|
||||
using (StreamReader r = new StreamReader(s))
|
||||
reply = r.ReadToEnd();
|
||||
response = request.EndGetResponse(ar);
|
||||
|
||||
}
|
||||
catch (System.InvalidOperationException)
|
||||
{
|
||||
}
|
||||
try
|
||||
{
|
||||
StreamReader r = new StreamReader(response.GetResponseStream());
|
||||
reply = r.ReadToEnd();
|
||||
|
||||
}
|
||||
catch (System.InvalidOperationException)
|
||||
{
|
||||
}
|
||||
|
||||
action(requestUrl, data, reply);
|
||||
|
||||
@@ -50,7 +50,6 @@ namespace OpenSim.Data
|
||||
public interface IGridUserData
|
||||
{
|
||||
GridUserData Get(string userID);
|
||||
GridUserData[] GetAll(string query);
|
||||
bool Store(GridUserData data);
|
||||
}
|
||||
}
|
||||
@@ -1,144 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using OpenSim.Data;
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace OpenSim.Data
|
||||
{
|
||||
public class GroupData
|
||||
{
|
||||
public UUID GroupID;
|
||||
public Dictionary<string, string> Data;
|
||||
}
|
||||
|
||||
public class MembershipData
|
||||
{
|
||||
public UUID GroupID;
|
||||
public string PrincipalID;
|
||||
public Dictionary<string, string> Data;
|
||||
}
|
||||
|
||||
public class RoleData
|
||||
{
|
||||
public UUID GroupID;
|
||||
public UUID RoleID;
|
||||
public Dictionary<string, string> Data;
|
||||
}
|
||||
|
||||
public class RoleMembershipData
|
||||
{
|
||||
public UUID GroupID;
|
||||
public UUID RoleID;
|
||||
public string PrincipalID;
|
||||
}
|
||||
|
||||
public class PrincipalData
|
||||
{
|
||||
public string PrincipalID;
|
||||
public UUID ActiveGroupID;
|
||||
}
|
||||
|
||||
public class InvitationData
|
||||
{
|
||||
public UUID InviteID;
|
||||
public UUID GroupID;
|
||||
public UUID RoleID;
|
||||
public string PrincipalID;
|
||||
public Dictionary<string, string> Data;
|
||||
}
|
||||
|
||||
public class NoticeData
|
||||
{
|
||||
public UUID GroupID;
|
||||
public UUID NoticeID;
|
||||
public Dictionary<string, string> Data;
|
||||
}
|
||||
|
||||
|
||||
public interface IGroupsData
|
||||
{
|
||||
// groups table
|
||||
bool StoreGroup(GroupData data);
|
||||
GroupData RetrieveGroup(UUID groupID);
|
||||
GroupData RetrieveGroup(string name);
|
||||
GroupData[] RetrieveGroups(string pattern);
|
||||
bool DeleteGroup(UUID groupID);
|
||||
int GroupsCount();
|
||||
|
||||
// membership table
|
||||
MembershipData RetrieveMember(UUID groupID, string pricipalID);
|
||||
MembershipData[] RetrieveMembers(UUID groupID);
|
||||
MembershipData[] RetrieveMemberships(string pricipalID);
|
||||
bool StoreMember(MembershipData data);
|
||||
bool DeleteMember(UUID groupID, string pricipalID);
|
||||
int MemberCount(UUID groupID);
|
||||
|
||||
// roles table
|
||||
bool StoreRole(RoleData data);
|
||||
RoleData RetrieveRole(UUID groupID, UUID roleID);
|
||||
RoleData[] RetrieveRoles(UUID groupID);
|
||||
bool DeleteRole(UUID groupID, UUID roleID);
|
||||
int RoleCount(UUID groupID);
|
||||
|
||||
// rolememberhip table
|
||||
RoleMembershipData[] RetrieveRolesMembers(UUID groupID);
|
||||
RoleMembershipData[] RetrieveRoleMembers(UUID groupID, UUID roleID);
|
||||
RoleMembershipData[] RetrieveMemberRoles(UUID groupID, string principalID);
|
||||
RoleMembershipData RetrieveRoleMember(UUID groupID, UUID roleID, string principalID);
|
||||
int RoleMemberCount(UUID groupID, UUID roleID);
|
||||
bool StoreRoleMember(RoleMembershipData data);
|
||||
bool DeleteRoleMember(RoleMembershipData data);
|
||||
bool DeleteMemberAllRoles(UUID groupID, string principalID);
|
||||
|
||||
// principals table
|
||||
bool StorePrincipal(PrincipalData data);
|
||||
PrincipalData RetrievePrincipal(string principalID);
|
||||
bool DeletePrincipal(string principalID);
|
||||
|
||||
// invites table
|
||||
bool StoreInvitation(InvitationData data);
|
||||
InvitationData RetrieveInvitation(UUID inviteID);
|
||||
InvitationData RetrieveInvitation(UUID groupID, string principalID);
|
||||
bool DeleteInvite(UUID inviteID);
|
||||
void DeleteOldInvites();
|
||||
|
||||
// notices table
|
||||
bool StoreNotice(NoticeData data);
|
||||
NoticeData RetrieveNotice(UUID noticeID);
|
||||
NoticeData[] RetrieveNotices(UUID groupID);
|
||||
bool DeleteNotice(UUID noticeID);
|
||||
void DeleteOldNotices();
|
||||
|
||||
// combinations
|
||||
MembershipData RetrievePrincipalGroupMembership(string principalID, UUID groupID);
|
||||
MembershipData[] RetrievePrincipalGroupMemberships(string principalID);
|
||||
|
||||
// Misc
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using OpenSim.Data;
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace OpenSim.Data
|
||||
{
|
||||
public class OfflineIMData
|
||||
{
|
||||
public UUID PrincipalID;
|
||||
public UUID FromID;
|
||||
public Dictionary<string, string> Data;
|
||||
}
|
||||
|
||||
|
||||
public interface IOfflineIMData
|
||||
{
|
||||
OfflineIMData[] Get(string field, string val);
|
||||
long GetCount(string field, string key);
|
||||
bool Store(OfflineIMData data);
|
||||
bool Delete(string field, string val);
|
||||
void DeleteOld();
|
||||
}
|
||||
}
|
||||
@@ -53,6 +53,5 @@ namespace OpenSim.Data
|
||||
bool ReportAgent(UUID sessionID, UUID regionID);
|
||||
PresenceData[] Get(string field, string data);
|
||||
bool Delete(string field, string val);
|
||||
bool VerifyAgent(UUID agentId, UUID secureSessionID);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using OpenMetaverse;
|
||||
using OpenMetaverse.StructuredData;
|
||||
using OpenSim.Framework;
|
||||
|
||||
namespace OpenSim.Data
|
||||
{
|
||||
|
||||
public interface IProfilesData
|
||||
{
|
||||
OSDArray GetClassifiedRecords(UUID creatorId);
|
||||
bool UpdateClassifiedRecord(UserClassifiedAdd ad, ref string result);
|
||||
bool DeleteClassifiedRecord(UUID recordId);
|
||||
OSDArray GetAvatarPicks(UUID avatarId);
|
||||
UserProfilePick GetPickInfo(UUID avatarId, UUID pickId);
|
||||
bool UpdatePicksRecord(UserProfilePick pick);
|
||||
bool DeletePicksRecord(UUID pickId);
|
||||
bool GetAvatarNotes(ref UserProfileNotes note);
|
||||
bool UpdateAvatarNotes(ref UserProfileNotes note, ref string result);
|
||||
bool GetAvatarProperties(ref UserProfileProperties props, ref string result);
|
||||
bool UpdateAvatarProperties(ref UserProfileProperties props, ref string result);
|
||||
bool UpdateAvatarInterests(UserProfileProperties up, ref string result);
|
||||
bool GetClassifiedInfo(ref UserClassifiedAdd ad, ref string result);
|
||||
bool UpdateUserPreferences(ref UserPreferences pref, ref string result);
|
||||
bool GetUserPreferences(ref UserPreferences pref, ref string result);
|
||||
bool GetUserAppData(ref UserAppData props, ref string result);
|
||||
bool SetUserAppData(UserAppData props, ref string result);
|
||||
OSDArray GetUserImageAssets(UUID avatarId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,12 +54,12 @@ namespace OpenSim.Data
|
||||
/// <summary>
|
||||
/// Return the x-coordinate of this region.
|
||||
/// </summary>
|
||||
public int coordX { get { return (int)Util.WorldToRegionLoc((uint)posX); } }
|
||||
public int coordX { get { return posX / (int)Constants.RegionSize; } }
|
||||
|
||||
/// <summary>
|
||||
/// Return the y-coordinate of this region.
|
||||
/// </summary>
|
||||
public int coordY { get { return (int)Util.WorldToRegionLoc((uint)posY); } }
|
||||
public int coordY { get { return posY / (int)Constants.RegionSize; } }
|
||||
|
||||
public Dictionary<string, object> Data;
|
||||
}
|
||||
@@ -81,11 +81,25 @@ namespace OpenSim.Data
|
||||
bool Delete(UUID regionID);
|
||||
|
||||
List<RegionData> GetDefaultRegions(UUID scopeID);
|
||||
List<RegionData> GetDefaultHypergridRegions(UUID scopeID);
|
||||
List<RegionData> GetFallbackRegions(UUID scopeID, int x, int y);
|
||||
List<RegionData> GetHyperlinks(UUID scopeID);
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum RegionFlags : int
|
||||
{
|
||||
DefaultRegion = 1, // Used for new Rez. Random if multiple defined
|
||||
FallbackRegion = 2, // Regions we redirect to when the destination is down
|
||||
RegionOnline = 4, // Set when a region comes online, unset when it unregisters and DeleteOnUnregister is false
|
||||
NoDirectLogin = 8, // Region unavailable for direct logins (by name)
|
||||
Persistent = 16, // Don't remove on unregister
|
||||
LockedOut = 32, // Don't allow registration
|
||||
NoMove = 64, // Don't allow moving this region
|
||||
Reservation = 128, // This is an inactive reservation
|
||||
Authenticate = 256, // Require authentication
|
||||
Hyperlink = 512 // Record represents a HG link
|
||||
}
|
||||
|
||||
public class RegionDataDistanceCompare : IComparer<RegionData>
|
||||
{
|
||||
private Vector2 m_origin;
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
|
||||
namespace OpenSim.Data
|
||||
{
|
||||
/// <summary>
|
||||
/// This interface exists to distinguish between the normal IAssetDataPlugin and the one used by XAssetService
|
||||
/// for now.
|
||||
/// </summary>
|
||||
public interface IXAssetDataPlugin : IPlugin
|
||||
{
|
||||
AssetBase GetAsset(UUID uuid);
|
||||
void StoreAsset(AssetBase asset);
|
||||
bool ExistsAsset(UUID uuid);
|
||||
List<AssetMetadata> FetchAssetMetadataSet(int start, int count);
|
||||
void Initialise(string connect);
|
||||
bool Delete(string id);
|
||||
}
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
|
||||
namespace OpenSim.Data
|
||||
{
|
||||
public class XGroup
|
||||
{
|
||||
public UUID groupID;
|
||||
public UUID ownerRoleID;
|
||||
public string name;
|
||||
public string charter;
|
||||
public bool showInList;
|
||||
public UUID insigniaID;
|
||||
public int membershipFee;
|
||||
public bool openEnrollment;
|
||||
public bool allowPublish;
|
||||
public bool maturePublish;
|
||||
public UUID founderID;
|
||||
public ulong everyonePowers;
|
||||
public ulong ownersPowers;
|
||||
|
||||
public XGroup Clone()
|
||||
{
|
||||
return (XGroup)MemberwiseClone();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Early stub interface for groups data, not final.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Currently in-use only for regression test purposes. Needs to be filled out over time.
|
||||
/// </remarks>
|
||||
public interface IXGroupData
|
||||
{
|
||||
bool StoreGroup(XGroup group);
|
||||
XGroup[] GetGroups(string field, string val);
|
||||
XGroup[] GetGroups(string[] fields, string[] vals);
|
||||
bool DeleteGroups(string field, string val);
|
||||
bool DeleteGroups(string[] fields, string[] vals);
|
||||
}
|
||||
}
|
||||
@@ -40,11 +40,6 @@ namespace OpenSim.Data
|
||||
public UUID folderID;
|
||||
public UUID agentID;
|
||||
public UUID parentFolderID;
|
||||
|
||||
public XInventoryFolder Clone()
|
||||
{
|
||||
return (XInventoryFolder)MemberwiseClone();
|
||||
}
|
||||
}
|
||||
|
||||
public class XInventoryItem
|
||||
@@ -69,11 +64,6 @@ namespace OpenSim.Data
|
||||
public UUID avatarID;
|
||||
public UUID parentFolderID;
|
||||
public int inventoryGroupPermissions;
|
||||
|
||||
public XInventoryItem Clone()
|
||||
{
|
||||
return (XInventoryItem)MemberwiseClone();
|
||||
}
|
||||
}
|
||||
|
||||
public interface IXInventoryData
|
||||
@@ -116,22 +106,7 @@ namespace OpenSim.Data
|
||||
/// <returns>true if the delete was successful, false if it was not</returns>
|
||||
bool DeleteItems(string[] fields, string[] vals);
|
||||
|
||||
/// <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);
|
||||
|
||||
bool MoveItem(string id, string newParent);
|
||||
XInventoryItem[] GetActiveGestures(UUID principalID);
|
||||
int GetAssetPermissions(UUID principalID, UUID assetID);
|
||||
}
|
||||
|
||||
@@ -163,18 +163,14 @@ namespace OpenSim.Data.MSSQL
|
||||
if (asset.Name.Length > 64)
|
||||
{
|
||||
assetName = asset.Name.Substring(0, 64);
|
||||
m_log.WarnFormat(
|
||||
"[ASSET DB]: Name '{0}' for asset {1} truncated from {2} to {3} characters on add",
|
||||
asset.Name, asset.ID, asset.Name.Length, assetName.Length);
|
||||
m_log.Warn("[ASSET DB]: Name field truncated from " + asset.Name.Length + " to " + assetName.Length + " characters on add");
|
||||
}
|
||||
|
||||
string assetDescription = asset.Description;
|
||||
if (asset.Description.Length > 64)
|
||||
{
|
||||
assetDescription = asset.Description.Substring(0, 64);
|
||||
m_log.WarnFormat(
|
||||
"[ASSET DB]: Description '{0}' for asset {1} truncated from {2} to {3} characters on add",
|
||||
asset.Description, asset.ID, asset.Description.Length, assetDescription.Length);
|
||||
m_log.Warn("[ASSET DB]: Description field truncated from " + asset.Description.Length + " to " + assetDescription.Length + " characters on add");
|
||||
}
|
||||
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace OpenSim.Data.MSSQL
|
||||
{
|
||||
}
|
||||
|
||||
public new GridUserData Get(string userID)
|
||||
public GridUserData Get(string userID)
|
||||
{
|
||||
GridUserData[] ret = Get("UserID", userID);
|
||||
|
||||
@@ -60,10 +60,5 @@ namespace OpenSim.Data.MSSQL
|
||||
return ret[0];
|
||||
}
|
||||
|
||||
public GridUserData[] GetAll(string userID)
|
||||
{
|
||||
return base.Get(String.Format("UserID LIKE '{0}%'", userID));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,11 +104,6 @@ namespace OpenSim.Data.MSSQL
|
||||
{
|
||||
return SqlDbType.BigInt;
|
||||
}
|
||||
if (type == typeof(DateTime))
|
||||
{
|
||||
return SqlDbType.DateTime;
|
||||
}
|
||||
|
||||
return SqlDbType.VarChar;
|
||||
}
|
||||
|
||||
|
||||
@@ -100,18 +100,5 @@ namespace OpenSim.Data.MSSQL
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool VerifyAgent(UUID agentId, UUID secureSessionID)
|
||||
{
|
||||
PresenceData[] ret = Get("SecureSessionID",
|
||||
secureSessionID.ToString());
|
||||
|
||||
if (ret.Length == 0)
|
||||
return false;
|
||||
|
||||
if(ret[0].UserID != agentId.ToString())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,6 @@ using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using RegionFlags = OpenSim.Framework.RegionFlags;
|
||||
|
||||
namespace OpenSim.Data.MSSQL
|
||||
{
|
||||
@@ -315,11 +314,6 @@ namespace OpenSim.Data.MSSQL
|
||||
return Get((int)RegionFlags.DefaultRegion, scopeID);
|
||||
}
|
||||
|
||||
public List<RegionData> GetDefaultHypergridRegions(UUID scopeID)
|
||||
{
|
||||
return Get((int)RegionFlags.DefaultHGRegion, scopeID);
|
||||
}
|
||||
|
||||
public List<RegionData> GetFallbackRegions(UUID scopeID, int x, int y)
|
||||
{
|
||||
List<RegionData> regions = Get((int)RegionFlags.FallbackRegion, scopeID);
|
||||
|
||||
@@ -49,7 +49,6 @@ namespace OpenSim.Data.MSSQL
|
||||
|
||||
// private static FileSystemDataStore Instance = new FileSystemDataStore();
|
||||
private static readonly ILog _Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
private static string LogHeader = "[REGION DB MSSQL]";
|
||||
|
||||
/// <summary>
|
||||
/// The database manager
|
||||
@@ -352,8 +351,7 @@ IF EXISTS (SELECT UUID FROM prims WHERE UUID = @UUID)
|
||||
ScriptAccessPin = @ScriptAccessPin, AllowedDrop = @AllowedDrop, DieAtEdge = @DieAtEdge, SalePrice = @SalePrice,
|
||||
SaleType = @SaleType, ColorR = @ColorR, ColorG = @ColorG, ColorB = @ColorB, ColorA = @ColorA, ParticleSystem = @ParticleSystem,
|
||||
ClickAction = @ClickAction, Material = @Material, CollisionSound = @CollisionSound, CollisionSoundVolume = @CollisionSoundVolume, PassTouches = @PassTouches,
|
||||
LinkNumber = @LinkNumber, MediaURL = @MediaURL, AttachedPosX = @AttachedPosX, AttachedPosY = @AttachedPosY, AttachedPosZ = @AttachedPosZ, DynAttrs = @DynAttrs,
|
||||
PhysicsShapeType = @PhysicsShapeType, Density = @Density, GravityModifier = @GravityModifier, Friction = @Friction, Restitution = @Restitution
|
||||
LinkNumber = @LinkNumber, MediaURL = @MediaURL
|
||||
WHERE UUID = @UUID
|
||||
END
|
||||
ELSE
|
||||
@@ -368,8 +366,7 @@ ELSE
|
||||
PayPrice, PayButton1, PayButton2, PayButton3, PayButton4, LoopedSound, LoopedSoundGain, TextureAnimation, OmegaX,
|
||||
OmegaY, OmegaZ, CameraEyeOffsetX, CameraEyeOffsetY, CameraEyeOffsetZ, CameraAtOffsetX, CameraAtOffsetY, CameraAtOffsetZ,
|
||||
ForceMouselook, ScriptAccessPin, AllowedDrop, DieAtEdge, SalePrice, SaleType, ColorR, ColorG, ColorB, ColorA,
|
||||
ParticleSystem, ClickAction, Material, CollisionSound, CollisionSoundVolume, PassTouches, LinkNumber, MediaURL, AttachedPosX, AttachedPosY, AttachedPosZ, DynAttrs,
|
||||
PhysicsShapeType, Density, GravityModifier, Friction, Restitution
|
||||
ParticleSystem, ClickAction, Material, CollisionSound, CollisionSoundVolume, PassTouches, LinkNumber, MediaURL
|
||||
) VALUES (
|
||||
@UUID, @CreationDate, @Name, @Text, @Description, @SitName, @TouchName, @ObjectFlags, @OwnerMask, @NextOwnerMask, @GroupMask,
|
||||
@EveryoneMask, @BaseMask, @PositionX, @PositionY, @PositionZ, @GroupPositionX, @GroupPositionY, @GroupPositionZ, @VelocityX,
|
||||
@@ -379,8 +376,7 @@ ELSE
|
||||
@PayPrice, @PayButton1, @PayButton2, @PayButton3, @PayButton4, @LoopedSound, @LoopedSoundGain, @TextureAnimation, @OmegaX,
|
||||
@OmegaY, @OmegaZ, @CameraEyeOffsetX, @CameraEyeOffsetY, @CameraEyeOffsetZ, @CameraAtOffsetX, @CameraAtOffsetY, @CameraAtOffsetZ,
|
||||
@ForceMouselook, @ScriptAccessPin, @AllowedDrop, @DieAtEdge, @SalePrice, @SaleType, @ColorR, @ColorG, @ColorB, @ColorA,
|
||||
@ParticleSystem, @ClickAction, @Material, @CollisionSound, @CollisionSoundVolume, @PassTouches, @LinkNumber, @MediaURL, @AttachedPosX, @AttachedPosY, @AttachedPosZ, @DynAttrs,
|
||||
@PhysicsShapeType, @Density, @GravityModifier, @Friction, @Restitution
|
||||
@ParticleSystem, @ClickAction, @Material, @CollisionSound, @CollisionSoundVolume, @PassTouches, @LinkNumber, @MediaURL
|
||||
)
|
||||
END";
|
||||
|
||||
@@ -531,53 +527,43 @@ ELSE
|
||||
/// <returns></returns>
|
||||
public double[,] LoadTerrain(UUID regionID)
|
||||
{
|
||||
double[,] ret = null;
|
||||
TerrainData terrData = LoadTerrain(regionID, (int)Constants.RegionSize, (int)Constants.RegionSize, (int)Constants.RegionHeight);
|
||||
if (terrData != null)
|
||||
ret = terrData.GetDoubles();
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Returns 'null' if region not found
|
||||
public TerrainData LoadTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ)
|
||||
{
|
||||
TerrainData terrData = null;
|
||||
double[,] terrain = new double[(int)Constants.RegionSize, (int)Constants.RegionSize];
|
||||
terrain.Initialize();
|
||||
|
||||
string sql = "select top 1 RegionUUID, Revision, Heightfield from terrain where RegionUUID = @RegionUUID order by Revision desc";
|
||||
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
// MySqlParameter param = new MySqlParameter();
|
||||
cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", regionID));
|
||||
conn.Open();
|
||||
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
// MySqlParameter param = new MySqlParameter();
|
||||
cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", regionID));
|
||||
conn.Open();
|
||||
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||
int rev;
|
||||
if (reader.Read())
|
||||
{
|
||||
int rev;
|
||||
if (reader.Read())
|
||||
MemoryStream str = new MemoryStream((byte[])reader["Heightfield"]);
|
||||
BinaryReader br = new BinaryReader(str);
|
||||
for (int x = 0; x < (int)Constants.RegionSize; x++)
|
||||
{
|
||||
rev = (int)reader["Revision"];
|
||||
byte[] blob = (byte[])reader["Heightfield"];
|
||||
terrData = TerrainData.CreateFromDatabaseBlobFactory(pSizeX, pSizeY, pSizeZ, rev, blob);
|
||||
for (int y = 0; y < (int)Constants.RegionSize; y++)
|
||||
{
|
||||
terrain[x, y] = br.ReadDouble();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_Log.Info("[REGION DB]: No terrain found for region");
|
||||
return null;
|
||||
}
|
||||
_Log.Info("[REGION DB]: Loaded terrain revision r" + rev);
|
||||
rev = (int)reader["Revision"];
|
||||
}
|
||||
else
|
||||
{
|
||||
_Log.Info("[REGION DB]: No terrain found for region");
|
||||
return null;
|
||||
}
|
||||
_Log.Info("[REGION DB]: Loaded terrain revision r" + rev);
|
||||
}
|
||||
}
|
||||
|
||||
return terrData;
|
||||
}
|
||||
|
||||
// Legacy entry point for when terrain was always a 256x256 hieghtmap
|
||||
public void StoreTerrain(double[,] ter, UUID regionID)
|
||||
{
|
||||
StoreTerrain(new HeightmapTerrainData(ter), regionID);
|
||||
return terrain;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -585,8 +571,10 @@ ELSE
|
||||
/// </summary>
|
||||
/// <param name="terrain">terrain map data.</param>
|
||||
/// <param name="regionID">regionID.</param>
|
||||
public void StoreTerrain(TerrainData terrData, UUID regionID)
|
||||
public void StoreTerrain(double[,] terrain, UUID regionID)
|
||||
{
|
||||
int revision = Util.UnixTimeSinceEpoch();
|
||||
|
||||
//Delete old terrain map
|
||||
string sql = "delete from terrain where RegionUUID=@RegionUUID";
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
@@ -599,23 +587,17 @@ ELSE
|
||||
|
||||
sql = "insert into terrain(RegionUUID, Revision, Heightfield) values(@RegionUUID, @Revision, @Heightfield)";
|
||||
|
||||
int terrainDBRevision;
|
||||
Array terrainDBblob;
|
||||
terrData.GetDatabaseBlob(out terrainDBRevision, out terrainDBblob);
|
||||
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", regionID));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("@Revision", terrainDBRevision));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("@Heightfield", terrainDBblob));
|
||||
conn.Open();
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", regionID));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("@Revision", revision));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("@Heightfield", serializeTerrain(terrain)));
|
||||
conn.Open();
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
_Log.InfoFormat("{0} Stored terrain revision r={1}", LogHeader, terrainDBRevision);
|
||||
_Log.Info("[REGION DB]: Stored terrain revision r " + revision);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1199,72 +1181,6 @@ VALUES
|
||||
// }
|
||||
#endregion
|
||||
}
|
||||
|
||||
#region Environment Settings
|
||||
public string LoadRegionEnvironmentSettings(UUID regionUUID)
|
||||
{
|
||||
string sql = "select * from [regionenvironment] where region_id = @region_id";
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.Add(_Database.CreateParameter("@region_id", regionUUID));
|
||||
conn.Open();
|
||||
using (SqlDataReader result = cmd.ExecuteReader())
|
||||
{
|
||||
if (!result.Read())
|
||||
{
|
||||
return String.Empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Convert.ToString(result["llsd_settings"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void StoreRegionEnvironmentSettings(UUID regionUUID, string settings)
|
||||
{
|
||||
{
|
||||
string sql = "DELETE FROM [regionenvironment] WHERE region_id = @region_id";
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.Add(_Database.CreateParameter("@region_id", regionUUID));
|
||||
conn.Open();
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
sql = "INSERT INTO [regionenvironment] (region_id, llsd_settings) VALUES (@region_id, @llsd_settings)";
|
||||
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.Add(_Database.CreateParameter("@region_id", regionUUID));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("@llsd_settings", settings));
|
||||
|
||||
conn.Open();
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveRegionEnvironmentSettings(UUID regionUUID)
|
||||
{
|
||||
string sql = "delete from [regionenvironment] where region_id = @region_id";
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.Add(_Database.CreateParameter("@region_id", regionUUID));
|
||||
|
||||
conn.Open();
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Loads the settings of a region.
|
||||
/// </summary>
|
||||
@@ -1359,6 +1275,30 @@ VALUES
|
||||
|
||||
#region Private Methods
|
||||
|
||||
/// <summary>
|
||||
/// Serializes the terrain data for storage in DB.
|
||||
/// </summary>
|
||||
/// <param name="val">terrain data</param>
|
||||
/// <returns></returns>
|
||||
private static Array serializeTerrain(double[,] val)
|
||||
{
|
||||
MemoryStream str = new MemoryStream(((int)Constants.RegionSize * (int)Constants.RegionSize) * sizeof(double));
|
||||
BinaryWriter bw = new BinaryWriter(str);
|
||||
|
||||
// TODO: COMPATIBILITY - Add byte-order conversions
|
||||
for (int x = 0; x < (int)Constants.RegionSize; x++)
|
||||
for (int y = 0; y < (int)Constants.RegionSize; y++)
|
||||
{
|
||||
double height = val[x, y];
|
||||
if (height == 0.0)
|
||||
height = double.Epsilon;
|
||||
|
||||
bw.Write(height);
|
||||
}
|
||||
|
||||
return str.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stores new regionsettings.
|
||||
/// </summary>
|
||||
@@ -1430,7 +1370,7 @@ VALUES
|
||||
newSettings.TerrainRaiseLimit = Convert.ToDouble(row["terrain_raise_limit"]);
|
||||
newSettings.TerrainLowerLimit = Convert.ToDouble(row["terrain_lower_limit"]);
|
||||
newSettings.UseEstateSun = Convert.ToBoolean(row["use_estate_sun"]);
|
||||
newSettings.Sandbox = Convert.ToBoolean(row["Sandbox"]);
|
||||
newSettings.Sandbox = Convert.ToBoolean(row["sandbox"]);
|
||||
newSettings.FixedSun = Convert.ToBoolean(row["fixed_sun"]);
|
||||
newSettings.SunPosition = Convert.ToDouble(row["sun_position"]);
|
||||
newSettings.SunVector = new Vector3(
|
||||
@@ -1685,23 +1625,6 @@ VALUES
|
||||
|
||||
if (!(primRow["MediaURL"] is System.DBNull))
|
||||
prim.MediaUrl = (string)primRow["MediaURL"];
|
||||
|
||||
if (!(primRow["AttachedPosX"] is System.DBNull))
|
||||
prim.AttachedPos = new Vector3(
|
||||
Convert.ToSingle(primRow["AttachedPosX"]),
|
||||
Convert.ToSingle(primRow["AttachedPosY"]),
|
||||
Convert.ToSingle(primRow["AttachedPosZ"]));
|
||||
|
||||
if (!(primRow["DynAttrs"] is System.DBNull))
|
||||
prim.DynAttrs = DAMap.FromXml((string)primRow["DynAttrs"]);
|
||||
else
|
||||
prim.DynAttrs = new DAMap();
|
||||
|
||||
prim.PhysicsShapeType = Convert.ToByte(primRow["PhysicsShapeType"]);
|
||||
prim.Density = Convert.ToSingle(primRow["Density"]);
|
||||
prim.GravityModifier = Convert.ToSingle(primRow["GravityModifier"]);
|
||||
prim.Friction = Convert.ToSingle(primRow["Friction"]);
|
||||
prim.Restitution = Convert.ToSingle(primRow["Restitution"]);
|
||||
|
||||
return prim;
|
||||
}
|
||||
@@ -1760,6 +1683,7 @@ VALUES
|
||||
baseShape.Media = PrimitiveBaseShape.MediaList.FromXml((string)shapeRow["Media"]);
|
||||
}
|
||||
|
||||
|
||||
return baseShape;
|
||||
}
|
||||
|
||||
@@ -1875,7 +1799,7 @@ VALUES
|
||||
parameters.Add(_Database.CreateParameter("terrain_raise_limit", settings.TerrainRaiseLimit));
|
||||
parameters.Add(_Database.CreateParameter("terrain_lower_limit", settings.TerrainLowerLimit));
|
||||
parameters.Add(_Database.CreateParameter("use_estate_sun", settings.UseEstateSun));
|
||||
parameters.Add(_Database.CreateParameter("Sandbox", settings.Sandbox));
|
||||
parameters.Add(_Database.CreateParameter("sandbox", settings.Sandbox));
|
||||
parameters.Add(_Database.CreateParameter("fixed_sun", settings.FixedSun));
|
||||
parameters.Add(_Database.CreateParameter("sun_position", settings.SunPosition));
|
||||
parameters.Add(_Database.CreateParameter("sunvectorx", settings.SunVector.X));
|
||||
@@ -2096,20 +2020,6 @@ VALUES
|
||||
parameters.Add(_Database.CreateParameter("PassTouches", 0));
|
||||
parameters.Add(_Database.CreateParameter("LinkNumber", prim.LinkNum));
|
||||
parameters.Add(_Database.CreateParameter("MediaURL", prim.MediaUrl));
|
||||
parameters.Add(_Database.CreateParameter("AttachedPosX", prim.AttachedPos.X));
|
||||
parameters.Add(_Database.CreateParameter("AttachedPosY", prim.AttachedPos.Y));
|
||||
parameters.Add(_Database.CreateParameter("AttachedPosZ", prim.AttachedPos.Z));
|
||||
|
||||
if (prim.DynAttrs.CountNamespaces > 0)
|
||||
parameters.Add(_Database.CreateParameter("DynAttrs", prim.DynAttrs.ToXml()));
|
||||
else
|
||||
parameters.Add(_Database.CreateParameter("DynAttrs", null));
|
||||
|
||||
parameters.Add(_Database.CreateParameter("PhysicsShapeType", prim.PhysicsShapeType));
|
||||
parameters.Add(_Database.CreateParameter("Density", (double)prim.Density));
|
||||
parameters.Add(_Database.CreateParameter("GravityModifier", (double)prim.GravityModifier));
|
||||
parameters.Add(_Database.CreateParameter("Friction", (double)prim.Friction));
|
||||
parameters.Add(_Database.CreateParameter("Restitution", (double)prim.Restitution));
|
||||
|
||||
return parameters.ToArray();
|
||||
}
|
||||
@@ -2167,6 +2077,7 @@ VALUES
|
||||
parameters.Add(_Database.CreateParameter("Media", s.Media.ToXml()));
|
||||
}
|
||||
|
||||
|
||||
return parameters.ToArray();
|
||||
}
|
||||
|
||||
@@ -2225,18 +2136,5 @@ VALUES
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SaveExtra(UUID regionID, string name, string value)
|
||||
{
|
||||
}
|
||||
|
||||
public void RemoveExtra(UUID regionID, string name)
|
||||
{
|
||||
}
|
||||
|
||||
public Dictionary<string, string> GetExtra(UUID regionID)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,12 +43,12 @@ namespace OpenSim.Data.MSSQL
|
||||
// private static readonly ILog m_log = LogManager.GetLogger(
|
||||
// MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private MSSQLFolderHandler m_Folders;
|
||||
private MSSQLGenericTableHandler<XInventoryFolder> m_Folders;
|
||||
private MSSQLItemHandler m_Items;
|
||||
|
||||
public MSSQLXInventoryData(string conn, string realm)
|
||||
{
|
||||
m_Folders = new MSSQLFolderHandler(
|
||||
m_Folders = new MSSQLGenericTableHandler<XInventoryFolder>(
|
||||
conn, "inventoryfolders", "InventoryStore");
|
||||
m_Items = new MSSQLItemHandler(
|
||||
conn, "inventoryitems", String.Empty);
|
||||
@@ -85,7 +85,6 @@ namespace OpenSim.Data.MSSQL
|
||||
{
|
||||
return m_Folders.Delete(field, val);
|
||||
}
|
||||
|
||||
public bool DeleteFolders(string[] fields, string[] vals)
|
||||
{
|
||||
return m_Folders.Delete(fields, vals);
|
||||
@@ -95,22 +94,15 @@ 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);
|
||||
@@ -122,7 +114,7 @@ namespace OpenSim.Data.MSSQL
|
||||
}
|
||||
}
|
||||
|
||||
public class MSSQLItemHandler : MSSQLInventoryHandler<XInventoryItem>
|
||||
public class MSSQLItemHandler : MSSQLGenericTableHandler<XInventoryItem>
|
||||
{
|
||||
public MSSQLItemHandler(string c, string t, string m) :
|
||||
base(c, t, m)
|
||||
@@ -131,163 +123,70 @@ namespace OpenSim.Data.MSSQL
|
||||
|
||||
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 (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();
|
||||
|
||||
if (cmd.ExecuteNonQuery() == 0)
|
||||
return false;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
IncrementFolderVersion(oldParent);
|
||||
IncrementFolderVersion(newParent);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public XInventoryItem[] GetActiveGestures(UUID principalID)
|
||||
{
|
||||
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||
using (SqlCommand cmd = new SqlCommand())
|
||||
{
|
||||
using (SqlCommand cmd = new SqlCommand())
|
||||
{
|
||||
cmd.CommandText = String.Format("select * from inventoryitems where avatarId = @uuid and assetType = @type and flags = 1", m_Realm);
|
||||
cmd.CommandText = String.Format("select * from inventoryitems where avatarId = @uuid and assetType = @type and flags = 1", m_Realm);
|
||||
|
||||
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())
|
||||
{
|
||||
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())
|
||||
{
|
||||
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())
|
||||
|
||||
int perms = 0;
|
||||
|
||||
if (reader.Read())
|
||||
{
|
||||
|
||||
int perms = 0;
|
||||
|
||||
if (reader.Read())
|
||||
{
|
||||
perms = Convert.ToInt32(reader["inventoryCurrentPermissions"]);
|
||||
}
|
||||
|
||||
return perms;
|
||||
perms = Convert.ToInt32(reader["inventoryCurrentPermissions"]);
|
||||
}
|
||||
|
||||
return perms;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public override bool Store(XInventoryItem item)
|
||||
{
|
||||
if (!base.Store(item))
|
||||
return false;
|
||||
|
||||
IncrementFolderVersion(item.parentFolderID);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public class MSSQLFolderHandler : MSSQLInventoryHandler<XInventoryFolder>
|
||||
{
|
||||
public MSSQLFolderHandler(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;
|
||||
|
||||
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))
|
||||
{
|
||||
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();
|
||||
|
||||
if (cmd.ExecuteNonQuery() == 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;
|
||||
}
|
||||
}
|
||||
|
||||
public class MSSQLInventoryHandler<T> : MSSQLGenericTableHandler<T> where T: class, new()
|
||||
{
|
||||
public MSSQLInventoryHandler(string c, string t, string m) : base(c, t, m) {}
|
||||
|
||||
protected bool IncrementFolderVersion(UUID folderID)
|
||||
{
|
||||
return IncrementFolderVersion(folderID.ToString());
|
||||
}
|
||||
|
||||
protected bool IncrementFolderVersion(string folderID)
|
||||
{
|
||||
// m_log.DebugFormat("[MYSQL ITEM HANDLER]: Incrementing version on folder {0}", folderID);
|
||||
// Util.PrintCallStack();
|
||||
|
||||
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();
|
||||
|
||||
cmd.Parameters.AddWithValue("@folderID", folderID);
|
||||
conn.Open();
|
||||
|
||||
cmd.Parameters.AddWithValue("@folderID", item.parentFolderID.ToString());
|
||||
try
|
||||
{
|
||||
cmd.ExecuteNonQuery();
|
||||
@@ -295,11 +194,9 @@ namespace OpenSim.Data.MSSQL
|
||||
catch (Exception)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,5 +61,5 @@ using System.Runtime.InteropServices;
|
||||
// You can specify all the values or you can default the Revision and Build Numbers
|
||||
// by using the '*' as shown below:
|
||||
|
||||
[assembly : AssemblyVersion("0.8.0.*")]
|
||||
|
||||
[assembly : AssemblyVersion("0.6.5.*")]
|
||||
[assembly : AssemblyFileVersion("0.6.5.0")]
|
||||
|
||||
@@ -1134,49 +1134,3 @@ ALTER TABLE landaccesslist ADD Expires integer NOT NULL DEFAULT 0;
|
||||
|
||||
COMMIT
|
||||
|
||||
:VERSION 37 #---------------- Environment Settings
|
||||
|
||||
BEGIN TRANSACTION
|
||||
|
||||
CREATE TABLE [dbo].[regionenvironment](
|
||||
[region_id] [uniqueidentifier] NOT NULL,
|
||||
[llsd_settings] [varchar](max) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
|
||||
PRIMARY KEY CLUSTERED
|
||||
(
|
||||
[region_id] ASC
|
||||
)WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
|
||||
) ON [PRIMARY]
|
||||
|
||||
COMMIT
|
||||
|
||||
:VERSION 38 #---------------- Dynamic attributes
|
||||
|
||||
BEGIN TRANSACTION
|
||||
|
||||
ALTER TABLE prims ADD DynAttrs TEXT;
|
||||
|
||||
COMMIT
|
||||
|
||||
:VERSION 39 #---------------- Extra physics params
|
||||
|
||||
BEGIN TRANSACTION
|
||||
|
||||
ALTER TABLE prims ADD `PhysicsShapeType` tinyint(4) NOT NULL default '0';
|
||||
ALTER TABLE prims ADD `Density` double NOT NULL default '1000';
|
||||
ALTER TABLE prims ADD `GravityModifier` double NOT NULL default '1';
|
||||
ALTER TABLE prims ADD `Friction` double NOT NULL default '0.6';
|
||||
ALTER TABLE prims ADD `Restitution` double NOT NULL default '0.5';
|
||||
|
||||
COMMIT
|
||||
|
||||
:VERSION 40 #---------------- Save Attachment info
|
||||
|
||||
BEGIN TRANSACTION
|
||||
|
||||
ALTER TABLE prims ADD AttachedPosX float(53) default 0.0;
|
||||
ALTER TABLE prims ADD AttachedPosY float(53) default 0.0;
|
||||
ALTER TABLE prims ADD AttachedPosZ float(53) default 0.0;
|
||||
ALTER TABLE primshapes ADD LastAttachPoint int not null default 0;
|
||||
|
||||
COMMIT
|
||||
|
||||
|
||||
@@ -142,8 +142,7 @@ namespace OpenSim.Data.MySQL
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Error(
|
||||
string.Format("[ASSETS DB]: MySql failure fetching asset {0}. Exception ", assetID), e);
|
||||
m_log.Error("[ASSETS DB]: MySql failure fetching asset " + assetID + ": " + e.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -164,59 +163,53 @@ namespace OpenSim.Data.MySQL
|
||||
{
|
||||
dbcon.Open();
|
||||
|
||||
using (MySqlCommand cmd =
|
||||
MySqlCommand cmd =
|
||||
new MySqlCommand(
|
||||
"replace INTO assets(id, name, description, assetType, local, temporary, create_time, access_time, asset_flags, CreatorID, data)" +
|
||||
"VALUES(?id, ?name, ?description, ?assetType, ?local, ?temporary, ?create_time, ?access_time, ?asset_flags, ?CreatorID, ?data)",
|
||||
dbcon))
|
||||
dbcon);
|
||||
|
||||
string assetName = asset.Name;
|
||||
if (asset.Name.Length > 64)
|
||||
{
|
||||
string assetName = asset.Name;
|
||||
if (asset.Name.Length > 64)
|
||||
assetName = asset.Name.Substring(0, 64);
|
||||
m_log.Warn("[ASSET DB]: Name field truncated from " + asset.Name.Length + " to " + assetName.Length + " characters on add");
|
||||
}
|
||||
|
||||
string assetDescription = asset.Description;
|
||||
if (asset.Description.Length > 64)
|
||||
{
|
||||
assetDescription = asset.Description.Substring(0, 64);
|
||||
m_log.Warn("[ASSET DB]: Description field truncated from " + asset.Description.Length + " to " + assetDescription.Length + " characters on add");
|
||||
}
|
||||
|
||||
// need to ensure we dispose
|
||||
try
|
||||
{
|
||||
using (cmd)
|
||||
{
|
||||
assetName = asset.Name.Substring(0, 64);
|
||||
m_log.WarnFormat(
|
||||
"[ASSET DB]: Name '{0}' for asset {1} truncated from {2} to {3} characters on add",
|
||||
asset.Name, asset.ID, asset.Name.Length, assetName.Length);
|
||||
}
|
||||
|
||||
string assetDescription = asset.Description;
|
||||
if (asset.Description.Length > 64)
|
||||
{
|
||||
assetDescription = asset.Description.Substring(0, 64);
|
||||
m_log.WarnFormat(
|
||||
"[ASSET DB]: Description '{0}' for asset {1} truncated from {2} to {3} characters on add",
|
||||
asset.Description, asset.ID, asset.Description.Length, assetDescription.Length);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
using (cmd)
|
||||
{
|
||||
// create unix epoch time
|
||||
int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow);
|
||||
cmd.Parameters.AddWithValue("?id", asset.ID);
|
||||
cmd.Parameters.AddWithValue("?name", assetName);
|
||||
cmd.Parameters.AddWithValue("?description", assetDescription);
|
||||
cmd.Parameters.AddWithValue("?assetType", asset.Type);
|
||||
cmd.Parameters.AddWithValue("?local", asset.Local);
|
||||
cmd.Parameters.AddWithValue("?temporary", asset.Temporary);
|
||||
cmd.Parameters.AddWithValue("?create_time", now);
|
||||
cmd.Parameters.AddWithValue("?access_time", now);
|
||||
cmd.Parameters.AddWithValue("?CreatorID", asset.Metadata.CreatorID);
|
||||
cmd.Parameters.AddWithValue("?asset_flags", (int)asset.Flags);
|
||||
cmd.Parameters.AddWithValue("?data", asset.Data);
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Error(
|
||||
string.Format(
|
||||
"[ASSET DB]: MySQL failure creating asset {0} with name {1}. Exception ",
|
||||
asset.FullID, asset.Name)
|
||||
, e);
|
||||
// create unix epoch time
|
||||
int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow);
|
||||
cmd.Parameters.AddWithValue("?id", asset.ID);
|
||||
cmd.Parameters.AddWithValue("?name", assetName);
|
||||
cmd.Parameters.AddWithValue("?description", assetDescription);
|
||||
cmd.Parameters.AddWithValue("?assetType", asset.Type);
|
||||
cmd.Parameters.AddWithValue("?local", asset.Local);
|
||||
cmd.Parameters.AddWithValue("?temporary", asset.Temporary);
|
||||
cmd.Parameters.AddWithValue("?create_time", now);
|
||||
cmd.Parameters.AddWithValue("?access_time", now);
|
||||
cmd.Parameters.AddWithValue("?CreatorID", asset.Metadata.CreatorID);
|
||||
cmd.Parameters.AddWithValue("?asset_flags", (int)asset.Flags);
|
||||
cmd.Parameters.AddWithValue("?data", asset.Data);
|
||||
cmd.ExecuteNonQuery();
|
||||
cmd.Dispose();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat("[ASSET DB]: MySQL failure creating asset {0} with name \"{1}\". Error: {2}",
|
||||
asset.FullID, asset.Name, e.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -228,32 +221,33 @@ namespace OpenSim.Data.MySQL
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
dbcon.Open();
|
||||
MySqlCommand cmd =
|
||||
new MySqlCommand("update assets set access_time=?access_time where id=?id",
|
||||
dbcon);
|
||||
|
||||
using (MySqlCommand cmd
|
||||
= new MySqlCommand("update assets set access_time=?access_time where id=?id", dbcon))
|
||||
// need to ensure we dispose
|
||||
try
|
||||
{
|
||||
try
|
||||
using (cmd)
|
||||
{
|
||||
using (cmd)
|
||||
{
|
||||
// create unix epoch time
|
||||
int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow);
|
||||
cmd.Parameters.AddWithValue("?id", asset.ID);
|
||||
cmd.Parameters.AddWithValue("?access_time", now);
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Error(
|
||||
string.Format(
|
||||
"[ASSETS DB]: Failure updating access_time for asset {0} with name {1}. Exception ",
|
||||
asset.FullID, asset.Name),
|
||||
e);
|
||||
// create unix epoch time
|
||||
int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow);
|
||||
cmd.Parameters.AddWithValue("?id", asset.ID);
|
||||
cmd.Parameters.AddWithValue("?access_time", now);
|
||||
cmd.ExecuteNonQuery();
|
||||
cmd.Dispose();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat(
|
||||
"[ASSETS DB]: " +
|
||||
"MySql failure updating access_time for asset {0} with name {1}" + Environment.NewLine + e.ToString()
|
||||
+ Environment.NewLine + "Attempting reconnection", asset.FullID, asset.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -289,8 +283,8 @@ namespace OpenSim.Data.MySQL
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Error(
|
||||
string.Format("[ASSETS DB]: MySql failure fetching asset {0}. Exception ", uuid), e);
|
||||
m_log.ErrorFormat(
|
||||
"[ASSETS DB]: MySql failure fetching asset {0}" + Environment.NewLine + e.ToString(), uuid);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -316,45 +310,35 @@ namespace OpenSim.Data.MySQL
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
dbcon.Open();
|
||||
MySqlCommand cmd = new MySqlCommand("SELECT name,description,assetType,temporary,id,asset_flags,CreatorID FROM assets LIMIT ?start, ?count", dbcon);
|
||||
cmd.Parameters.AddWithValue("?start", start);
|
||||
cmd.Parameters.AddWithValue("?count", count);
|
||||
|
||||
using (MySqlCommand cmd
|
||||
= new MySqlCommand(
|
||||
"SELECT name,description,assetType,temporary,id,asset_flags,CreatorID FROM assets LIMIT ?start, ?count",
|
||||
dbcon))
|
||||
try
|
||||
{
|
||||
cmd.Parameters.AddWithValue("?start", start);
|
||||
cmd.Parameters.AddWithValue("?count", count);
|
||||
|
||||
try
|
||||
using (MySqlDataReader dbReader = cmd.ExecuteReader())
|
||||
{
|
||||
using (MySqlDataReader dbReader = cmd.ExecuteReader())
|
||||
while (dbReader.Read())
|
||||
{
|
||||
while (dbReader.Read())
|
||||
{
|
||||
AssetMetadata metadata = new AssetMetadata();
|
||||
metadata.Name = (string)dbReader["name"];
|
||||
metadata.Description = (string)dbReader["description"];
|
||||
metadata.Type = (sbyte)dbReader["assetType"];
|
||||
metadata.Temporary = Convert.ToBoolean(dbReader["temporary"]); // Not sure if this is correct.
|
||||
metadata.Flags = (AssetFlags)Convert.ToInt32(dbReader["asset_flags"]);
|
||||
metadata.FullID = DBGuid.FromDB(dbReader["id"]);
|
||||
metadata.CreatorID = dbReader["CreatorID"].ToString();
|
||||
|
||||
// Current SHA1s are not stored/computed.
|
||||
metadata.SHA1 = new byte[] { };
|
||||
|
||||
retList.Add(metadata);
|
||||
}
|
||||
AssetMetadata metadata = new AssetMetadata();
|
||||
metadata.Name = (string)dbReader["name"];
|
||||
metadata.Description = (string)dbReader["description"];
|
||||
metadata.Type = (sbyte)dbReader["assetType"];
|
||||
metadata.Temporary = Convert.ToBoolean(dbReader["temporary"]); // Not sure if this is correct.
|
||||
metadata.Flags = (AssetFlags)Convert.ToInt32(dbReader["asset_flags"]);
|
||||
metadata.FullID = DBGuid.FromDB(dbReader["id"]);
|
||||
metadata.CreatorID = dbReader["CreatorID"].ToString();
|
||||
|
||||
// Current SHA1s are not stored/computed.
|
||||
metadata.SHA1 = new byte[] { };
|
||||
|
||||
retList.Add(metadata);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Error(
|
||||
string.Format(
|
||||
"[ASSETS DB]: MySql failure fetching asset set from {0}, count {1}. Exception ",
|
||||
start, count),
|
||||
e);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Error("[ASSETS DB]: MySql failure fetching asset set" + Environment.NewLine + e.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -369,12 +353,11 @@ namespace OpenSim.Data.MySQL
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
dbcon.Open();
|
||||
MySqlCommand cmd = new MySqlCommand("delete from assets where id=?id", dbcon);
|
||||
cmd.Parameters.AddWithValue("?id", id);
|
||||
cmd.ExecuteNonQuery();
|
||||
|
||||
using (MySqlCommand cmd = new MySqlCommand("delete from assets where id=?id", dbcon))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("?id", id);
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
cmd.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -383,4 +366,4 @@ namespace OpenSim.Data.MySQL
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,52 +70,41 @@ namespace OpenSim.Data.MySQL
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
dbcon.Open();
|
||||
MySqlCommand cmd = new MySqlCommand("select * from `" + m_Realm + "` where UUID = ?principalID", dbcon);
|
||||
cmd.Parameters.AddWithValue("?principalID", principalID.ToString());
|
||||
|
||||
using (MySqlCommand cmd
|
||||
= new MySqlCommand("select * from `" + m_Realm + "` where UUID = ?principalID", dbcon))
|
||||
IDataReader result = cmd.ExecuteReader();
|
||||
|
||||
if (result.Read())
|
||||
{
|
||||
cmd.Parameters.AddWithValue("?principalID", principalID.ToString());
|
||||
ret.PrincipalID = principalID;
|
||||
|
||||
IDataReader result = cmd.ExecuteReader();
|
||||
|
||||
if (result.Read())
|
||||
if (m_ColumnNames == null)
|
||||
{
|
||||
ret.PrincipalID = principalID;
|
||||
|
||||
CheckColumnNames(result);
|
||||
|
||||
foreach (string s in m_ColumnNames)
|
||||
{
|
||||
if (s == "UUID")
|
||||
continue;
|
||||
|
||||
ret.Data[s] = result[s].ToString();
|
||||
}
|
||||
|
||||
return ret;
|
||||
m_ColumnNames = new List<string>();
|
||||
|
||||
DataTable schemaTable = result.GetSchemaTable();
|
||||
foreach (DataRow row in schemaTable.Rows)
|
||||
m_ColumnNames.Add(row["ColumnName"].ToString());
|
||||
}
|
||||
else
|
||||
|
||||
foreach (string s in m_ColumnNames)
|
||||
{
|
||||
return null;
|
||||
if (s == "UUID")
|
||||
continue;
|
||||
|
||||
ret.Data[s] = result[s].ToString();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void CheckColumnNames(IDataReader result)
|
||||
{
|
||||
if (m_ColumnNames != null)
|
||||
return;
|
||||
|
||||
List<string> columnNames = new List<string>();
|
||||
|
||||
DataTable schemaTable = result.GetSchemaTable();
|
||||
foreach (DataRow row in schemaTable.Rows)
|
||||
columnNames.Add(row["ColumnName"].ToString());
|
||||
|
||||
m_ColumnNames = columnNames;
|
||||
}
|
||||
|
||||
public bool Store(AuthenticationData data)
|
||||
{
|
||||
if (data.Data.ContainsKey("UUID"))
|
||||
@@ -123,53 +112,57 @@ namespace OpenSim.Data.MySQL
|
||||
|
||||
string[] fields = new List<string>(data.Data.Keys).ToArray();
|
||||
|
||||
using (MySqlCommand cmd = new MySqlCommand())
|
||||
MySqlCommand cmd = new MySqlCommand();
|
||||
|
||||
string update = "update `"+m_Realm+"` set ";
|
||||
bool first = true;
|
||||
foreach (string field in fields)
|
||||
{
|
||||
string update = "update `"+m_Realm+"` set ";
|
||||
bool first = true;
|
||||
foreach (string field in fields)
|
||||
{
|
||||
if (!first)
|
||||
update += ", ";
|
||||
update += "`" + field + "` = ?"+field;
|
||||
|
||||
first = false;
|
||||
|
||||
cmd.Parameters.AddWithValue("?"+field, data.Data[field]);
|
||||
}
|
||||
|
||||
update += " where UUID = ?principalID";
|
||||
|
||||
cmd.CommandText = update;
|
||||
cmd.Parameters.AddWithValue("?principalID", data.PrincipalID.ToString());
|
||||
|
||||
if (!first)
|
||||
update += ", ";
|
||||
update += "`" + field + "` = ?"+field;
|
||||
|
||||
first = false;
|
||||
|
||||
cmd.Parameters.AddWithValue("?"+field, data.Data[field]);
|
||||
}
|
||||
|
||||
update += " where UUID = ?principalID";
|
||||
|
||||
cmd.CommandText = update;
|
||||
cmd.Parameters.AddWithValue("?principalID", data.PrincipalID.ToString());
|
||||
|
||||
if (ExecuteNonQuery(cmd) < 1)
|
||||
{
|
||||
string insert = "insert into `" + m_Realm + "` (`UUID`, `" +
|
||||
String.Join("`, `", fields) +
|
||||
"`) values (?principalID, ?" + String.Join(", ?", fields) + ")";
|
||||
|
||||
cmd.CommandText = insert;
|
||||
|
||||
if (ExecuteNonQuery(cmd) < 1)
|
||||
{
|
||||
string insert = "insert into `" + m_Realm + "` (`UUID`, `" +
|
||||
String.Join("`, `", fields) +
|
||||
"`) values (?principalID, ?" + String.Join(", ?", fields) + ")";
|
||||
|
||||
cmd.CommandText = insert;
|
||||
|
||||
if (ExecuteNonQuery(cmd) < 1)
|
||||
return false;
|
||||
cmd.Dispose();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
cmd.Dispose();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool SetDataItem(UUID principalID, string item, string value)
|
||||
{
|
||||
using (MySqlCommand cmd
|
||||
= new MySqlCommand("update `" + m_Realm + "` set `" + item + "` = ?" + item + " where UUID = ?UUID"))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("?"+item, value);
|
||||
cmd.Parameters.AddWithValue("?UUID", principalID.ToString());
|
||||
|
||||
if (ExecuteNonQuery(cmd) > 0)
|
||||
return true;
|
||||
}
|
||||
MySqlCommand cmd = new MySqlCommand("update `" + m_Realm +
|
||||
"` set `" + item + "` = ?" + item + " where UUID = ?UUID");
|
||||
|
||||
|
||||
cmd.Parameters.AddWithValue("?"+item, value);
|
||||
cmd.Parameters.AddWithValue("?UUID", principalID.ToString());
|
||||
|
||||
if (ExecuteNonQuery(cmd) > 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -179,18 +172,18 @@ namespace OpenSim.Data.MySQL
|
||||
if (System.Environment.TickCount - m_LastExpire > 30000)
|
||||
DoExpire();
|
||||
|
||||
using (MySqlCommand cmd
|
||||
= new MySqlCommand(
|
||||
"insert into tokens (UUID, token, validity) values (?principalID, ?token, date_add(now(), interval ?lifetime minute))"))
|
||||
MySqlCommand cmd = new MySqlCommand("insert into tokens (UUID, token, validity) values (?principalID, ?token, date_add(now(), interval ?lifetime minute))");
|
||||
cmd.Parameters.AddWithValue("?principalID", principalID.ToString());
|
||||
cmd.Parameters.AddWithValue("?token", token);
|
||||
cmd.Parameters.AddWithValue("?lifetime", lifetime.ToString());
|
||||
|
||||
if (ExecuteNonQuery(cmd) > 0)
|
||||
{
|
||||
cmd.Parameters.AddWithValue("?principalID", principalID.ToString());
|
||||
cmd.Parameters.AddWithValue("?token", token);
|
||||
cmd.Parameters.AddWithValue("?lifetime", lifetime.ToString());
|
||||
|
||||
if (ExecuteNonQuery(cmd) > 0)
|
||||
return true;
|
||||
cmd.Dispose();
|
||||
return true;
|
||||
}
|
||||
|
||||
cmd.Dispose();
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -199,29 +192,30 @@ namespace OpenSim.Data.MySQL
|
||||
if (System.Environment.TickCount - m_LastExpire > 30000)
|
||||
DoExpire();
|
||||
|
||||
using (MySqlCommand cmd
|
||||
= new MySqlCommand(
|
||||
"update tokens set validity = date_add(now(), interval ?lifetime minute) where UUID = ?principalID and token = ?token and validity > now()"))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("?principalID", principalID.ToString());
|
||||
cmd.Parameters.AddWithValue("?token", token);
|
||||
cmd.Parameters.AddWithValue("?lifetime", lifetime.ToString());
|
||||
MySqlCommand cmd = new MySqlCommand("update tokens set validity = date_add(now(), interval ?lifetime minute) where UUID = ?principalID and token = ?token and validity > now()");
|
||||
cmd.Parameters.AddWithValue("?principalID", principalID.ToString());
|
||||
cmd.Parameters.AddWithValue("?token", token);
|
||||
cmd.Parameters.AddWithValue("?lifetime", lifetime.ToString());
|
||||
|
||||
if (ExecuteNonQuery(cmd) > 0)
|
||||
return true;
|
||||
if (ExecuteNonQuery(cmd) > 0)
|
||||
{
|
||||
cmd.Dispose();
|
||||
return true;
|
||||
}
|
||||
|
||||
cmd.Dispose();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void DoExpire()
|
||||
{
|
||||
using (MySqlCommand cmd = new MySqlCommand("delete from tokens where validity < now()"))
|
||||
{
|
||||
ExecuteNonQuery(cmd);
|
||||
}
|
||||
MySqlCommand cmd = new MySqlCommand("delete from tokens where validity < now()");
|
||||
ExecuteNonQuery(cmd);
|
||||
|
||||
cmd.Dispose();
|
||||
|
||||
m_LastExpire = System.Environment.TickCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,15 +52,14 @@ namespace OpenSim.Data.MySQL
|
||||
|
||||
public bool Delete(UUID principalID, string name)
|
||||
{
|
||||
using (MySqlCommand cmd = new MySqlCommand())
|
||||
{
|
||||
cmd.CommandText = String.Format("delete from {0} where `PrincipalID` = ?PrincipalID and `Name` = ?Name", m_Realm);
|
||||
cmd.Parameters.AddWithValue("?PrincipalID", principalID.ToString());
|
||||
cmd.Parameters.AddWithValue("?Name", name);
|
||||
|
||||
if (ExecuteNonQuery(cmd) > 0)
|
||||
return true;
|
||||
}
|
||||
MySqlCommand cmd = new MySqlCommand();
|
||||
|
||||
cmd.CommandText = String.Format("delete from {0} where `PrincipalID` = ?PrincipalID and `Name` = ?Name", m_Realm);
|
||||
cmd.Parameters.AddWithValue("?PrincipalID", principalID.ToString());
|
||||
cmd.Parameters.AddWithValue("?Name", name);
|
||||
|
||||
if (ExecuteNonQuery(cmd) > 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -49,38 +49,34 @@ namespace OpenSim.Data.MySQL
|
||||
|
||||
public bool Delete(string principalID, string friend)
|
||||
{
|
||||
using (MySqlCommand cmd = new MySqlCommand())
|
||||
{
|
||||
cmd.CommandText = String.Format("delete from {0} where PrincipalID = ?PrincipalID and Friend = ?Friend", m_Realm);
|
||||
cmd.Parameters.AddWithValue("?PrincipalID", principalID.ToString());
|
||||
cmd.Parameters.AddWithValue("?Friend", friend);
|
||||
MySqlCommand cmd = new MySqlCommand();
|
||||
|
||||
ExecuteNonQuery(cmd);
|
||||
}
|
||||
cmd.CommandText = String.Format("delete from {0} where PrincipalID = ?PrincipalID and Friend = ?Friend", m_Realm);
|
||||
cmd.Parameters.AddWithValue("?PrincipalID", principalID.ToString());
|
||||
cmd.Parameters.AddWithValue("?Friend", friend);
|
||||
|
||||
ExecuteNonQuery(cmd);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public FriendsData[] GetFriends(UUID principalID)
|
||||
{
|
||||
using (MySqlCommand cmd = new MySqlCommand())
|
||||
{
|
||||
cmd.CommandText = String.Format("select a.*,case when b.Flags is null then -1 else b.Flags end as TheirFlags from {0} as a left join {0} as b on a.PrincipalID = b.Friend and a.Friend = b.PrincipalID where a.PrincipalID = ?PrincipalID", m_Realm);
|
||||
cmd.Parameters.AddWithValue("?PrincipalID", principalID.ToString());
|
||||
MySqlCommand cmd = new MySqlCommand();
|
||||
|
||||
return DoQuery(cmd);
|
||||
}
|
||||
cmd.CommandText = String.Format("select a.*,case when b.Flags is null then -1 else b.Flags end as TheirFlags from {0} as a left join {0} as b on a.PrincipalID = b.Friend and a.Friend = b.PrincipalID where a.PrincipalID = ?PrincipalID", m_Realm);
|
||||
cmd.Parameters.AddWithValue("?PrincipalID", principalID.ToString());
|
||||
|
||||
return DoQuery(cmd);
|
||||
}
|
||||
|
||||
public FriendsData[] GetFriends(string principalID)
|
||||
{
|
||||
using (MySqlCommand cmd = new MySqlCommand())
|
||||
{
|
||||
cmd.CommandText = String.Format("select a.*,case when b.Flags is null then -1 else b.Flags end as TheirFlags from {0} as a left join {0} as b on a.PrincipalID = b.Friend and a.Friend = b.PrincipalID where a.PrincipalID LIKE ?PrincipalID", m_Realm);
|
||||
cmd.Parameters.AddWithValue("?PrincipalID", principalID.ToString() + '%');
|
||||
MySqlCommand cmd = new MySqlCommand();
|
||||
|
||||
return DoQuery(cmd);
|
||||
}
|
||||
cmd.CommandText = String.Format("select a.*,case when b.Flags is null then -1 else b.Flags end as TheirFlags from {0} as a left join {0} as b on a.PrincipalID = b.Friend and a.Friend = b.PrincipalID where a.PrincipalID LIKE ?PrincipalID", m_Realm);
|
||||
cmd.Parameters.AddWithValue("?PrincipalID", principalID.ToString() + '%');
|
||||
return DoQuery(cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,17 +91,15 @@ namespace OpenSim.Data.MySQL
|
||||
if (m_ColumnNames != null)
|
||||
return;
|
||||
|
||||
List<string> columnNames = new List<string>();
|
||||
m_ColumnNames = new List<string>();
|
||||
|
||||
DataTable schemaTable = reader.GetSchemaTable();
|
||||
foreach (DataRow row in schemaTable.Rows)
|
||||
{
|
||||
if (row["ColumnName"] != null &&
|
||||
(!m_Fields.ContainsKey(row["ColumnName"].ToString())))
|
||||
columnNames.Add(row["ColumnName"].ToString());
|
||||
m_ColumnNames.Add(row["ColumnName"].ToString());
|
||||
}
|
||||
|
||||
m_ColumnNames = columnNames;
|
||||
}
|
||||
|
||||
public virtual T[] Get(string field, string key)
|
||||
@@ -219,8 +217,6 @@ 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 = "";
|
||||
@@ -275,10 +271,6 @@ 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;
|
||||
|
||||
@@ -301,65 +293,5 @@ namespace OpenSim.Data.MySQL
|
||||
return ExecuteNonQuery(cmd) > 0;
|
||||
}
|
||||
}
|
||||
|
||||
public long GetCount(string field, string key)
|
||||
{
|
||||
return GetCount(new string[] { field }, new string[] { key });
|
||||
}
|
||||
|
||||
public long GetCount(string[] fields, string[] keys)
|
||||
{
|
||||
if (fields.Length != keys.Length)
|
||||
return 0;
|
||||
|
||||
List<string> terms = new List<string>();
|
||||
|
||||
using (MySqlCommand cmd = new MySqlCommand())
|
||||
{
|
||||
for (int i = 0; i < fields.Length; i++)
|
||||
{
|
||||
cmd.Parameters.AddWithValue(fields[i], keys[i]);
|
||||
terms.Add("`" + fields[i] + "` = ?" + fields[i]);
|
||||
}
|
||||
|
||||
string where = String.Join(" and ", terms.ToArray());
|
||||
|
||||
string query = String.Format("select count(*) from {0} where {1}",
|
||||
m_Realm, where);
|
||||
|
||||
cmd.CommandText = query;
|
||||
|
||||
Object result = DoQueryScalar(cmd);
|
||||
|
||||
return Convert.ToInt64(result);
|
||||
}
|
||||
}
|
||||
|
||||
public long GetCount(string where)
|
||||
{
|
||||
using (MySqlCommand cmd = new MySqlCommand())
|
||||
{
|
||||
string query = String.Format("select count(*) from {0} where {1}",
|
||||
m_Realm, where);
|
||||
|
||||
cmd.CommandText = query;
|
||||
|
||||
object result = DoQueryScalar(cmd);
|
||||
|
||||
return Convert.ToInt64(result);
|
||||
}
|
||||
}
|
||||
|
||||
public object DoQueryScalar(MySqlCommand cmd)
|
||||
{
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
dbcon.Open();
|
||||
cmd.Connection = dbcon;
|
||||
|
||||
return cmd.ExecuteScalar();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -46,7 +46,7 @@ namespace OpenSim.Data.MySQL
|
||||
|
||||
public MySQLGridUserData(string connectionString, string realm) : base(connectionString, realm, "GridUserStore") {}
|
||||
|
||||
public new GridUserData Get(string userID)
|
||||
public GridUserData Get(string userID)
|
||||
{
|
||||
GridUserData[] ret = Get("UserID", userID);
|
||||
|
||||
@@ -56,9 +56,6 @@ namespace OpenSim.Data.MySQL
|
||||
return ret[0];
|
||||
}
|
||||
|
||||
public GridUserData[] GetAll(string userID)
|
||||
{
|
||||
return base.Get(String.Format("UserID LIKE '{0}%'", userID));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,484 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Data.MySQL;
|
||||
|
||||
using OpenMetaverse;
|
||||
using MySql.Data.MySqlClient;
|
||||
|
||||
namespace OpenSim.Data.MySQL
|
||||
{
|
||||
public class MySQLGroupsData : IGroupsData
|
||||
{
|
||||
private MySqlGroupsGroupsHandler m_Groups;
|
||||
private MySqlGroupsMembershipHandler m_Membership;
|
||||
private MySqlGroupsRolesHandler m_Roles;
|
||||
private MySqlGroupsRoleMembershipHandler m_RoleMembership;
|
||||
private MySqlGroupsInvitesHandler m_Invites;
|
||||
private MySqlGroupsNoticesHandler m_Notices;
|
||||
private MySqlGroupsPrincipalsHandler m_Principals;
|
||||
|
||||
public MySQLGroupsData(string connectionString, string realm)
|
||||
{
|
||||
m_Groups = new MySqlGroupsGroupsHandler(connectionString, realm + "_groups", realm + "_Store");
|
||||
m_Membership = new MySqlGroupsMembershipHandler(connectionString, realm + "_membership");
|
||||
m_Roles = new MySqlGroupsRolesHandler(connectionString, realm + "_roles");
|
||||
m_RoleMembership = new MySqlGroupsRoleMembershipHandler(connectionString, realm + "_rolemembership");
|
||||
m_Invites = new MySqlGroupsInvitesHandler(connectionString, realm + "_invites");
|
||||
m_Notices = new MySqlGroupsNoticesHandler(connectionString, realm + "_notices");
|
||||
m_Principals = new MySqlGroupsPrincipalsHandler(connectionString, realm + "_principals");
|
||||
}
|
||||
|
||||
#region groups table
|
||||
public bool StoreGroup(GroupData data)
|
||||
{
|
||||
return m_Groups.Store(data);
|
||||
}
|
||||
|
||||
public GroupData RetrieveGroup(UUID groupID)
|
||||
{
|
||||
GroupData[] groups = m_Groups.Get("GroupID", groupID.ToString());
|
||||
if (groups.Length > 0)
|
||||
return groups[0];
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public GroupData RetrieveGroup(string name)
|
||||
{
|
||||
GroupData[] groups = m_Groups.Get("Name", name);
|
||||
if (groups.Length > 0)
|
||||
return groups[0];
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public GroupData[] RetrieveGroups(string pattern)
|
||||
{
|
||||
if (string.IsNullOrEmpty(pattern))
|
||||
pattern = "1 ORDER BY Name LIMIT 100";
|
||||
else
|
||||
pattern = string.Format("Name LIKE '%{0}%' ORDER BY Name LIMIT 100", pattern);
|
||||
|
||||
return m_Groups.Get(pattern);
|
||||
}
|
||||
|
||||
public bool DeleteGroup(UUID groupID)
|
||||
{
|
||||
return m_Groups.Delete("GroupID", groupID.ToString());
|
||||
}
|
||||
|
||||
public int GroupsCount()
|
||||
{
|
||||
return (int)m_Groups.GetCount("Location=\"\"");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region membership table
|
||||
public MembershipData[] RetrieveMembers(UUID groupID)
|
||||
{
|
||||
return m_Membership.Get("GroupID", groupID.ToString());
|
||||
}
|
||||
|
||||
public MembershipData RetrieveMember(UUID groupID, string pricipalID)
|
||||
{
|
||||
MembershipData[] m = m_Membership.Get(new string[] { "GroupID", "PrincipalID" },
|
||||
new string[] { groupID.ToString(), pricipalID });
|
||||
if (m != null && m.Length > 0)
|
||||
return m[0];
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public MembershipData[] RetrieveMemberships(string pricipalID)
|
||||
{
|
||||
return m_Membership.Get("PrincipalID", pricipalID.ToString());
|
||||
}
|
||||
|
||||
public bool StoreMember(MembershipData data)
|
||||
{
|
||||
return m_Membership.Store(data);
|
||||
}
|
||||
|
||||
public bool DeleteMember(UUID groupID, string pricipalID)
|
||||
{
|
||||
return m_Membership.Delete(new string[] { "GroupID", "PrincipalID" },
|
||||
new string[] { groupID.ToString(), pricipalID });
|
||||
}
|
||||
|
||||
public int MemberCount(UUID groupID)
|
||||
{
|
||||
return (int)m_Membership.GetCount("GroupID", groupID.ToString());
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region roles table
|
||||
public bool StoreRole(RoleData data)
|
||||
{
|
||||
return m_Roles.Store(data);
|
||||
}
|
||||
|
||||
public RoleData RetrieveRole(UUID groupID, UUID roleID)
|
||||
{
|
||||
RoleData[] data = m_Roles.Get(new string[] { "GroupID", "RoleID" },
|
||||
new string[] { groupID.ToString(), roleID.ToString() });
|
||||
|
||||
if (data != null && data.Length > 0)
|
||||
return data[0];
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public RoleData[] RetrieveRoles(UUID groupID)
|
||||
{
|
||||
//return m_Roles.RetrieveRoles(groupID);
|
||||
return m_Roles.Get("GroupID", groupID.ToString());
|
||||
}
|
||||
|
||||
public bool DeleteRole(UUID groupID, UUID roleID)
|
||||
{
|
||||
return m_Roles.Delete(new string[] { "GroupID", "RoleID" },
|
||||
new string[] { groupID.ToString(), roleID.ToString() });
|
||||
}
|
||||
|
||||
public int RoleCount(UUID groupID)
|
||||
{
|
||||
return (int)m_Roles.GetCount("GroupID", groupID.ToString());
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region rolememberhip table
|
||||
public RoleMembershipData[] RetrieveRolesMembers(UUID groupID)
|
||||
{
|
||||
RoleMembershipData[] data = m_RoleMembership.Get("GroupID", groupID.ToString());
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
public RoleMembershipData[] RetrieveRoleMembers(UUID groupID, UUID roleID)
|
||||
{
|
||||
RoleMembershipData[] data = m_RoleMembership.Get(new string[] { "GroupID", "RoleID" },
|
||||
new string[] { groupID.ToString(), roleID.ToString() });
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
public RoleMembershipData[] RetrieveMemberRoles(UUID groupID, string principalID)
|
||||
{
|
||||
RoleMembershipData[] data = m_RoleMembership.Get(new string[] { "GroupID", "PrincipalID" },
|
||||
new string[] { groupID.ToString(), principalID.ToString() });
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
public RoleMembershipData RetrieveRoleMember(UUID groupID, UUID roleID, string principalID)
|
||||
{
|
||||
RoleMembershipData[] data = m_RoleMembership.Get(new string[] { "GroupID", "RoleID", "PrincipalID" },
|
||||
new string[] { groupID.ToString(), roleID.ToString(), principalID.ToString() });
|
||||
|
||||
if (data != null && data.Length > 0)
|
||||
return data[0];
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public int RoleMemberCount(UUID groupID, UUID roleID)
|
||||
{
|
||||
return (int)m_RoleMembership.GetCount(new string[] { "GroupID", "RoleID" },
|
||||
new string[] { groupID.ToString(), roleID.ToString() });
|
||||
}
|
||||
|
||||
public bool StoreRoleMember(RoleMembershipData data)
|
||||
{
|
||||
return m_RoleMembership.Store(data);
|
||||
}
|
||||
|
||||
public bool DeleteRoleMember(RoleMembershipData data)
|
||||
{
|
||||
return m_RoleMembership.Delete(new string[] { "GroupID", "RoleID", "PrincipalID"},
|
||||
new string[] { data.GroupID.ToString(), data.RoleID.ToString(), data.PrincipalID });
|
||||
}
|
||||
|
||||
public bool DeleteMemberAllRoles(UUID groupID, string principalID)
|
||||
{
|
||||
return m_RoleMembership.Delete(new string[] { "GroupID", "PrincipalID" },
|
||||
new string[] { groupID.ToString(), principalID });
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region principals table
|
||||
public bool StorePrincipal(PrincipalData data)
|
||||
{
|
||||
return m_Principals.Store(data);
|
||||
}
|
||||
|
||||
public PrincipalData RetrievePrincipal(string principalID)
|
||||
{
|
||||
PrincipalData[] p = m_Principals.Get("PrincipalID", principalID);
|
||||
if (p != null && p.Length > 0)
|
||||
return p[0];
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public bool DeletePrincipal(string principalID)
|
||||
{
|
||||
return m_Principals.Delete("PrincipalID", principalID);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region invites table
|
||||
|
||||
public bool StoreInvitation(InvitationData data)
|
||||
{
|
||||
return m_Invites.Store(data);
|
||||
}
|
||||
|
||||
public InvitationData RetrieveInvitation(UUID inviteID)
|
||||
{
|
||||
InvitationData[] invites = m_Invites.Get("InviteID", inviteID.ToString());
|
||||
|
||||
if (invites != null && invites.Length > 0)
|
||||
return invites[0];
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public InvitationData RetrieveInvitation(UUID groupID, string principalID)
|
||||
{
|
||||
InvitationData[] invites = m_Invites.Get(new string[] { "GroupID", "PrincipalID" },
|
||||
new string[] { groupID.ToString(), principalID });
|
||||
|
||||
if (invites != null && invites.Length > 0)
|
||||
return invites[0];
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public bool DeleteInvite(UUID inviteID)
|
||||
{
|
||||
return m_Invites.Delete("InviteID", inviteID.ToString());
|
||||
}
|
||||
|
||||
public void DeleteOldInvites()
|
||||
{
|
||||
m_Invites.DeleteOld();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region notices table
|
||||
|
||||
public bool StoreNotice(NoticeData data)
|
||||
{
|
||||
return m_Notices.Store(data);
|
||||
}
|
||||
|
||||
public NoticeData RetrieveNotice(UUID noticeID)
|
||||
{
|
||||
NoticeData[] notices = m_Notices.Get("NoticeID", noticeID.ToString());
|
||||
|
||||
if (notices != null && notices.Length > 0)
|
||||
return notices[0];
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public NoticeData[] RetrieveNotices(UUID groupID)
|
||||
{
|
||||
NoticeData[] notices = m_Notices.Get("GroupID", groupID.ToString());
|
||||
|
||||
return notices;
|
||||
}
|
||||
|
||||
public bool DeleteNotice(UUID noticeID)
|
||||
{
|
||||
return m_Notices.Delete("NoticeID", noticeID.ToString());
|
||||
}
|
||||
|
||||
public void DeleteOldNotices()
|
||||
{
|
||||
m_Notices.DeleteOld();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region combinations
|
||||
public MembershipData RetrievePrincipalGroupMembership(string principalID, UUID groupID)
|
||||
{
|
||||
// TODO
|
||||
return null;
|
||||
}
|
||||
public MembershipData[] RetrievePrincipalGroupMemberships(string principalID)
|
||||
{
|
||||
// TODO
|
||||
return null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
public class MySqlGroupsGroupsHandler : MySQLGenericTableHandler<GroupData>
|
||||
{
|
||||
protected override Assembly Assembly
|
||||
{
|
||||
// WARNING! Moving migrations to this assembly!!!
|
||||
get { return GetType().Assembly; }
|
||||
}
|
||||
|
||||
public MySqlGroupsGroupsHandler(string connectionString, string realm, string store)
|
||||
: base(connectionString, realm, store)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class MySqlGroupsMembershipHandler : MySQLGenericTableHandler<MembershipData>
|
||||
{
|
||||
protected override Assembly Assembly
|
||||
{
|
||||
// WARNING! Moving migrations to this assembly!!!
|
||||
get { return GetType().Assembly; }
|
||||
}
|
||||
|
||||
public MySqlGroupsMembershipHandler(string connectionString, string realm)
|
||||
: base(connectionString, realm, string.Empty)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class MySqlGroupsRolesHandler : MySQLGenericTableHandler<RoleData>
|
||||
{
|
||||
protected override Assembly Assembly
|
||||
{
|
||||
// WARNING! Moving migrations to this assembly!!!
|
||||
get { return GetType().Assembly; }
|
||||
}
|
||||
|
||||
public MySqlGroupsRolesHandler(string connectionString, string realm)
|
||||
: base(connectionString, realm, string.Empty)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class MySqlGroupsRoleMembershipHandler : MySQLGenericTableHandler<RoleMembershipData>
|
||||
{
|
||||
protected override Assembly Assembly
|
||||
{
|
||||
// WARNING! Moving migrations to this assembly!!!
|
||||
get { return GetType().Assembly; }
|
||||
}
|
||||
|
||||
public MySqlGroupsRoleMembershipHandler(string connectionString, string realm)
|
||||
: base(connectionString, realm, string.Empty)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class MySqlGroupsInvitesHandler : MySQLGenericTableHandler<InvitationData>
|
||||
{
|
||||
protected override Assembly Assembly
|
||||
{
|
||||
// WARNING! Moving migrations to this assembly!!!
|
||||
get { return GetType().Assembly; }
|
||||
}
|
||||
|
||||
public MySqlGroupsInvitesHandler(string connectionString, string realm)
|
||||
: base(connectionString, realm, string.Empty)
|
||||
{
|
||||
}
|
||||
|
||||
public void DeleteOld()
|
||||
{
|
||||
uint now = (uint)Util.UnixTimeSinceEpoch();
|
||||
|
||||
using (MySqlCommand cmd = new MySqlCommand())
|
||||
{
|
||||
cmd.CommandText = String.Format("delete from {0} where TMStamp < ?tstamp", m_Realm);
|
||||
cmd.Parameters.AddWithValue("?tstamp", now - 14 * 24 * 60 * 60); // > 2 weeks old
|
||||
|
||||
ExecuteNonQuery(cmd);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public class MySqlGroupsNoticesHandler : MySQLGenericTableHandler<NoticeData>
|
||||
{
|
||||
protected override Assembly Assembly
|
||||
{
|
||||
// WARNING! Moving migrations to this assembly!!!
|
||||
get { return GetType().Assembly; }
|
||||
}
|
||||
|
||||
public MySqlGroupsNoticesHandler(string connectionString, string realm)
|
||||
: base(connectionString, realm, string.Empty)
|
||||
{
|
||||
}
|
||||
|
||||
public void DeleteOld()
|
||||
{
|
||||
uint now = (uint)Util.UnixTimeSinceEpoch();
|
||||
|
||||
using (MySqlCommand cmd = new MySqlCommand())
|
||||
{
|
||||
cmd.CommandText = String.Format("delete from {0} where TMStamp < ?tstamp", m_Realm);
|
||||
cmd.Parameters.AddWithValue("?tstamp", now - 14 * 24 * 60 * 60); // > 2 weeks old
|
||||
|
||||
ExecuteNonQuery(cmd);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public class MySqlGroupsPrincipalsHandler : MySQLGenericTableHandler<PrincipalData>
|
||||
{
|
||||
protected override Assembly Assembly
|
||||
{
|
||||
// WARNING! Moving migrations to this assembly!!!
|
||||
get { return GetType().Assembly; }
|
||||
}
|
||||
|
||||
public MySqlGroupsPrincipalsHandler(string connectionString, string realm)
|
||||
: base(connectionString, realm, string.Empty)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,80 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using log4net;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using MySql.Data.MySqlClient;
|
||||
|
||||
namespace OpenSim.Data.MySQL
|
||||
{
|
||||
/// <summary>
|
||||
/// A MySQL Interface for user grid data
|
||||
/// </summary>
|
||||
public class MySQLHGTravelData : MySQLGenericTableHandler<HGTravelingData>, IHGTravelingData
|
||||
{
|
||||
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
public MySQLHGTravelData(string connectionString, string realm) : base(connectionString, realm, "HGTravelStore") { }
|
||||
|
||||
public HGTravelingData Get(UUID sessionID)
|
||||
{
|
||||
HGTravelingData[] ret = Get("SessionID", sessionID.ToString());
|
||||
|
||||
if (ret.Length == 0)
|
||||
return null;
|
||||
|
||||
return ret[0];
|
||||
}
|
||||
|
||||
public HGTravelingData[] GetSessions(UUID userID)
|
||||
{
|
||||
return base.Get("UserID", userID.ToString());
|
||||
}
|
||||
|
||||
public bool Delete(UUID sessionID)
|
||||
{
|
||||
return Delete("SessionID", sessionID.ToString());
|
||||
}
|
||||
|
||||
public void DeleteOld()
|
||||
{
|
||||
using (MySqlCommand cmd = new MySqlCommand())
|
||||
{
|
||||
cmd.CommandText = String.Format("delete from {0} where TMStamp < NOW() - INTERVAL 2 DAY", m_Realm);
|
||||
|
||||
ExecuteNonQuery(cmd);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -467,43 +467,43 @@ namespace OpenSim.Data.MySQL
|
||||
{
|
||||
dbcon.Open();
|
||||
|
||||
using (MySqlCommand result = new MySqlCommand(sql, dbcon))
|
||||
MySqlCommand result = new MySqlCommand(sql, dbcon);
|
||||
result.Parameters.AddWithValue("?inventoryID", item.ID.ToString());
|
||||
result.Parameters.AddWithValue("?assetID", item.AssetID.ToString());
|
||||
result.Parameters.AddWithValue("?assetType", item.AssetType.ToString());
|
||||
result.Parameters.AddWithValue("?parentFolderID", item.Folder.ToString());
|
||||
result.Parameters.AddWithValue("?avatarID", item.Owner.ToString());
|
||||
result.Parameters.AddWithValue("?inventoryName", itemName);
|
||||
result.Parameters.AddWithValue("?inventoryDescription", itemDesc);
|
||||
result.Parameters.AddWithValue("?inventoryNextPermissions", item.NextPermissions.ToString());
|
||||
result.Parameters.AddWithValue("?inventoryCurrentPermissions",
|
||||
item.CurrentPermissions.ToString());
|
||||
result.Parameters.AddWithValue("?invType", item.InvType);
|
||||
result.Parameters.AddWithValue("?creatorID", item.CreatorId);
|
||||
result.Parameters.AddWithValue("?inventoryBasePermissions", item.BasePermissions);
|
||||
result.Parameters.AddWithValue("?inventoryEveryOnePermissions", item.EveryOnePermissions);
|
||||
result.Parameters.AddWithValue("?inventoryGroupPermissions", item.GroupPermissions);
|
||||
result.Parameters.AddWithValue("?salePrice", item.SalePrice);
|
||||
result.Parameters.AddWithValue("?saleType", unchecked((sbyte)item.SaleType));
|
||||
result.Parameters.AddWithValue("?creationDate", item.CreationDate);
|
||||
result.Parameters.AddWithValue("?groupID", item.GroupID);
|
||||
result.Parameters.AddWithValue("?groupOwned", item.GroupOwned);
|
||||
result.Parameters.AddWithValue("?flags", item.Flags);
|
||||
|
||||
lock (m_dbLock)
|
||||
{
|
||||
result.Parameters.AddWithValue("?inventoryID", item.ID.ToString());
|
||||
result.Parameters.AddWithValue("?assetID", item.AssetID.ToString());
|
||||
result.Parameters.AddWithValue("?assetType", item.AssetType.ToString());
|
||||
result.Parameters.AddWithValue("?parentFolderID", item.Folder.ToString());
|
||||
result.Parameters.AddWithValue("?avatarID", item.Owner.ToString());
|
||||
result.Parameters.AddWithValue("?inventoryName", itemName);
|
||||
result.Parameters.AddWithValue("?inventoryDescription", itemDesc);
|
||||
result.Parameters.AddWithValue("?inventoryNextPermissions", item.NextPermissions.ToString());
|
||||
result.Parameters.AddWithValue("?inventoryCurrentPermissions",
|
||||
item.CurrentPermissions.ToString());
|
||||
result.Parameters.AddWithValue("?invType", item.InvType);
|
||||
result.Parameters.AddWithValue("?creatorID", item.CreatorId);
|
||||
result.Parameters.AddWithValue("?inventoryBasePermissions", item.BasePermissions);
|
||||
result.Parameters.AddWithValue("?inventoryEveryOnePermissions", item.EveryOnePermissions);
|
||||
result.Parameters.AddWithValue("?inventoryGroupPermissions", item.GroupPermissions);
|
||||
result.Parameters.AddWithValue("?salePrice", item.SalePrice);
|
||||
result.Parameters.AddWithValue("?saleType", unchecked((sbyte)item.SaleType));
|
||||
result.Parameters.AddWithValue("?creationDate", item.CreationDate);
|
||||
result.Parameters.AddWithValue("?groupID", item.GroupID);
|
||||
result.Parameters.AddWithValue("?groupOwned", item.GroupOwned);
|
||||
result.Parameters.AddWithValue("?flags", item.Flags);
|
||||
|
||||
lock (m_dbLock)
|
||||
result.ExecuteNonQuery();
|
||||
|
||||
result.Dispose();
|
||||
result.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
using (MySqlCommand result = new MySqlCommand("update inventoryfolders set version=version+1 where folderID = ?folderID", dbcon))
|
||||
{
|
||||
result.Parameters.AddWithValue("?folderID", item.Folder.ToString());
|
||||
result.Dispose();
|
||||
|
||||
lock (m_dbLock)
|
||||
result.ExecuteNonQuery();
|
||||
result = new MySqlCommand("update inventoryfolders set version=version+1 where folderID = ?folderID", dbcon);
|
||||
result.Parameters.AddWithValue("?folderID", item.Folder.ToString());
|
||||
lock (m_dbLock)
|
||||
{
|
||||
result.ExecuteNonQuery();
|
||||
}
|
||||
result.Dispose();
|
||||
}
|
||||
}
|
||||
catch (MySqlException e)
|
||||
@@ -533,12 +533,12 @@ namespace OpenSim.Data.MySQL
|
||||
{
|
||||
dbcon.Open();
|
||||
|
||||
using (MySqlCommand cmd = new MySqlCommand("DELETE FROM inventoryitems WHERE inventoryID=?uuid", dbcon))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("?uuid", itemID.ToString());
|
||||
MySqlCommand cmd = new MySqlCommand("DELETE FROM inventoryitems WHERE inventoryID=?uuid", dbcon);
|
||||
cmd.Parameters.AddWithValue("?uuid", itemID.ToString());
|
||||
|
||||
lock (m_dbLock)
|
||||
cmd.ExecuteNonQuery();
|
||||
lock (m_dbLock)
|
||||
{
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -579,27 +579,25 @@ namespace OpenSim.Data.MySQL
|
||||
{
|
||||
dbcon.Open();
|
||||
|
||||
using (MySqlCommand cmd = new MySqlCommand(sql, dbcon))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("?folderID", folder.ID.ToString());
|
||||
cmd.Parameters.AddWithValue("?agentID", folder.Owner.ToString());
|
||||
cmd.Parameters.AddWithValue("?parentFolderID", folder.ParentID.ToString());
|
||||
cmd.Parameters.AddWithValue("?folderName", folderName);
|
||||
cmd.Parameters.AddWithValue("?type", folder.Type);
|
||||
cmd.Parameters.AddWithValue("?version", folder.Version);
|
||||
MySqlCommand cmd = new MySqlCommand(sql, dbcon);
|
||||
cmd.Parameters.AddWithValue("?folderID", folder.ID.ToString());
|
||||
cmd.Parameters.AddWithValue("?agentID", folder.Owner.ToString());
|
||||
cmd.Parameters.AddWithValue("?parentFolderID", folder.ParentID.ToString());
|
||||
cmd.Parameters.AddWithValue("?folderName", folderName);
|
||||
cmd.Parameters.AddWithValue("?type", folder.Type);
|
||||
cmd.Parameters.AddWithValue("?version", folder.Version);
|
||||
|
||||
try
|
||||
try
|
||||
{
|
||||
lock (m_dbLock)
|
||||
{
|
||||
lock (m_dbLock)
|
||||
{
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Error(e.ToString());
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Error(e.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -626,23 +624,21 @@ namespace OpenSim.Data.MySQL
|
||||
{
|
||||
dbcon.Open();
|
||||
|
||||
using (MySqlCommand cmd = new MySqlCommand(sql, dbcon))
|
||||
MySqlCommand cmd = new MySqlCommand(sql, dbcon);
|
||||
cmd.Parameters.AddWithValue("?folderID", folder.ID.ToString());
|
||||
cmd.Parameters.AddWithValue("?parentFolderID", folder.ParentID.ToString());
|
||||
|
||||
try
|
||||
{
|
||||
cmd.Parameters.AddWithValue("?folderID", folder.ID.ToString());
|
||||
cmd.Parameters.AddWithValue("?parentFolderID", folder.ParentID.ToString());
|
||||
|
||||
try
|
||||
lock (m_dbLock)
|
||||
{
|
||||
lock (m_dbLock)
|
||||
{
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Error(e.ToString());
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Error(e.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -63,14 +63,13 @@ namespace OpenSim.Data.MySQL
|
||||
|
||||
public void LogoutRegionAgents(UUID regionID)
|
||||
{
|
||||
using (MySqlCommand cmd = new MySqlCommand())
|
||||
{
|
||||
cmd.CommandText = String.Format("delete from {0} where `RegionID`=?RegionID", m_Realm);
|
||||
|
||||
cmd.Parameters.AddWithValue("?RegionID", regionID.ToString());
|
||||
|
||||
ExecuteNonQuery(cmd);
|
||||
}
|
||||
MySqlCommand cmd = new MySqlCommand();
|
||||
|
||||
cmd.CommandText = String.Format("delete from {0} where `RegionID`=?RegionID", m_Realm);
|
||||
|
||||
cmd.Parameters.AddWithValue("?RegionID", regionID.ToString());
|
||||
|
||||
ExecuteNonQuery(cmd);
|
||||
}
|
||||
|
||||
public bool ReportAgent(UUID sessionID, UUID regionID)
|
||||
@@ -82,32 +81,17 @@ namespace OpenSim.Data.MySQL
|
||||
if (regionID == UUID.Zero)
|
||||
return false;
|
||||
|
||||
using (MySqlCommand cmd = new MySqlCommand())
|
||||
{
|
||||
cmd.CommandText = String.Format("update {0} set RegionID=?RegionID, LastSeen=NOW() where `SessionID`=?SessionID", m_Realm);
|
||||
|
||||
cmd.Parameters.AddWithValue("?SessionID", sessionID.ToString());
|
||||
cmd.Parameters.AddWithValue("?RegionID", regionID.ToString());
|
||||
|
||||
if (ExecuteNonQuery(cmd) == 0)
|
||||
return false;
|
||||
}
|
||||
MySqlCommand cmd = new MySqlCommand();
|
||||
|
||||
return true;
|
||||
}
|
||||
cmd.CommandText = String.Format("update {0} set RegionID=?RegionID, LastSeen=NOW() where `SessionID`=?SessionID", m_Realm);
|
||||
|
||||
public bool VerifyAgent(UUID agentId, UUID secureSessionID)
|
||||
{
|
||||
PresenceData[] ret = Get("SecureSessionID",
|
||||
secureSessionID.ToString());
|
||||
cmd.Parameters.AddWithValue("?SessionID", sessionID.ToString());
|
||||
cmd.Parameters.AddWithValue("?RegionID", regionID.ToString());
|
||||
|
||||
if (ret.Length == 0)
|
||||
return false;
|
||||
|
||||
if(ret[0].UserID != agentId.ToString())
|
||||
if (ExecuteNonQuery(cmd) == 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,11 +30,11 @@ using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Reflection;
|
||||
using MySql.Data.MySqlClient;
|
||||
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Data;
|
||||
using RegionFlags = OpenSim.Framework.RegionFlags;
|
||||
using MySql.Data.MySqlClient;
|
||||
|
||||
namespace OpenSim.Data.MySQL
|
||||
{
|
||||
@@ -162,7 +162,17 @@ namespace OpenSim.Data.MySQL
|
||||
ret.sizeX = Convert.ToInt32(result["sizeX"]);
|
||||
ret.sizeY = Convert.ToInt32(result["sizeY"]);
|
||||
|
||||
CheckColumnNames(result);
|
||||
if (m_ColumnNames == null)
|
||||
{
|
||||
m_ColumnNames = new List<string>();
|
||||
|
||||
DataTable schemaTable = result.GetSchemaTable();
|
||||
foreach (DataRow row in schemaTable.Rows)
|
||||
{
|
||||
if (row["ColumnName"] != null)
|
||||
m_ColumnNames.Add(row["ColumnName"].ToString());
|
||||
}
|
||||
}
|
||||
|
||||
foreach (string s in m_ColumnNames)
|
||||
{
|
||||
@@ -177,11 +187,7 @@ namespace OpenSim.Data.MySQL
|
||||
if (s == "locY")
|
||||
continue;
|
||||
|
||||
object value = result[s];
|
||||
if (value is DBNull)
|
||||
ret.Data[s] = null;
|
||||
else
|
||||
ret.Data[s] = result[s].ToString();
|
||||
ret.Data[s] = result[s].ToString();
|
||||
}
|
||||
|
||||
retList.Add(ret);
|
||||
@@ -192,23 +198,6 @@ namespace OpenSim.Data.MySQL
|
||||
return retList;
|
||||
}
|
||||
|
||||
private void CheckColumnNames(IDataReader result)
|
||||
{
|
||||
if (m_ColumnNames != null)
|
||||
return;
|
||||
|
||||
List<string> columnNames = new List<string>();
|
||||
|
||||
DataTable schemaTable = result.GetSchemaTable();
|
||||
foreach (DataRow row in schemaTable.Rows)
|
||||
{
|
||||
if (row["ColumnName"] != null)
|
||||
columnNames.Add(row["ColumnName"].ToString());
|
||||
}
|
||||
|
||||
m_ColumnNames = columnNames;
|
||||
}
|
||||
|
||||
public bool Store(RegionData data)
|
||||
{
|
||||
if (data.Data.ContainsKey("uuid"))
|
||||
@@ -310,11 +299,6 @@ namespace OpenSim.Data.MySQL
|
||||
return Get((int)RegionFlags.DefaultRegion, scopeID);
|
||||
}
|
||||
|
||||
public List<RegionData> GetDefaultHypergridRegions(UUID scopeID)
|
||||
{
|
||||
return Get((int)RegionFlags.DefaultHGRegion, scopeID);
|
||||
}
|
||||
|
||||
public List<RegionData> GetFallbackRegions(UUID scopeID, int x, int y)
|
||||
{
|
||||
List<RegionData> regions = Get((int)RegionFlags.FallbackRegion, scopeID);
|
||||
@@ -334,12 +318,11 @@ namespace OpenSim.Data.MySQL
|
||||
if (scopeID != UUID.Zero)
|
||||
command += " and ScopeID = ?scopeID";
|
||||
|
||||
using (MySqlCommand cmd = new MySqlCommand(command))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString());
|
||||
|
||||
return RunCommand(cmd);
|
||||
}
|
||||
MySqlCommand cmd = new MySqlCommand(command);
|
||||
|
||||
cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString());
|
||||
|
||||
return RunCommand(cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -62,24 +62,23 @@ namespace OpenSim.Data.MySQL
|
||||
if (words.Length > 2)
|
||||
return new UserAccountData[0];
|
||||
|
||||
using (MySqlCommand cmd = new MySqlCommand())
|
||||
{
|
||||
if (words.Length == 1)
|
||||
{
|
||||
cmd.CommandText = String.Format("select * from {0} where (ScopeID=?ScopeID or ScopeID='00000000-0000-0000-0000-000000000000') and (FirstName like ?search or LastName like ?search)", m_Realm);
|
||||
cmd.Parameters.AddWithValue("?search", "%" + words[0] + "%");
|
||||
cmd.Parameters.AddWithValue("?ScopeID", scopeID.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
cmd.CommandText = String.Format("select * from {0} where (ScopeID=?ScopeID or ScopeID='00000000-0000-0000-0000-000000000000') and (FirstName like ?searchFirst or LastName like ?searchLast)", m_Realm);
|
||||
cmd.Parameters.AddWithValue("?searchFirst", "%" + words[0] + "%");
|
||||
cmd.Parameters.AddWithValue("?searchLast", "%" + words[1] + "%");
|
||||
cmd.Parameters.AddWithValue("?ScopeID", scopeID.ToString());
|
||||
}
|
||||
MySqlCommand cmd = new MySqlCommand();
|
||||
|
||||
return DoQuery(cmd);
|
||||
if (words.Length == 1)
|
||||
{
|
||||
cmd.CommandText = String.Format("select * from {0} where (ScopeID=?ScopeID or ScopeID='00000000-0000-0000-0000-000000000000') and (FirstName like ?search or LastName like ?search)", m_Realm);
|
||||
cmd.Parameters.AddWithValue("?search", "%" + words[0] + "%");
|
||||
cmd.Parameters.AddWithValue("?ScopeID", scopeID.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
cmd.CommandText = String.Format("select * from {0} where (ScopeID=?ScopeID or ScopeID='00000000-0000-0000-0000-000000000000') and (FirstName like ?searchFirst or LastName like ?searchLast)", m_Realm);
|
||||
cmd.Parameters.AddWithValue("?searchFirst", "%" + words[0] + "%");
|
||||
cmd.Parameters.AddWithValue("?searchLast", "%" + words[1] + "%");
|
||||
cmd.Parameters.AddWithValue("?ScopeID", scopeID.ToString());
|
||||
}
|
||||
|
||||
return DoQuery(cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user