Compare commits
646 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3dd5d8508c | ||
|
|
2a15739935 | ||
|
|
fabe054608 | ||
|
|
fe1ae9db1b | ||
|
|
12ce20a203 | ||
|
|
45e280274c | ||
|
|
e87a0d9db1 | ||
|
|
62e9cdd72a | ||
|
|
3730163e5d | ||
|
|
4e3a2d3a64 | ||
|
|
e9447cc836 | ||
|
|
693a3ea8fa | ||
|
|
7e2927f537 | ||
|
|
ba745a524d | ||
|
|
cf8b6efaf2 | ||
|
|
40f7062d02 | ||
|
|
81fe05bb84 | ||
|
|
ed6aabb197 | ||
|
|
8542f34d7d | ||
|
|
025ac85a46 | ||
|
|
5edffc9ecd | ||
|
|
56a3d2f00d | ||
|
|
28babf307e | ||
|
|
03c6d2b0b4 | ||
|
|
b293242017 | ||
|
|
924ca8e2e9 | ||
|
|
86630a9010 | ||
|
|
68fcb132d9 | ||
|
|
6f582aeaff | ||
|
|
fa1f6031ca | ||
|
|
eea3be9b17 | ||
|
|
698dfe8977 | ||
|
|
25757a6abb | ||
|
|
5a1017241f | ||
|
|
76ee671dc6 | ||
|
|
2cdef143c4 | ||
|
|
34a645efb6 | ||
|
|
02980336a3 | ||
|
|
8899f2e2bb | ||
|
|
60d4b0999c | ||
|
|
a8edc908e0 | ||
|
|
901602411c | ||
|
|
d98a19b398 | ||
|
|
e8f363ff90 | ||
|
|
5e4cf1b84c | ||
|
|
ffe07527fc | ||
|
|
72456f90a4 | ||
|
|
0cf5ea9420 | ||
|
|
becb949a33 | ||
|
|
63a6998409 | ||
|
|
15f323295b | ||
|
|
2c823c9f72 | ||
|
|
d541f150d0 | ||
|
|
4da471a5aa | ||
|
|
75d21aa71a | ||
|
|
88e9cd0eee | ||
|
|
26ec918ec8 | ||
|
|
4bc2201453 | ||
|
|
344db4dc0b | ||
|
|
de6e3edfbb | ||
|
|
a1e92dead2 | ||
|
|
068cab94e0 | ||
|
|
7b66ef44c3 | ||
|
|
dcbe9d1ffb | ||
|
|
27597463da | ||
|
|
3a477a29d7 | ||
|
|
3f703ae1cb | ||
|
|
c32ccfb520 | ||
|
|
9ca86664bb | ||
|
|
464d31b70b | ||
|
|
5622cf68aa | ||
|
|
394ec508f6 | ||
|
|
bcaacb4e41 | ||
|
|
d131c57978 | ||
|
|
987c56984d | ||
|
|
e19c830a6c | ||
|
|
fab0389cb1 | ||
|
|
d2877b9cd4 | ||
|
|
b778bd9423 | ||
|
|
449548d7a4 | ||
|
|
33cc847c4a | ||
|
|
5aeaa7fcdd | ||
|
|
e68867c9b6 | ||
|
|
1fa3a6f1bd | ||
|
|
ff9da24465 | ||
|
|
227685bea4 | ||
|
|
20f20895cf | ||
|
|
9bae636ff0 | ||
|
|
cf95b65c10 | ||
|
|
250ea09328 | ||
|
|
b3a496d6f2 | ||
|
|
f55e153636 | ||
|
|
fbcb76383d | ||
|
|
72c67c5091 | ||
|
|
5015b0b485 | ||
|
|
c78a8271c4 | ||
|
|
fbed245596 | ||
|
|
174df94172 | ||
|
|
3fbaef9275 | ||
|
|
16bf38e1ab | ||
|
|
f8b8241239 | ||
|
|
bffc9ad184 | ||
|
|
15b50ae737 | ||
|
|
65a135f4d3 | ||
|
|
1b156b7fe8 | ||
|
|
b7c7293c7a | ||
|
|
f7b2aa0f49 | ||
|
|
04aa13a086 | ||
|
|
251b93d97e | ||
|
|
a1b291c889 | ||
|
|
5b433e101d | ||
|
|
d93275745b | ||
|
|
32070fa5f4 | ||
|
|
9479f64778 | ||
|
|
5ec3429843 | ||
|
|
77a331fce3 | ||
|
|
b46be88db6 | ||
|
|
3a6f312484 | ||
|
|
47b84875fd | ||
|
|
78733b979f | ||
|
|
dd30a29ba0 | ||
|
|
882af7195c | ||
|
|
96e5836b50 | ||
|
|
ab1472e5b7 | ||
|
|
922f76a3a7 | ||
|
|
0be9e3b079 | ||
|
|
4a74c4533c | ||
|
|
d2c738fc09 | ||
|
|
6dc1b113d0 | ||
|
|
d32d25634d | ||
|
|
7c12dfe185 | ||
|
|
2f7539a25b | ||
|
|
0c0ee95bd8 | ||
|
|
c23d37a509 | ||
|
|
4569c595bf | ||
|
|
484aa72ff8 | ||
|
|
8ad29fc5c8 | ||
|
|
87e2668529 | ||
|
|
515d373a8e | ||
|
|
bbc1dc6bce | ||
|
|
8457044b2f | ||
|
|
19d8f05584 | ||
|
|
7db4336f1c | ||
|
|
faf9ba53fc | ||
|
|
bf8f64e40e | ||
|
|
73891c7fd3 | ||
|
|
667a272cce | ||
|
|
f41809e07d | ||
|
|
afb938e579 | ||
|
|
a31393ba0b | ||
|
|
a845c1a893 | ||
|
|
093705efd1 | ||
|
|
f4cba27105 | ||
|
|
3db9b847bf | ||
|
|
2b33677402 | ||
|
|
812f5e124d | ||
|
|
2fbafc7465 | ||
|
|
c38736de82 | ||
|
|
e44450cce1 | ||
|
|
766c94213c | ||
|
|
78015bbbdc | ||
|
|
9e83b43009 | ||
|
|
8b3c2f7d0c | ||
|
|
cecb446e0e | ||
|
|
0faba7dc33 | ||
|
|
e245638f24 | ||
|
|
c9742c826d | ||
|
|
539165e6bd | ||
|
|
95eeb4dde8 | ||
|
|
ef262799ca | ||
|
|
614b9e14c4 | ||
|
|
eb79c882ea | ||
|
|
1e5cff32fc | ||
|
|
df49196e17 | ||
|
|
0fe08c8799 | ||
|
|
7862d1e20d | ||
|
|
13b2ac1425 | ||
|
|
7f570636f8 | ||
|
|
5a10da3ee8 | ||
|
|
53b72ab4b8 | ||
|
|
3a2c099169 | ||
|
|
c31d93cb6f | ||
|
|
f0411dc128 | ||
|
|
7c121a2acc | ||
|
|
f0eeb47262 | ||
|
|
44f533d95a | ||
|
|
7bb673a854 | ||
|
|
5d01a1ff4d | ||
|
|
253110293a | ||
|
|
5fc61942e0 | ||
|
|
d4eee213a9 | ||
|
|
2dbc18054e | ||
|
|
88f7a833dc | ||
|
|
06e4fcd260 | ||
|
|
df89e15290 | ||
|
|
63aea3a5f2 | ||
|
|
cb8c3ba023 | ||
|
|
2e216aa056 | ||
|
|
9664273df6 | ||
|
|
2227f51b29 | ||
|
|
38acda9f29 | ||
|
|
904baa6da6 | ||
|
|
a108fcac95 | ||
|
|
2572ed9ed9 | ||
|
|
cf54df3ecf | ||
|
|
1d9a9e6004 | ||
|
|
0d898d8d8a | ||
|
|
463d0b2f8f | ||
|
|
bc06db3df4 | ||
|
|
e8a2eff2e8 | ||
|
|
d62f0bc35d | ||
|
|
d15a3b10a3 | ||
|
|
6efc203ce8 | ||
|
|
d1865c526d | ||
|
|
98c1940820 | ||
|
|
5dc0298f83 | ||
|
|
7180690a14 | ||
|
|
0b743045ef | ||
|
|
5092cbd77e | ||
|
|
cb1f2886cd | ||
|
|
7a5699224e | ||
|
|
328bc3b76e | ||
|
|
b01e73cf27 | ||
|
|
7eb12f96ec | ||
|
|
2506b3d89e | ||
|
|
018832522c | ||
|
|
ca78c8326e | ||
|
|
998d7009a6 | ||
|
|
617bc4710a | ||
|
|
2c9859314f | ||
|
|
eb5bfd14fa | ||
|
|
85f4357ce6 | ||
|
|
a893fd90cd | ||
|
|
93a9ed2a6d | ||
|
|
4cac87d9f4 | ||
|
|
538ff31b28 | ||
|
|
06db136fbc | ||
|
|
acc2c42a79 | ||
|
|
b065c02661 | ||
|
|
bc969a6b46 | ||
|
|
3f76f72137 | ||
|
|
52f8669169 | ||
|
|
853c0fccc8 | ||
|
|
090f9bcece | ||
|
|
3185db7f94 | ||
|
|
a780e01a54 | ||
|
|
63fd027494 | ||
|
|
b3ebec184f | ||
|
|
e1dd228f18 | ||
|
|
c8914d22eb | ||
|
|
574a11558d | ||
|
|
5d964a6424 | ||
|
|
18b91fdbe9 | ||
|
|
f0998a9222 | ||
|
|
7c148d9b2f | ||
|
|
de0ab04d00 | ||
|
|
530c86335d | ||
|
|
562a3cb338 | ||
|
|
32ad66c274 | ||
|
|
c725ad1577 | ||
|
|
06e0528d0b | ||
|
|
cf1686335f | ||
|
|
af406748a2 | ||
|
|
e00f1a0410 | ||
|
|
86105a1533 | ||
|
|
c0fd09b445 | ||
|
|
85d51e57a9 | ||
|
|
55cc8044cb | ||
|
|
f3508649f5 | ||
|
|
abe0f4a088 | ||
|
|
d4acaf25af | ||
|
|
cacbb5c165 | ||
|
|
86a2cd915c | ||
|
|
2c00b73cd2 | ||
|
|
8b8e1b88ec | ||
|
|
aec723b955 | ||
|
|
6b1d09813e | ||
|
|
50eec6df52 | ||
|
|
3c5b7d7b79 | ||
|
|
4aa483777b | ||
|
|
672bd9fc98 | ||
|
|
01daa74adf | ||
|
|
6d2893be67 | ||
|
|
65c4cb48ac | ||
|
|
9406db3047 | ||
|
|
e756457703 | ||
|
|
6ac9c9c972 | ||
|
|
91b7679db9 | ||
|
|
17929abd28 | ||
|
|
5cb4044539 | ||
|
|
e6d0dcd4e8 | ||
|
|
2051535ce1 | ||
|
|
0301c81b01 | ||
|
|
9211361b19 | ||
|
|
6b65895736 | ||
|
|
559c66afe6 | ||
|
|
aa217cf90f | ||
|
|
bbfda8e19e | ||
|
|
fad0fd7f75 | ||
|
|
d1c3f8eef5 | ||
|
|
ac16a667e1 | ||
|
|
7bafee28fa | ||
|
|
46095c058e | ||
|
|
e5a5b69b08 | ||
|
|
43eab5e163 | ||
|
|
444737c830 | ||
|
|
7cb1690589 | ||
|
|
0af8886400 | ||
|
|
4cbd45f3d5 | ||
|
|
59d0e3c3c8 | ||
|
|
635f3f77ab | ||
|
|
6557eba235 | ||
|
|
1fe504fee5 | ||
|
|
f360b687d6 | ||
|
|
ba5a236922 | ||
|
|
20640357ab | ||
|
|
45ada5ca2d | ||
|
|
9c7b28341c | ||
|
|
a15282f023 | ||
|
|
161c827a44 | ||
|
|
76add0fdb0 | ||
|
|
af54e6f370 | ||
|
|
e7fa8a4699 | ||
|
|
262892336b | ||
|
|
1247174db4 | ||
|
|
de941d2ec7 | ||
|
|
b0bae62c30 | ||
|
|
7a4c5b067d | ||
|
|
6c447f892e | ||
|
|
5e8dfb4f7e | ||
|
|
7a47c15edb | ||
|
|
14a7ddb885 | ||
|
|
2fbb906ff6 | ||
|
|
62a03a5cac | ||
|
|
d3387d591a | ||
|
|
cffea984f1 | ||
|
|
99308d64c6 | ||
|
|
6d1d58b654 | ||
|
|
14836e60ff | ||
|
|
9aec36156e | ||
|
|
fce3fca7f9 | ||
|
|
542bef20e8 | ||
|
|
dba33fee39 | ||
|
|
b1d8aa0b64 | ||
|
|
8ecab21b37 | ||
|
|
368b29a680 | ||
|
|
f90aee696a | ||
|
|
f901a38204 | ||
|
|
4289b71141 | ||
|
|
e131e73652 | ||
|
|
84d7227dfd | ||
|
|
b13214af27 | ||
|
|
e735f76553 | ||
|
|
4031933475 | ||
|
|
8555e54e22 | ||
|
|
7c0ebcb984 | ||
|
|
091f3a8000 | ||
|
|
e12c044eab | ||
|
|
8276a9e5f7 | ||
|
|
6a477e044d | ||
|
|
1769e93c42 | ||
|
|
1a32b35279 | ||
|
|
305f5110c6 | ||
|
|
35078e03e5 | ||
|
|
5fd9411143 | ||
|
|
0ff61341e4 | ||
|
|
8cec0b3fa1 | ||
|
|
1b30ae81b5 | ||
|
|
b9e0d0fdb2 | ||
|
|
1d4551e52f | ||
|
|
c8583e566d | ||
|
|
a2dd8f31de | ||
|
|
6edc446780 | ||
|
|
bf68dbabd7 | ||
|
|
89945f8829 | ||
|
|
edc04d4184 | ||
|
|
5b2af7f99e | ||
|
|
df9845a283 | ||
|
|
7496d0b0f7 | ||
|
|
4bccfed80c | ||
|
|
eaf99bf928 | ||
|
|
f5ae36d7e2 | ||
|
|
425d76bb98 | ||
|
|
921f0052f4 | ||
|
|
6734b94761 | ||
|
|
773ffcafc3 | ||
|
|
62b3bdf0fc | ||
|
|
b0cb0ec02f | ||
|
|
81c9952e99 | ||
|
|
db83208794 | ||
|
|
ff5c38534d | ||
|
|
58d7e3b8ed | ||
|
|
949139eb0b | ||
|
|
fe16a72a9a | ||
|
|
58def34dbe | ||
|
|
d4dad75a3c | ||
|
|
ebe7726cd7 | ||
|
|
a4d322dcd1 | ||
|
|
ccf18fd2ef | ||
|
|
3d0778bcd6 | ||
|
|
a5800f479e | ||
|
|
178a5a5585 | ||
|
|
6664079f84 | ||
|
|
fb312279c9 | ||
|
|
f8caf41bd8 | ||
|
|
47e7febebc | ||
|
|
33ae733006 | ||
|
|
da25903300 | ||
|
|
7f027552ec | ||
|
|
d04bb3ca9b | ||
|
|
bd6f734d3a | ||
|
|
b5f94c72b9 | ||
|
|
220ea9f687 | ||
|
|
61353dde80 | ||
|
|
cf97535d9e | ||
|
|
52b7b40034 | ||
|
|
1497b75361 | ||
|
|
9858766516 | ||
|
|
e6080a38c5 | ||
|
|
1d0a9e521c | ||
|
|
fad1d70180 | ||
|
|
9e0d419239 | ||
|
|
eed343ed8a | ||
|
|
7df325c275 | ||
|
|
fdcd392582 | ||
|
|
f27766d47b | ||
|
|
a660c0a750 | ||
|
|
8ce3fa646b | ||
|
|
e82d394ddf | ||
|
|
d5f5649750 | ||
|
|
c605c7a7b7 | ||
|
|
a53272c5fb | ||
|
|
ae56b946cf | ||
|
|
01520bbb3e | ||
|
|
f3e177814a | ||
|
|
873eee5431 | ||
|
|
6a279feb2f | ||
|
|
296d63e20b | ||
|
|
beba20846f | ||
|
|
7112ee0015 | ||
|
|
86630a1b70 | ||
|
|
d975b42f6a | ||
|
|
8edf4225f3 | ||
|
|
6b17c9bd98 | ||
|
|
71c808cd32 | ||
|
|
3e8f593bf2 | ||
|
|
742f505440 | ||
|
|
0237d9113d | ||
|
|
120f872d2b | ||
|
|
932c9e757b | ||
|
|
77e7bbcbf7 | ||
|
|
4f67286044 | ||
|
|
cfd3e8f0ea | ||
|
|
abcb2cdb36 | ||
|
|
a96601478c | ||
|
|
e3c4936dea | ||
|
|
da990d01f2 | ||
|
|
12f2648a57 | ||
|
|
9de3fe9410 | ||
|
|
8225e3f40c | ||
|
|
3c05d67094 | ||
|
|
6b7625a56b | ||
|
|
71918eeab4 | ||
|
|
ddd38a3dea | ||
|
|
58c0ed78d4 | ||
|
|
470d053443 | ||
|
|
ed14e97bb4 | ||
|
|
aa2fb1ec25 | ||
|
|
14569992e1 | ||
|
|
4e6f7435d0 | ||
|
|
39ed382ddf | ||
|
|
c9415fd763 | ||
|
|
31de7b845f | ||
|
|
5038a59ef3 | ||
|
|
88b1fc1382 | ||
|
|
94ad69faf2 | ||
|
|
5fafea6631 | ||
|
|
1f4f09ad69 | ||
|
|
91333b9267 | ||
|
|
ed760f2586 | ||
|
|
d7c9725ec0 | ||
|
|
6955190c7d | ||
|
|
ce5d308d23 | ||
|
|
0e23374aa2 | ||
|
|
26fe59c35e | ||
|
|
bc9952f901 | ||
|
|
fd1b2a1c57 | ||
|
|
0f03c64a0c | ||
|
|
d6837f5dc7 | ||
|
|
0b213af675 | ||
|
|
cddf1ec0dc | ||
|
|
97c74afca8 | ||
|
|
d27e188fe2 | ||
|
|
11b4f534c2 | ||
|
|
d50d169441 | ||
|
|
28419251bf | ||
|
|
d1bb73d068 | ||
|
|
4d1426e77d | ||
|
|
a2866b85f3 | ||
|
|
269a6410a0 | ||
|
|
c26f01ff8c | ||
|
|
fc9930e420 | ||
|
|
79200ed270 | ||
|
|
7fc289c039 | ||
|
|
877bdcdce1 | ||
|
|
bdbbeaa494 | ||
|
|
f6913e911e | ||
|
|
f74aafaf63 | ||
|
|
4fed301e65 | ||
|
|
733e067958 | ||
|
|
ffd0da23fb | ||
|
|
f49d513089 | ||
|
|
fc35b45e21 | ||
|
|
bc7fda39b4 | ||
|
|
e10012a7a6 | ||
|
|
3a7c8d1f32 | ||
|
|
c0cc5e0fa4 | ||
|
|
b83a224147 | ||
|
|
4a1c1fc009 | ||
|
|
cf61cdf58c | ||
|
|
1913ab5ad5 | ||
|
|
29c8461631 | ||
|
|
8f372b8ac8 | ||
|
|
342be228c6 | ||
|
|
87abf06956 | ||
|
|
f81841a2c5 | ||
|
|
1b41ec0a85 | ||
|
|
31cba5aa66 | ||
|
|
1aed6567a8 | ||
|
|
f0f852b27f | ||
|
|
1197658233 | ||
|
|
e1d1c27965 | ||
|
|
49c2213a01 | ||
|
|
41b6602a77 | ||
|
|
8c6a0cb44a | ||
|
|
2a4dd34616 | ||
|
|
9c97fb8e12 | ||
|
|
a8e64cd59a | ||
|
|
abb193ec94 | ||
|
|
b2878eb773 | ||
|
|
b8e22f02e7 | ||
|
|
1380b37d71 | ||
|
|
3d62f4369d | ||
|
|
d405254971 | ||
|
|
9db4090c07 | ||
|
|
c9550e473d | ||
|
|
257f9cec40 | ||
|
|
13bb9ea682 | ||
|
|
67ec95bde8 | ||
|
|
c467dfcd81 | ||
|
|
b73baeb4a4 | ||
|
|
b50e5704b8 | ||
|
|
7807b19a89 | ||
|
|
bdab05df0e | ||
|
|
0842e2e15b | ||
|
|
fbf33ef1de | ||
|
|
3f5c6c897f | ||
|
|
1900254e77 | ||
|
|
678c107915 | ||
|
|
dde0e547a7 | ||
|
|
226b5e4d75 | ||
|
|
cfe1bced7d | ||
|
|
2877c7d94d | ||
|
|
0c3493f619 | ||
|
|
d25265ae82 | ||
|
|
1d533b0f01 | ||
|
|
bfb0011cd3 | ||
|
|
e5d59dc696 | ||
|
|
8eec717f5f | ||
|
|
4faf11e001 | ||
|
|
49af6b53e7 | ||
|
|
13a9d5409c | ||
|
|
6831e58616 | ||
|
|
afb2e07111 | ||
|
|
674a3a5639 | ||
|
|
4c362a83f9 | ||
|
|
90fa3202c6 | ||
|
|
5e6a47f13f | ||
|
|
6fbfb47b92 | ||
|
|
dd6db72939 | ||
|
|
f127e4b4ee | ||
|
|
54a4b9eab4 | ||
|
|
813f0da00b | ||
|
|
08fa0a6a8a | ||
|
|
60de0bc3c2 | ||
|
|
cc5cffc212 | ||
|
|
1eea6fd452 | ||
|
|
3760d10cd0 | ||
|
|
1cf17a3cf7 | ||
|
|
fd045d520e | ||
|
|
9984ecf862 | ||
|
|
01c0bbf181 | ||
|
|
2d2bea4aa7 | ||
|
|
e5f7c8b6e8 | ||
|
|
b40b57776b | ||
|
|
5c9fa15f30 | ||
|
|
a01862509e | ||
|
|
6937eec258 | ||
|
|
13a9a4b653 | ||
|
|
4eb52eb19e | ||
|
|
31bacfbb63 | ||
|
|
6cd0d7a62b | ||
|
|
109136c074 | ||
|
|
7aa00632b9 | ||
|
|
3193bcaae1 | ||
|
|
604b39cea9 | ||
|
|
d67236c09d | ||
|
|
e2a1fa806d | ||
|
|
c12e68e34d | ||
|
|
7061784cc6 | ||
|
|
beeec1c467 | ||
|
|
a7a837550e | ||
|
|
f7bd0da026 | ||
|
|
a75ce7423c | ||
|
|
d0854e4ace | ||
|
|
c931b16c1f | ||
|
|
f2810bf03a | ||
|
|
cd1a23fc14 | ||
|
|
ac94dc8a14 | ||
|
|
9bf363e9be | ||
|
|
79b031bd0c | ||
|
|
6df7d4219d | ||
|
|
f66737fe56 | ||
|
|
92c06a5d0b | ||
|
|
976530569a | ||
|
|
ff5885ab23 | ||
|
|
39777db8ef | ||
|
|
2be0347f50 | ||
|
|
c581506058 | ||
|
|
8937a2244d | ||
|
|
97bc5263de | ||
|
|
86bf79aa2b | ||
|
|
7416809077 | ||
|
|
25ae59b9eb | ||
|
|
9b150194f6 | ||
|
|
8c432c7c9b | ||
|
|
8c1d80fdfd | ||
|
|
aea5d3a842 | ||
|
|
fa1c688342 | ||
|
|
139639d25e | ||
|
|
317c04fe17 | ||
|
|
fbc9072a5c | ||
|
|
7fa64cce7d | ||
|
|
ab1474b5de | ||
|
|
0765a83a8c | ||
|
|
96abbbb6fb |
@@ -19,10 +19,14 @@ Prereqs:
|
||||
|
||||
From the distribution type:
|
||||
* ./runprebuild.sh
|
||||
* nant (or xbuild)
|
||||
* nant (or !* xbuild)
|
||||
* cd bin
|
||||
* copy OpenSim.ini.example to OpenSim.ini and other appropriate files in bin/config-include
|
||||
* run mono OpenSim.exe
|
||||
!* xbuild option switches
|
||||
!* clean: xbuild /target:clean
|
||||
!* debug: (default) xbuild /property:Configuration=Debug
|
||||
!* release: xbuild /property:Configuration=Release
|
||||
|
||||
# Using Monodevelop
|
||||
|
||||
|
||||
@@ -9,13 +9,15 @@ people that make the day to day of OpenSim happen.
|
||||
* dahlia
|
||||
* Melanie Thielker
|
||||
* Diva (Crista Lopes, University of California, Irvine)
|
||||
* Dan Lake (Intel)
|
||||
* Dan Lake
|
||||
* Marck
|
||||
* Mic Bowman (Intel)
|
||||
* Mic Bowman
|
||||
* BlueWall (James Hughes)
|
||||
* Nebadon Izumi (Michael Cerquoni, OSgrid)
|
||||
* Snoopy Pfeffer
|
||||
* Robert Adams (Intel)
|
||||
* Robert Adams
|
||||
* Oren Hurvitz (Kitely)
|
||||
* Kevin Cozens
|
||||
|
||||
= Core Developers Following the White Rabbit =
|
||||
Core developers who have temporarily (we hope) gone chasing the white rabbit.
|
||||
@@ -66,6 +68,7 @@ what it is today.
|
||||
* alex_carnell
|
||||
* Alan Webb (IBM)
|
||||
* Aleric
|
||||
* Alicia Raven
|
||||
* Allen Kerensky
|
||||
* BigFootAg
|
||||
* BlueWall Slade
|
||||
@@ -78,12 +81,13 @@ what it is today.
|
||||
* ctrlaltdavid (David Rowe)
|
||||
* Daedius
|
||||
* daTwitch
|
||||
* Dev Random
|
||||
* devalnor-#708
|
||||
* dmiles (Daxtron Labs)
|
||||
* Dong Jun Lan (IBM)
|
||||
* DoranZemlja
|
||||
* dr0b3rts
|
||||
* dslake (Intel)
|
||||
* dslake
|
||||
* FredoChaplin
|
||||
* Garmin Kawaguichi
|
||||
* Gerhard
|
||||
@@ -97,10 +101,12 @@ what it is today.
|
||||
* Flyte Xevious
|
||||
* Garmin Kawaguichi
|
||||
* Gryc Ueusp
|
||||
* H-H-H (ginge264)
|
||||
* Hiro Lecker
|
||||
* Iain Oliver
|
||||
* Imaze Rhiano
|
||||
* Intimidated
|
||||
* Jak Daniels
|
||||
* Jeremy Bongio (IBM)
|
||||
* jhurliman
|
||||
* John R Sohn (XenReborn)
|
||||
@@ -108,26 +114,30 @@ what it is today.
|
||||
* Jon Cundill
|
||||
* Junta Kohime
|
||||
* Kayne
|
||||
* Kevin Cozens
|
||||
* kinoc (Daxtron Labs)
|
||||
* Kira
|
||||
* Kitto Flora
|
||||
* KittyLiu
|
||||
* Kurt Taylor (IBM)
|
||||
* Lani Global
|
||||
* lillith_xue
|
||||
* lkalif
|
||||
* LuciusSirnah
|
||||
* lulurun
|
||||
* M.Igarashi
|
||||
* maimedleech
|
||||
* Mana Janus
|
||||
* MarcelEdward
|
||||
* Matt Lehmann
|
||||
* Mic Bowman
|
||||
* Michelle Argus
|
||||
* Michael Cortez (The Flotsam Project, http://osflotsam.org/)
|
||||
* Micheil Merlin
|
||||
* Mike Osias (IBM)
|
||||
* Mike Pitman (IBM)
|
||||
* mikemig
|
||||
* mikkopa/_someone - RealXtend
|
||||
* Misterblue (Intel)
|
||||
* Misterblue
|
||||
* Mircea Kitsune
|
||||
* mpallari
|
||||
* MrMonkE
|
||||
@@ -136,7 +146,6 @@ what it is today.
|
||||
* nornalbion
|
||||
* Omar Vera Ustariz (IBM)
|
||||
* openlifegrid.com
|
||||
* Oren Hurvitz (Kitely)
|
||||
* otakup0pe
|
||||
* Pixel Tomsen
|
||||
* ralphos
|
||||
@@ -145,6 +154,7 @@ what it is today.
|
||||
* Richard Alimi (IBM)
|
||||
* Rick Alther (IBM)
|
||||
* Rob Smart (IBM)
|
||||
* Roger Kirkman (zadark)
|
||||
* rtomita
|
||||
* Ruud Lathorp
|
||||
* SachaMagne
|
||||
|
||||
@@ -56,8 +56,8 @@ namespace OpenSim.Groups
|
||||
private IGroupsServicesConnector m_groupData = null;
|
||||
|
||||
// Config Options
|
||||
private bool m_groupMessagingEnabled = false;
|
||||
private bool m_debugEnabled = true;
|
||||
private bool m_groupMessagingEnabled;
|
||||
private bool m_debugEnabled;
|
||||
|
||||
/// <summary>
|
||||
/// If enabled, module only tries to send group IMs to online users by querying cached presence information.
|
||||
@@ -83,7 +83,6 @@ namespace OpenSim.Groups
|
||||
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)
|
||||
@@ -111,9 +110,17 @@ namespace OpenSim.Groups
|
||||
m_messageOnlineAgentsOnly = groupsConfig.GetBoolean("MessageOnlineUsersOnly", false);
|
||||
|
||||
if (m_messageOnlineAgentsOnly)
|
||||
{
|
||||
m_usersOnlineCache = new ExpiringCache<UUID, PresenceInfo[]>();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.Error("[Groups.Messaging]: GroupsMessagingModule V2 requires MessageOnlineUsersOnly = true");
|
||||
m_groupMessagingEnabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
m_debugEnabled = groupsConfig.GetBoolean("DebugEnabled", true);
|
||||
m_debugEnabled = groupsConfig.GetBoolean("MessagingDebugEnabled", m_debugEnabled);
|
||||
|
||||
m_log.InfoFormat(
|
||||
"[Groups.Messaging]: GroupsMessagingModule enabled with MessageOnlineOnly = {0}, DebugEnabled = {1}",
|
||||
@@ -133,6 +140,14 @@ namespace OpenSim.Groups
|
||||
scene.EventManager.OnMakeChildAgent += OnMakeChildAgent;
|
||||
scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage;
|
||||
scene.EventManager.OnClientLogin += OnClientLogin;
|
||||
|
||||
scene.AddCommand(
|
||||
"Debug",
|
||||
this,
|
||||
"debug groups messaging verbose",
|
||||
"debug groups messaging verbose <true|false>",
|
||||
"This setting turns on very verbose groups messaging debugging",
|
||||
HandleDebugGroupsMessagingVerbose);
|
||||
}
|
||||
|
||||
public void RegionLoaded(Scene scene)
|
||||
@@ -172,10 +187,8 @@ namespace OpenSim.Groups
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (m_presenceService == null)
|
||||
m_presenceService = scene.PresenceService;
|
||||
|
||||
}
|
||||
|
||||
public void RemoveRegion(Scene scene)
|
||||
@@ -222,6 +235,25 @@ namespace OpenSim.Groups
|
||||
|
||||
#endregion
|
||||
|
||||
private void HandleDebugGroupsMessagingVerbose(object modules, string[] args)
|
||||
{
|
||||
if (args.Length < 5)
|
||||
{
|
||||
MainConsole.Instance.Output("Usage: debug groups messaging verbose <true|false>");
|
||||
return;
|
||||
}
|
||||
|
||||
bool verbose = false;
|
||||
if (!bool.TryParse(args[4], out verbose))
|
||||
{
|
||||
MainConsole.Instance.Output("Usage: debug groups messaging verbose <true|false>");
|
||||
return;
|
||||
}
|
||||
|
||||
m_debugEnabled = verbose;
|
||||
|
||||
MainConsole.Instance.OutputFormat("{0} verbose logging set to {1}", Name, m_debugEnabled);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Not really needed, but does confirm that the group exists.
|
||||
@@ -242,11 +274,23 @@ namespace OpenSim.Groups
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void SendMessageToGroup(GridInstantMessage im, UUID groupID)
|
||||
{
|
||||
SendMessageToGroup(im, groupID, UUID.Zero, null);
|
||||
}
|
||||
|
||||
public void SendMessageToGroup(
|
||||
GridInstantMessage im, UUID groupID, UUID sendingAgentForGroupCalls, Func<GroupMembersData, bool> sendCondition)
|
||||
{
|
||||
int requestStartTick = Environment.TickCount;
|
||||
|
||||
UUID fromAgentID = new UUID(im.fromAgentID);
|
||||
|
||||
// Unlike current XmlRpcGroups, Groups V2 can accept UUID.Zero when a perms check for the requesting agent
|
||||
// is not necessary.
|
||||
List<GroupMembersData> groupMembers = m_groupData.GetGroupMembers(UUID.Zero.ToString(), groupID);
|
||||
|
||||
int groupMembersCount = groupMembers.Count;
|
||||
PresenceInfo[] onlineAgents = null;
|
||||
|
||||
@@ -254,7 +298,7 @@ namespace OpenSim.Groups
|
||||
// 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
|
||||
// We cache in order not to overwhelm 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))
|
||||
@@ -273,8 +317,6 @@ namespace OpenSim.Groups
|
||||
// "[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);
|
||||
@@ -299,12 +341,27 @@ namespace OpenSim.Groups
|
||||
|
||||
if (clientsAlreadySent.Contains(member.AgentID))
|
||||
continue;
|
||||
|
||||
clientsAlreadySent.Add(member.AgentID);
|
||||
|
||||
if (hasAgentDroppedGroupChatSession(member.AgentID.ToString(), groupID))
|
||||
if (sendCondition != null)
|
||||
{
|
||||
if (!sendCondition(member))
|
||||
{
|
||||
if (m_debugEnabled)
|
||||
m_log.DebugFormat(
|
||||
"[Groups.Messaging]: Not sending to {0} as they do not fulfill send condition",
|
||||
member.AgentID);
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else 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);
|
||||
if (m_debugEnabled)
|
||||
m_log.DebugFormat("[Groups.Messaging]: {0} has dropped session, not delivering to them", member.AgentID);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -45,9 +45,6 @@ namespace OpenSim.Groups
|
||||
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GroupsModule")]
|
||||
public class GroupsModule : ISharedRegionModule, IGroupsModule
|
||||
{
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
|
||||
private static readonly ILog m_log =
|
||||
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
@@ -104,7 +101,7 @@ namespace OpenSim.Groups
|
||||
{
|
||||
scene.RegisterModuleInterface<IGroupsModule>(this);
|
||||
scene.AddCommand(
|
||||
"debug",
|
||||
"Debug",
|
||||
this,
|
||||
"debug groups verbose",
|
||||
"debug groups verbose <true|false>",
|
||||
@@ -466,6 +463,7 @@ namespace OpenSim.Groups
|
||||
OnNewGroupNotice(GroupID, NoticeID);
|
||||
}
|
||||
|
||||
|
||||
// Send notice out to everyone that wants notices
|
||||
foreach (GroupMembersData member in m_groupData.GetGroupMembers(GetRequestingAgentIDStr(remoteClient), GroupID))
|
||||
{
|
||||
@@ -498,12 +496,13 @@ namespace OpenSim.Groups
|
||||
Util.ParseUniversalUserIdentifier(notice.noticeData.AttachmentOwnerID, out giver, out tmp, out tmp, out tmp, out tmp);
|
||||
|
||||
m_log.DebugFormat("[Groups]: Giving inventory from {0} to {1}", giver, remoteClient.AgentId);
|
||||
string message;
|
||||
InventoryItemBase itemCopy = ((Scene)(remoteClient.Scene)).GiveInventoryItem(remoteClient.AgentId,
|
||||
giver, notice.noticeData.AttachmentItemID);
|
||||
giver, notice.noticeData.AttachmentItemID, out message);
|
||||
|
||||
if (itemCopy == null)
|
||||
{
|
||||
remoteClient.SendAgentAlertMessage("Can't find item to give. Nothing given.", false);
|
||||
remoteClient.SendAgentAlertMessage(message, false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
@@ -560,7 +560,7 @@ namespace OpenSim.Groups
|
||||
|
||||
// so we have the list of urls to send the notice to
|
||||
// this may take a long time...
|
||||
Util.FireAndForget(delegate
|
||||
Util.RunThreadNoTimeout(delegate
|
||||
{
|
||||
foreach (string u in urls)
|
||||
{
|
||||
@@ -571,7 +571,7 @@ namespace OpenSim.Groups
|
||||
hasAttachment, attType, attName, attItemID, AgentUUIForOutside(attOwnerID));
|
||||
}
|
||||
}
|
||||
});
|
||||
}, "AddGroupNotice", null);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
@@ -158,7 +158,7 @@ namespace OpenSim.Groups
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[Groups.RobustHGConnector]: Exception {0}", e.StackTrace);
|
||||
m_log.Error(string.Format("[Groups.RobustHGConnector]: Exception {0} ", e.Message), e);
|
||||
}
|
||||
|
||||
return FailureResult();
|
||||
|
||||
@@ -32,27 +32,47 @@ using System.Reflection;
|
||||
using System.Text;
|
||||
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.ServiceAuth;
|
||||
using OpenSim.Server.Base;
|
||||
|
||||
using OpenMetaverse;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
|
||||
namespace OpenSim.Groups
|
||||
{
|
||||
public class GroupsServiceRemoteConnector
|
||||
public class GroupsServiceRemoteConnector
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private string m_ServerURI;
|
||||
private IServiceAuth m_Auth;
|
||||
private object m_Lock = new object();
|
||||
|
||||
public GroupsServiceRemoteConnector(string url)
|
||||
public GroupsServiceRemoteConnector(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_ServerURI = url;
|
||||
if (!m_ServerURI.EndsWith("/"))
|
||||
m_ServerURI += "/";
|
||||
|
||||
m_log.DebugFormat("[Groups.RemoteConnector]: Groups server at {0}", m_ServerURI);
|
||||
/// This is from BaseServiceConnector
|
||||
string authType = Util.GetConfigVarFromSections<string>(config, "AuthType", new string[] { "Network", "Groups" }, "None");
|
||||
|
||||
switch (authType)
|
||||
{
|
||||
case "BasicHttpAuthentication":
|
||||
m_Auth = new BasicHttpAuthentication(config, "Groups");
|
||||
break;
|
||||
}
|
||||
///
|
||||
|
||||
m_log.DebugFormat("[Groups.RemoteConnector]: Groups server at {0}, authentication {1}",
|
||||
m_ServerURI, (m_Auth == null ? "None" : m_Auth.GetType().ToString()));
|
||||
}
|
||||
|
||||
public ExtendedGroupRecord CreateGroup(string RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment,
|
||||
@@ -106,7 +126,7 @@ namespace OpenSim.Groups
|
||||
sendData["OP"] = "UPDATE";
|
||||
Dictionary<string, object> ret = MakeRequest("PUTGROUP", sendData);
|
||||
|
||||
if (ret == null || (ret != null && ret["RESULT"].ToString() == "NULL"))
|
||||
if (ret == null || (ret != null && (!ret.ContainsKey("RESULT") || ret["RESULT"].ToString() == "NULL")))
|
||||
return null;
|
||||
|
||||
return GroupsDataUtils.GroupRecord((Dictionary<string, object>)ret["RESULT"]);
|
||||
@@ -127,7 +147,7 @@ namespace OpenSim.Groups
|
||||
|
||||
Dictionary<string, object> ret = MakeRequest("GETGROUP", sendData);
|
||||
|
||||
if (ret == null || (ret != null && ret["RESULT"].ToString() == "NULL"))
|
||||
if (ret == null || (ret != null && (!ret.ContainsKey("RESULT") || ret["RESULT"].ToString() == "NULL")))
|
||||
return null;
|
||||
|
||||
return GroupsDataUtils.GroupRecord((Dictionary<string, object>)ret["RESULT"]);
|
||||
@@ -267,6 +287,7 @@ namespace OpenSim.Groups
|
||||
|
||||
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);
|
||||
@@ -357,6 +378,7 @@ namespace OpenSim.Groups
|
||||
|
||||
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);
|
||||
@@ -657,7 +679,8 @@ namespace OpenSim.Groups
|
||||
lock (m_Lock)
|
||||
reply = SynchronousRestFormsRequester.MakeRequest("POST",
|
||||
m_ServerURI + "groups",
|
||||
ServerUtils.BuildQueryString(sendData));
|
||||
ServerUtils.BuildQueryString(sendData),
|
||||
m_Auth);
|
||||
|
||||
if (reply == string.Empty)
|
||||
return null;
|
||||
@@ -667,7 +690,7 @@ namespace OpenSim.Groups
|
||||
|
||||
return replyData;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -72,12 +72,7 @@ namespace OpenSim.Groups
|
||||
|
||||
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_GroupsService = new GroupsServiceRemoteConnector(config);
|
||||
m_Scenes = new List<Scene>();
|
||||
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ using OpenSim.Framework;
|
||||
using OpenSim.Server.Base;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using OpenSim.Framework.Servers.HttpServer;
|
||||
using OpenSim.Framework.ServiceAuth;
|
||||
using OpenSim.Server.Handlers.Base;
|
||||
using log4net;
|
||||
using OpenMetaverse;
|
||||
@@ -52,14 +53,26 @@ namespace OpenSim.Groups
|
||||
public GroupsServiceRobustConnector(IConfigSource config, IHttpServer server, string configName) :
|
||||
base(config, server, configName)
|
||||
{
|
||||
string key = string.Empty;
|
||||
if (configName != String.Empty)
|
||||
m_ConfigName = configName;
|
||||
|
||||
m_log.DebugFormat("[Groups.RobustConnector]: Starting with config name {0}", m_ConfigName);
|
||||
|
||||
IConfig groupsConfig = config.Configs[m_ConfigName];
|
||||
if (groupsConfig != null)
|
||||
{
|
||||
key = groupsConfig.GetString("SecretKey", string.Empty);
|
||||
m_log.DebugFormat("[Groups.RobustConnector]: Starting with secret key {0}", key);
|
||||
}
|
||||
// else
|
||||
// m_log.DebugFormat("[Groups.RobustConnector]: Unable to find {0} section in configuration", m_ConfigName);
|
||||
|
||||
m_GroupsService = new GroupsService(config);
|
||||
|
||||
server.AddStreamHandler(new GroupsServicePostHandler(m_GroupsService));
|
||||
IServiceAuth auth = ServiceAuth.Create(config, m_ConfigName);
|
||||
|
||||
server.AddStreamHandler(new GroupsServicePostHandler(m_GroupsService, auth));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,8 +82,8 @@ namespace OpenSim.Groups
|
||||
|
||||
private GroupsService m_GroupsService;
|
||||
|
||||
public GroupsServicePostHandler(GroupsService service) :
|
||||
base("POST", "/groups")
|
||||
public GroupsServicePostHandler(GroupsService service, IServiceAuth auth) :
|
||||
base("POST", "/groups", auth)
|
||||
{
|
||||
m_GroupsService = service;
|
||||
}
|
||||
@@ -96,7 +109,7 @@ namespace OpenSim.Groups
|
||||
string method = request["METHOD"].ToString();
|
||||
request.Remove("METHOD");
|
||||
|
||||
m_log.DebugFormat("[Groups.Handler]: {0}", method);
|
||||
// m_log.DebugFormat("[Groups.Handler]: {0}", method);
|
||||
switch (method)
|
||||
{
|
||||
case "PUTGROUP":
|
||||
@@ -140,7 +153,7 @@ namespace OpenSim.Groups
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[GROUPS HANDLER]: Exception {0}", e.StackTrace);
|
||||
m_log.Error(string.Format("[GROUPS HANDLER]: Exception {0} ", e.Message), e);
|
||||
}
|
||||
|
||||
return FailureResult();
|
||||
@@ -652,7 +665,11 @@ namespace OpenSim.Groups
|
||||
GroupInviteInfo invite = m_GroupsService.GetAgentToGroupInvite(request["RequestingAgentID"].ToString(),
|
||||
new UUID(request["InviteID"].ToString()));
|
||||
|
||||
result["RESULT"] = GroupsDataUtils.GroupInviteInfo(invite);
|
||||
if (invite != null)
|
||||
result["RESULT"] = GroupsDataUtils.GroupInviteInfo(invite);
|
||||
else
|
||||
result["RESULT"] = "NULL";
|
||||
|
||||
return Util.UTF8NoBomEncoding.GetBytes(ServerUtils.BuildXmlResponse(result));
|
||||
}
|
||||
|
||||
@@ -784,6 +801,14 @@ namespace OpenSim.Groups
|
||||
string xmlString = ServerUtils.BuildXmlResponse(result);
|
||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
||||
}
|
||||
|
||||
private byte[] FailureResult(string reason)
|
||||
{
|
||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
||||
NullResult(result, reason);
|
||||
string xmlString = ServerUtils.BuildXmlResponse(result);
|
||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ namespace OpenSim.OfflineIM
|
||||
if (serviceLocation == string.Empty)
|
||||
m_OfflineIMService = new OfflineIMService(config);
|
||||
else
|
||||
m_OfflineIMService = new OfflineIMServiceRemoteConnector(serviceLocation);
|
||||
m_OfflineIMService = new OfflineIMServiceRemoteConnector(config);
|
||||
|
||||
m_ForwardOfflineGroupMessages = cnf.GetBoolean("ForwardOfflineGroupMessages", m_ForwardOfflineGroupMessages);
|
||||
m_log.DebugFormat("[OfflineIM.V2]: Offline messages enabled by {0}", Name);
|
||||
@@ -226,10 +226,6 @@ namespace OpenSim.OfflineIM
|
||||
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);
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ using System.Reflection;
|
||||
using System.Text;
|
||||
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.ServiceAuth;
|
||||
using OpenSim.Server.Base;
|
||||
using OpenSim.Services.Interfaces;
|
||||
|
||||
@@ -46,6 +47,7 @@ namespace OpenSim.OfflineIM
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private string m_ServerURI = string.Empty;
|
||||
private IServiceAuth m_Auth;
|
||||
private object m_Lock = new object();
|
||||
|
||||
public OfflineIMServiceRemoteConnector(string url)
|
||||
@@ -65,6 +67,18 @@ namespace OpenSim.OfflineIM
|
||||
|
||||
m_ServerURI = cnf.GetString("OfflineMessageURL", string.Empty);
|
||||
|
||||
/// This is from BaseServiceConnector
|
||||
string authType = Util.GetConfigVarFromSections<string>(config, "AuthType", new string[] { "Network", "Messaging" }, "None");
|
||||
|
||||
switch (authType)
|
||||
{
|
||||
case "BasicHttpAuthentication":
|
||||
m_Auth = new BasicHttpAuthentication(config, "Messaging");
|
||||
break;
|
||||
}
|
||||
///
|
||||
m_log.DebugFormat("[OfflineIM.V2.RemoteConnector]: Offline IM server at {0} with auth {1}",
|
||||
m_ServerURI, (m_Auth == null ? "None" : m_Auth.GetType().ToString()));
|
||||
}
|
||||
|
||||
#region IOfflineIMService
|
||||
@@ -82,8 +96,13 @@ namespace OpenSim.OfflineIM
|
||||
if (!ret.ContainsKey("RESULT"))
|
||||
return ims;
|
||||
|
||||
if (ret["RESULT"].ToString() == "NULL")
|
||||
string result = ret["RESULT"].ToString();
|
||||
if (result == "NULL" || result.ToLower() == "false")
|
||||
{
|
||||
string reason = ret.ContainsKey("REASON") ? ret["REASON"].ToString() : "Unknown error";
|
||||
m_log.DebugFormat("[OfflineIM.V2.RemoteConnector]: GetMessages for {0} failed: {1}", principalID, reason);
|
||||
return ims;
|
||||
}
|
||||
|
||||
foreach (object v in ((Dictionary<string, object>)ret["RESULT"]).Values)
|
||||
{
|
||||
@@ -110,7 +129,7 @@ namespace OpenSim.OfflineIM
|
||||
string result = ret["RESULT"].ToString();
|
||||
if (result == "NULL" || result.ToLower() == "false")
|
||||
{
|
||||
reason = ret["REASON"].ToString();
|
||||
reason = ret.ContainsKey("REASON") ? ret["REASON"].ToString() : "Unknown error";
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -138,7 +157,8 @@ namespace OpenSim.OfflineIM
|
||||
lock (m_Lock)
|
||||
reply = SynchronousRestFormsRequester.MakeRequest("POST",
|
||||
m_ServerURI + "/offlineim",
|
||||
ServerUtils.BuildQueryString(sendData));
|
||||
ServerUtils.BuildQueryString(sendData),
|
||||
m_Auth);
|
||||
|
||||
Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(
|
||||
reply);
|
||||
|
||||
@@ -36,6 +36,7 @@ using OpenSim.Framework;
|
||||
using OpenSim.Server.Base;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using OpenSim.Framework.Servers.HttpServer;
|
||||
using OpenSim.Framework.ServiceAuth;
|
||||
using OpenSim.Server.Handlers.Base;
|
||||
using log4net;
|
||||
using OpenMetaverse;
|
||||
@@ -59,7 +60,9 @@ namespace OpenSim.OfflineIM
|
||||
|
||||
m_OfflineIMService = new OfflineIMService(config);
|
||||
|
||||
server.AddStreamHandler(new OfflineIMServicePostHandler(m_OfflineIMService));
|
||||
IServiceAuth auth = ServiceAuth.Create(config, m_ConfigName);
|
||||
|
||||
server.AddStreamHandler(new OfflineIMServicePostHandler(m_OfflineIMService, auth));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,8 +72,8 @@ namespace OpenSim.OfflineIM
|
||||
|
||||
private IOfflineIMService m_OfflineIMService;
|
||||
|
||||
public OfflineIMServicePostHandler(IOfflineIMService service) :
|
||||
base("POST", "/offlineim")
|
||||
public OfflineIMServicePostHandler(IOfflineIMService service, IServiceAuth auth) :
|
||||
base("POST", "/offlineim", auth)
|
||||
{
|
||||
m_OfflineIMService = service;
|
||||
}
|
||||
@@ -109,7 +112,7 @@ namespace OpenSim.OfflineIM
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.DebugFormat("[OFFLINE IM HANDLER]: Exception {0}", e.StackTrace);
|
||||
m_log.Error(string.Format("[OFFLINE IM HANDLER]: Exception {0} ", e.Message), e);
|
||||
}
|
||||
|
||||
return FailureResult();
|
||||
|
||||
@@ -104,7 +104,7 @@ namespace OpenSim.OfflineIM
|
||||
using (MemoryStream mstream = new MemoryStream())
|
||||
{
|
||||
XmlWriterSettings settings = new XmlWriterSettings();
|
||||
settings.Encoding = Encoding.UTF8;
|
||||
settings.Encoding = Util.UTF8NoBomEncoding;
|
||||
|
||||
using (XmlWriter writer = XmlWriter.Create(mstream, settings))
|
||||
{
|
||||
@@ -112,7 +112,7 @@ namespace OpenSim.OfflineIM
|
||||
writer.Flush();
|
||||
}
|
||||
|
||||
imXml = Util.UTF8.GetString(mstream.ToArray());
|
||||
imXml = Util.UTF8NoBomEncoding.GetString(mstream.ToArray());
|
||||
}
|
||||
|
||||
OfflineIMData data = new OfflineIMData();
|
||||
|
||||
@@ -32,6 +32,7 @@ using log4net;
|
||||
using Mono.Addins;
|
||||
using Nini.Config;
|
||||
using OpenSim;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
|
||||
@@ -45,6 +46,12 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
|
||||
LogManager.GetLogger(
|
||||
MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
/// <summary>
|
||||
/// Controls whether we load modules from Mono.Addins.
|
||||
/// </summary>
|
||||
/// <remarks>For debug purposes. Defaults to true.</remarks>
|
||||
public bool LoadModulesFromAddins { get; set; }
|
||||
|
||||
// Config access
|
||||
private OpenSimBase m_openSim;
|
||||
|
||||
@@ -61,6 +68,11 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
|
||||
private List<ISharedRegionModule> m_sharedInstances =
|
||||
new List<ISharedRegionModule>();
|
||||
|
||||
public RegionModulesControllerPlugin()
|
||||
{
|
||||
LoadModulesFromAddins = true;
|
||||
}
|
||||
|
||||
#region IApplicationPlugin implementation
|
||||
|
||||
public void Initialise (OpenSimBase openSim)
|
||||
@@ -69,6 +81,9 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
|
||||
m_openSim.ApplicationRegistry.RegisterInterface<IRegionModulesController>(this);
|
||||
m_log.DebugFormat("[REGIONMODULES]: Initializing...");
|
||||
|
||||
if (!LoadModulesFromAddins)
|
||||
return;
|
||||
|
||||
// Who we are
|
||||
string id = AddinManager.CurrentAddin.Id;
|
||||
|
||||
@@ -88,40 +103,8 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
|
||||
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)
|
||||
{
|
||||
if (CheckModuleEnabled(node, modulesConfig))
|
||||
{
|
||||
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]++;
|
||||
}
|
||||
}
|
||||
foreach (TypeExtensionNode node in AddinManager.GetExtensionNodes("/OpenSim/RegionModules"))
|
||||
AddNode(node, modulesConfig, loadedModules);
|
||||
|
||||
foreach (KeyValuePair<RuntimeAddin, IList<int>> loadedModuleData in loadedModules)
|
||||
{
|
||||
@@ -194,6 +177,41 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
|
||||
|
||||
#region IPlugin implementation
|
||||
|
||||
private void AddNode(
|
||||
TypeExtensionNode node, IConfig modulesConfig, Dictionary<RuntimeAddin, IList<int>> loadedModules)
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (CheckModuleEnabled(node, modulesConfig))
|
||||
{
|
||||
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]++;
|
||||
}
|
||||
}
|
||||
|
||||
// We don't do that here
|
||||
//
|
||||
public void Initialise ()
|
||||
@@ -215,6 +233,7 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
|
||||
m_sharedInstances[0].Close();
|
||||
m_sharedInstances.RemoveAt(0);
|
||||
}
|
||||
|
||||
m_sharedModules.Clear();
|
||||
m_nonSharedModules.Clear();
|
||||
}
|
||||
|
||||
@@ -162,6 +162,9 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||
availableMethods["admin_acl_list"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcAccessListList);
|
||||
availableMethods["admin_estate_reload"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcEstateReload);
|
||||
|
||||
// Land management
|
||||
availableMethods["admin_reset_land"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcResetLand);
|
||||
|
||||
// Either enable full remote functionality or just selected features
|
||||
string enabledMethods = m_config.GetString("enabled_methods", "all");
|
||||
|
||||
@@ -1022,7 +1025,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||
// Set home position
|
||||
|
||||
GridRegion home = scene.GridService.GetRegionByPosition(scopeID,
|
||||
(int)(regionXLocation * Constants.RegionSize), (int)(regionYLocation * Constants.RegionSize));
|
||||
(int)Util.RegionToWorldLoc(regionXLocation), (int)Util.RegionToWorldLoc(regionYLocation));
|
||||
if (null == home)
|
||||
{
|
||||
m_log.WarnFormat("[RADMIN]: Unable to set home region for newly created user account {0} {1}", firstName, lastName);
|
||||
@@ -1252,7 +1255,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||
if ((null != regionXLocation) && (null != regionYLocation))
|
||||
{
|
||||
GridRegion home = scene.GridService.GetRegionByPosition(scopeID,
|
||||
(int)(regionXLocation * Constants.RegionSize), (int)(regionYLocation * Constants.RegionSize));
|
||||
(int)Util.RegionToWorldLoc((uint)regionXLocation), (int)Util.RegionToWorldLoc((uint)regionYLocation));
|
||||
if (null == home) {
|
||||
m_log.WarnFormat("[RADMIN]: Unable to set home region for updated user account {0} {1}", firstName, lastName);
|
||||
} else {
|
||||
@@ -1484,8 +1487,11 @@ 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, mergeOar, skipAssets, Guid.Empty);
|
||||
archiver.DearchiveRegion(filename, Guid.Empty, archiveOptions);
|
||||
else
|
||||
throw new Exception("Archiver module not present for scene");
|
||||
|
||||
@@ -2060,6 +2066,56 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||
responseData["success"] = true;
|
||||
}
|
||||
|
||||
private void XmlRpcResetLand(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
|
||||
{
|
||||
Hashtable requestData = (Hashtable)request.Params[0];
|
||||
Hashtable responseData = (Hashtable)response.Value;
|
||||
|
||||
string musicURL = string.Empty;
|
||||
UUID groupID = UUID.Zero;
|
||||
uint flags = 0;
|
||||
bool set_group = false, set_music = false, set_flags = false;
|
||||
|
||||
if (requestData.Contains("group") && requestData["group"] != null)
|
||||
set_group = UUID.TryParse(requestData["group"].ToString(), out groupID);
|
||||
if (requestData.Contains("music") && requestData["music"] != null)
|
||||
{
|
||||
musicURL = requestData["music"].ToString();
|
||||
set_music = true;
|
||||
}
|
||||
if (requestData.Contains("flags") && requestData["flags"] != null)
|
||||
set_flags = UInt32.TryParse(requestData["flags"].ToString(), out flags);
|
||||
|
||||
m_log.InfoFormat("[RADMIN]: Received Reset Land Request group={0} musicURL={1} flags={2}",
|
||||
(set_group ? groupID.ToString() : "unchanged"),
|
||||
(set_music ? musicURL : "unchanged"),
|
||||
(set_flags ? flags.ToString() : "unchanged"));
|
||||
|
||||
m_application.SceneManager.ForEachScene(delegate(Scene s)
|
||||
{
|
||||
List<ILandObject> parcels = s.LandChannel.AllParcels();
|
||||
foreach (ILandObject p in parcels)
|
||||
{
|
||||
if (set_music)
|
||||
p.LandData.MusicURL = musicURL;
|
||||
|
||||
if (set_group)
|
||||
p.LandData.GroupID = groupID;
|
||||
|
||||
if (set_flags)
|
||||
p.LandData.Flags = flags;
|
||||
|
||||
s.LandChannel.UpdateLandObject(p.LandData.LocalID, p.LandData);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
responseData["success"] = true;
|
||||
|
||||
m_log.Info("[RADMIN]: Reset Land Request complete");
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Parse a float with the given parameter name from a request data hash table.
|
||||
/// </summary>
|
||||
@@ -2235,7 +2291,6 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||
{
|
||||
account.ServiceURLs = new Dictionary<string, object>();
|
||||
account.ServiceURLs["HomeURI"] = string.Empty;
|
||||
account.ServiceURLs["GatekeeperURI"] = string.Empty;
|
||||
account.ServiceURLs["InventoryServerURI"] = string.Empty;
|
||||
account.ServiceURLs["AssetServerURI"] = string.Empty;
|
||||
}
|
||||
@@ -2881,7 +2936,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||
// Set home position
|
||||
|
||||
GridRegion home = scene.GridService.GetRegionByPosition(scopeID,
|
||||
(int)(regionXLocation * Constants.RegionSize), (int)(regionYLocation * Constants.RegionSize));
|
||||
(int)Util.RegionToWorldLoc(regionXLocation), (int)Util.RegionToWorldLoc(regionYLocation));
|
||||
if (null == home) {
|
||||
m_log.WarnFormat("[RADMIN]: Unable to set home region for newly created user account {0} {1}", names[0], names[1]);
|
||||
} else {
|
||||
|
||||
@@ -50,8 +50,7 @@ namespace OpenSim.Framework.Capabilities
|
||||
|
||||
public class Caps
|
||||
{
|
||||
// private static readonly ILog m_log =
|
||||
// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private string m_httpListenerHostName;
|
||||
private uint m_httpListenPort;
|
||||
@@ -152,6 +151,10 @@ namespace OpenSim.Framework.Capabilities
|
||||
|
||||
public void RegisterPollHandler(string capName, PollServiceEventArgs pollServiceHandler)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[CAPS]: Registering handler with name {0}, url {1} for {2}",
|
||||
// capName, pollServiceHandler.Url, m_agentID, m_regionName);
|
||||
|
||||
m_pollServiceHandlers.Add(capName, pollServiceHandler);
|
||||
|
||||
m_httpListener.AddPollServiceHTTPHandler(pollServiceHandler.Url, pollServiceHandler);
|
||||
|
||||
@@ -56,12 +56,15 @@ namespace OpenSim.Capabilities.Handlers
|
||||
public const string DefaultFormat = "x-j2c";
|
||||
|
||||
// TODO: Change this to a config option
|
||||
const string REDIRECT_URL = null;
|
||||
private string m_RedirectURL = null;
|
||||
|
||||
public GetTextureHandler(string path, IAssetService assService, string name, string description)
|
||||
public GetTextureHandler(string path, IAssetService assService, string name, string description, string redirectURL)
|
||||
: base("GET", path, name, description)
|
||||
{
|
||||
m_assetService = assService;
|
||||
m_RedirectURL = redirectURL;
|
||||
if (m_RedirectURL != null && !m_RedirectURL.EndsWith("/"))
|
||||
m_RedirectURL += "/";
|
||||
}
|
||||
|
||||
protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
||||
@@ -134,7 +137,7 @@ namespace OpenSim.Capabilities.Handlers
|
||||
if (format != DefaultFormat)
|
||||
fullID = fullID + "-" + format;
|
||||
|
||||
if (!String.IsNullOrEmpty(REDIRECT_URL))
|
||||
if (!String.IsNullOrEmpty(m_RedirectURL))
|
||||
{
|
||||
// Only try to fetch locally cached textures. Misses are redirected
|
||||
texture = m_assetService.GetCached(fullID);
|
||||
@@ -150,8 +153,9 @@ namespace OpenSim.Capabilities.Handlers
|
||||
}
|
||||
else
|
||||
{
|
||||
string textureUrl = REDIRECT_URL + textureID.ToString();
|
||||
string textureUrl = m_RedirectURL + "?texture_id="+ textureID.ToString();
|
||||
m_log.Debug("[GETTEXTURE]: Redirecting texture request to " + textureUrl);
|
||||
httpResponse.StatusCode = (int)OSHttpStatusCode.RedirectMovedPermanently;
|
||||
httpResponse.RedirectLocation = textureUrl;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -62,8 +62,10 @@ namespace OpenSim.Capabilities.Handlers
|
||||
if (m_AssetService == null)
|
||||
throw new Exception(String.Format("Failed to load AssetService from {0}; config is {1}", assetService, m_ConfigName));
|
||||
|
||||
string rurl = serverConfig.GetString("GetTextureRedirectURL");
|
||||
;
|
||||
server.AddStreamHandler(
|
||||
new GetTextureHandler("/CAPS/GetTexture/" /*+ UUID.Random() */, m_AssetService, "GetTexture", null));
|
||||
new GetTextureHandler("/CAPS/GetTexture/" /*+ UUID.Random() */, m_AssetService, "GetTexture", null, rurl));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -52,7 +52,7 @@ namespace OpenSim.Capabilities.Handlers.GetTexture.Tests
|
||||
// Overkill - we only really need the asset service, not a whole scene.
|
||||
Scene scene = new SceneHelpers().SetupScene();
|
||||
|
||||
GetTextureHandler handler = new GetTextureHandler(null, scene.AssetService, "TestGetTexture", null);
|
||||
GetTextureHandler handler = new GetTextureHandler(null, scene.AssetService, "TestGetTexture", null, null);
|
||||
TestOSHttpRequest req = new TestOSHttpRequest();
|
||||
TestOSHttpResponse resp = new TestOSHttpResponse();
|
||||
req.Url = new Uri("http://localhost/?texture_id=00000000-0000-1111-9999-000000000012");
|
||||
|
||||
@@ -238,7 +238,15 @@ namespace OpenSim.Capabilities.Handlers
|
||||
|
||||
if (folderID != UUID.Zero)
|
||||
{
|
||||
contents = m_InventoryService.GetFolderContent(agentID, folderID);
|
||||
InventoryCollection fetchedContents = m_InventoryService.GetFolderContent(agentID, folderID);
|
||||
|
||||
if (fetchedContents == null)
|
||||
{
|
||||
m_log.WarnFormat("[WEB FETCH INV DESC HANDLER]: Could not get contents of folder {0} for user {1}", folderID, agentID);
|
||||
return contents;
|
||||
}
|
||||
|
||||
contents = fetchedContents;
|
||||
InventoryFolderBase containingFolder = new InventoryFolderBase();
|
||||
containingFolder.ID = folderID;
|
||||
containingFolder.Owner = agentID;
|
||||
|
||||
@@ -37,9 +37,8 @@ namespace OpenSim.Data
|
||||
public abstract class AssetDataBase : IAssetDataPlugin
|
||||
{
|
||||
public abstract AssetBase GetAsset(UUID uuid);
|
||||
|
||||
public abstract void StoreAsset(AssetBase asset);
|
||||
public abstract bool ExistsAsset(UUID uuid);
|
||||
public abstract bool[] AssetsExist(UUID[] uuids);
|
||||
|
||||
public abstract List<AssetMetadata> FetchAssetMetadataSet(int start, int count);
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace OpenSim.Data
|
||||
{
|
||||
AssetBase GetAsset(UUID uuid);
|
||||
void StoreAsset(AssetBase asset);
|
||||
bool ExistsAsset(UUID uuid);
|
||||
bool[] AssetsExist(UUID[] uuids);
|
||||
List<AssetMetadata> FetchAssetMetadataSet(int start, int count);
|
||||
void Initialise(string connect);
|
||||
bool Delete(string id);
|
||||
|
||||
@@ -29,7 +29,7 @@ using System.Collections.Generic;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
|
||||
namespace OpenSim.Region.Framework.Interfaces
|
||||
namespace OpenSim.Data
|
||||
{
|
||||
public interface IEstateDataStore
|
||||
{
|
||||
@@ -54,12 +54,12 @@ namespace OpenSim.Data
|
||||
/// <summary>
|
||||
/// Return the x-coordinate of this region.
|
||||
/// </summary>
|
||||
public int coordX { get { return posX / (int)Constants.RegionSize; } }
|
||||
public int coordX { get { return (int)Util.WorldToRegionLoc((uint)posX); } }
|
||||
|
||||
/// <summary>
|
||||
/// Return the y-coordinate of this region.
|
||||
/// </summary>
|
||||
public int coordY { get { return posY / (int)Constants.RegionSize; } }
|
||||
public int coordY { get { return (int)Util.WorldToRegionLoc((uint)posY); } }
|
||||
|
||||
public Dictionary<string, object> Data;
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace OpenSim.Data
|
||||
{
|
||||
AssetBase GetAsset(UUID uuid);
|
||||
void StoreAsset(AssetBase asset);
|
||||
bool ExistsAsset(UUID uuid);
|
||||
bool[] AssetsExist(UUID[] uuids);
|
||||
List<AssetMetadata> FetchAssetMetadataSet(int start, int count);
|
||||
void Initialise(string connect);
|
||||
bool Delete(string id);
|
||||
|
||||
@@ -48,9 +48,57 @@ namespace OpenSim.Data
|
||||
public ulong everyonePowers;
|
||||
public ulong ownersPowers;
|
||||
|
||||
public Dictionary<UUID, XGroupMember> members = new Dictionary<UUID, XGroupMember>();
|
||||
public Dictionary<UUID, XGroupNotice> notices = new Dictionary<UUID, XGroupNotice>();
|
||||
|
||||
public XGroup Clone()
|
||||
{
|
||||
return (XGroup)MemberwiseClone();
|
||||
XGroup clone = (XGroup)MemberwiseClone();
|
||||
clone.members = new Dictionary<UUID, XGroupMember>();
|
||||
clone.notices = new Dictionary<UUID, XGroupNotice>();
|
||||
|
||||
foreach (KeyValuePair<UUID, XGroupMember> kvp in members)
|
||||
clone.members[kvp.Key] = kvp.Value.Clone();
|
||||
|
||||
foreach (KeyValuePair<UUID, XGroupNotice> kvp in notices)
|
||||
clone.notices[kvp.Key] = kvp.Value.Clone();
|
||||
|
||||
return clone;
|
||||
}
|
||||
}
|
||||
|
||||
public class XGroupMember
|
||||
{
|
||||
public UUID agentID;
|
||||
public UUID groupID;
|
||||
public UUID roleID;
|
||||
public bool acceptNotices = true;
|
||||
public bool listInProfile = true;
|
||||
|
||||
public XGroupMember Clone()
|
||||
{
|
||||
return (XGroupMember)MemberwiseClone();
|
||||
}
|
||||
}
|
||||
|
||||
public class XGroupNotice
|
||||
{
|
||||
public UUID groupID;
|
||||
public UUID noticeID;
|
||||
public uint timestamp;
|
||||
public string fromName;
|
||||
public string subject;
|
||||
public string message;
|
||||
public byte[] binaryBucket;
|
||||
public bool hasAttachment;
|
||||
public int assetType;
|
||||
|
||||
public XGroupNotice Clone()
|
||||
{
|
||||
XGroupNotice clone = (XGroupNotice)MemberwiseClone();
|
||||
clone.binaryBucket = (byte[])binaryBucket.Clone();
|
||||
|
||||
return clone;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,14 +106,13 @@ namespace OpenSim.Data
|
||||
/// 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.
|
||||
/// Currently in-use only for regression test purposes.
|
||||
/// </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);
|
||||
XGroup GetGroup(UUID groupID);
|
||||
Dictionary<UUID, XGroup> GetGroups();
|
||||
bool DeleteGroup(UUID groupID);
|
||||
}
|
||||
}
|
||||
@@ -160,18 +160,18 @@ namespace OpenSim.Data.MSSQL
|
||||
@temporary, @create_time, @access_time, @creatorid, @asset_flags, @data)";
|
||||
|
||||
string assetName = asset.Name;
|
||||
if (asset.Name.Length > 64)
|
||||
if (asset.Name.Length > AssetBase.MAX_ASSET_NAME)
|
||||
{
|
||||
assetName = asset.Name.Substring(0, 64);
|
||||
assetName = asset.Name.Substring(0, AssetBase.MAX_ASSET_NAME);
|
||||
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)
|
||||
if (asset.Description.Length > AssetBase.MAX_ASSET_DESC)
|
||||
{
|
||||
assetDescription = asset.Description.Substring(0, 64);
|
||||
assetDescription = asset.Description.Substring(0, AssetBase.MAX_ASSET_DESC);
|
||||
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);
|
||||
@@ -225,17 +225,38 @@ namespace OpenSim.Data.MSSQL
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// Check if asset exist in m_database
|
||||
/// Check if the assets exist in the database.
|
||||
/// </summary>
|
||||
/// <param name="uuid"></param>
|
||||
/// <returns>true if exist.</returns>
|
||||
override public bool ExistsAsset(UUID uuid)
|
||||
/// <param name="uuids">The assets' IDs</param>
|
||||
/// <returns>For each asset: true if it exists, false otherwise</returns>
|
||||
public override bool[] AssetsExist(UUID[] uuids)
|
||||
{
|
||||
if (GetAsset(uuid) != null)
|
||||
if (uuids.Length == 0)
|
||||
return new bool[0];
|
||||
|
||||
HashSet<UUID> exist = new HashSet<UUID>();
|
||||
|
||||
string ids = "'" + string.Join("','", uuids) + "'";
|
||||
string sql = string.Format("SELECT id FROM assets WHERE id IN ({0})", ids);
|
||||
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
return true;
|
||||
conn.Open();
|
||||
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
UUID id = DBGuid.FromDB(reader["id"]);
|
||||
exist.Add(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
bool[] results = new bool[uuids.Length];
|
||||
for (int i = 0; i < uuids.Length; i++)
|
||||
results[i] = exist.Contains(uuids[i]);
|
||||
return results;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
@@ -55,7 +55,7 @@ namespace OpenSim.Data.MSSQL
|
||||
return Delete(principalID.ToString(), friend);
|
||||
}
|
||||
|
||||
public bool Delete(string principalID, string friend)
|
||||
public override bool Delete(string principalID, string friend)
|
||||
{
|
||||
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||
using (SqlCommand cmd = new SqlCommand())
|
||||
|
||||
@@ -49,6 +49,7 @@ 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
|
||||
@@ -530,43 +531,53 @@ ELSE
|
||||
/// <returns></returns>
|
||||
public double[,] LoadTerrain(UUID regionID)
|
||||
{
|
||||
double[,] terrain = new double[(int)Constants.RegionSize, (int)Constants.RegionSize];
|
||||
terrain.Initialize();
|
||||
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;
|
||||
|
||||
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))
|
||||
{
|
||||
// MySqlParameter param = new MySqlParameter();
|
||||
cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", regionID));
|
||||
conn.Open();
|
||||
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
int rev;
|
||||
if (reader.Read())
|
||||
// MySqlParameter param = new MySqlParameter();
|
||||
cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", regionID));
|
||||
conn.Open();
|
||||
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
MemoryStream str = new MemoryStream((byte[])reader["Heightfield"]);
|
||||
BinaryReader br = new BinaryReader(str);
|
||||
for (int x = 0; x < (int)Constants.RegionSize; x++)
|
||||
int rev;
|
||||
if (reader.Read())
|
||||
{
|
||||
for (int y = 0; y < (int)Constants.RegionSize; y++)
|
||||
{
|
||||
terrain[x, y] = br.ReadDouble();
|
||||
}
|
||||
rev = (int)reader["Revision"];
|
||||
byte[] blob = (byte[])reader["Heightfield"];
|
||||
terrData = TerrainData.CreateFromDatabaseBlobFactory(pSizeX, pSizeY, pSizeZ, rev, blob);
|
||||
}
|
||||
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);
|
||||
}
|
||||
else
|
||||
{
|
||||
_Log.Info("[REGION DB]: No terrain found for region");
|
||||
return null;
|
||||
}
|
||||
_Log.Info("[REGION DB]: Loaded terrain revision r" + rev);
|
||||
}
|
||||
}
|
||||
|
||||
return terrain;
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -574,10 +585,8 @@ ELSE
|
||||
/// </summary>
|
||||
/// <param name="terrain">terrain map data.</param>
|
||||
/// <param name="regionID">regionID.</param>
|
||||
public void StoreTerrain(double[,] terrain, UUID regionID)
|
||||
public void StoreTerrain(TerrainData terrData, 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))
|
||||
@@ -590,17 +599,23 @@ 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))
|
||||
{
|
||||
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();
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
_Log.Info("[REGION DB]: Stored terrain revision r " + revision);
|
||||
_Log.InfoFormat("{0} Stored terrain revision r={1}", LogHeader, terrainDBRevision);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1344,30 +1359,6 @@ 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>
|
||||
|
||||
@@ -278,7 +278,7 @@ namespace OpenSim.Data.MSSQL
|
||||
// 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";
|
||||
string sql = "update inventoryfolders set version=version+1 where folderID = @folderID";
|
||||
|
||||
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||
{
|
||||
|
||||
@@ -331,4 +331,12 @@ ALTER TABLE dbo.estate_map ADD CONSTRAINT
|
||||
|
||||
COMMIT
|
||||
|
||||
:VERSION 10
|
||||
|
||||
BEGIN transaction
|
||||
|
||||
ALTER TABLE estate_settings ADD AllowLandmark tinyint NOT NULL default 1;
|
||||
ALTER TABLE estate_settings ADD AllowParcelChanges tinyint NOT NULL default 1;
|
||||
ALTER TABLE estate_settings ADD AllowSetHome tinyint NOT NULL default 1;
|
||||
|
||||
COMMIT;
|
||||
@@ -1,4 +1,4 @@
|
||||
:VERSION 1
|
||||
:VERSION 1
|
||||
|
||||
BEGIN TRANSACTION
|
||||
|
||||
@@ -26,6 +26,14 @@ COMMIT
|
||||
|
||||
BEGIN TRANSACTION
|
||||
|
||||
ALTER TABLE Presence ADD LastSeen DateTime
|
||||
ALTER TABLE Presence ADD LastSeen DateTime;
|
||||
|
||||
COMMIT
|
||||
COMMIT
|
||||
|
||||
:VERSION 3
|
||||
|
||||
BEGIN TRANSACTION
|
||||
|
||||
CREATE INDEX RegionID ON Presence(RegionID);
|
||||
|
||||
COMMIT
|
||||
|
||||
@@ -1161,11 +1161,11 @@ COMMIT
|
||||
|
||||
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';
|
||||
ALTER TABLE prims ADD PhysicsShapeType tinyint NOT NULL default 0;
|
||||
ALTER TABLE prims ADD Density float NOT NULL default 1000;
|
||||
ALTER TABLE prims ADD GravityModifier float NOT NULL default 1;
|
||||
ALTER TABLE prims ADD Friction float NOT NULL default 0.6;
|
||||
ALTER TABLE prims ADD Restitution float NOT NULL default 0.5;
|
||||
|
||||
COMMIT
|
||||
|
||||
|
||||
@@ -171,18 +171,18 @@ namespace OpenSim.Data.MySQL
|
||||
dbcon))
|
||||
{
|
||||
string assetName = asset.Name;
|
||||
if (asset.Name.Length > 64)
|
||||
if (asset.Name.Length > AssetBase.MAX_ASSET_NAME)
|
||||
{
|
||||
assetName = asset.Name.Substring(0, 64);
|
||||
assetName = asset.Name.Substring(0, AssetBase.MAX_ASSET_NAME);
|
||||
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)
|
||||
if (asset.Description.Length > AssetBase.MAX_ASSET_DESC)
|
||||
{
|
||||
assetDescription = asset.Description.Substring(0, 64);
|
||||
assetDescription = asset.Description.Substring(0, AssetBase.MAX_ASSET_DESC);
|
||||
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);
|
||||
@@ -257,46 +257,44 @@ namespace OpenSim.Data.MySQL
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if the asset exists in the database
|
||||
/// Check if the assets exist in the database.
|
||||
/// </summary>
|
||||
/// <param name="uuid">The asset UUID</param>
|
||||
/// <returns>true if it exists, false otherwise.</returns>
|
||||
override public bool ExistsAsset(UUID uuid)
|
||||
/// <param name="uuidss">The assets' IDs</param>
|
||||
/// <returns>For each asset: true if it exists, false otherwise</returns>
|
||||
public override bool[] AssetsExist(UUID[] uuids)
|
||||
{
|
||||
// m_log.DebugFormat("[ASSETS DB]: Checking for asset {0}", uuid);
|
||||
if (uuids.Length == 0)
|
||||
return new bool[0];
|
||||
|
||||
bool assetExists = false;
|
||||
HashSet<UUID> exist = new HashSet<UUID>();
|
||||
|
||||
string ids = "'" + string.Join("','", uuids) + "'";
|
||||
string sql = string.Format("SELECT id FROM assets WHERE id IN ({0})", ids);
|
||||
|
||||
lock (m_dbLock)
|
||||
{
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
dbcon.Open();
|
||||
using (MySqlCommand cmd = new MySqlCommand("SELECT id FROM assets WHERE id=?id", dbcon))
|
||||
using (MySqlCommand cmd = new MySqlCommand(sql, dbcon))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("?id", uuid.ToString());
|
||||
|
||||
try
|
||||
using (MySqlDataReader dbReader = cmd.ExecuteReader())
|
||||
{
|
||||
using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow))
|
||||
while (dbReader.Read())
|
||||
{
|
||||
if (dbReader.Read())
|
||||
{
|
||||
// m_log.DebugFormat("[ASSETS DB]: Found asset {0}", uuid);
|
||||
assetExists = true;
|
||||
}
|
||||
UUID id = DBGuid.FromDB(dbReader["id"]);
|
||||
exist.Add(id);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Error(
|
||||
string.Format("[ASSETS DB]: MySql failure fetching asset {0}. Exception ", uuid), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return assetExists;
|
||||
bool[] results = new bool[uuids.Length];
|
||||
for (int i = 0; i < uuids.Length; i++)
|
||||
results[i] = exist.Contains(uuids[i]);
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -145,7 +145,11 @@ namespace OpenSim.Data.MySQL
|
||||
cmd.CommandText = sql;
|
||||
cmd.Parameters.AddWithValue("?RegionID", regionID.ToString());
|
||||
|
||||
return DoLoad(cmd, regionID, create);
|
||||
EstateSettings e = DoLoad(cmd, regionID, create);
|
||||
if (!create && e.EstateID == 0) // Not found
|
||||
return null;
|
||||
|
||||
return e;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -427,7 +431,10 @@ namespace OpenSim.Data.MySQL
|
||||
cmd.CommandText = sql;
|
||||
cmd.Parameters.AddWithValue("?EstateID", estateID);
|
||||
|
||||
return DoLoad(cmd, UUID.Zero, false);
|
||||
EstateSettings e = DoLoad(cmd, UUID.Zero, false);
|
||||
if (e.EstateID != estateID)
|
||||
return null;
|
||||
return e;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace OpenSim.Data.MySQL
|
||||
return Delete(principalID.ToString(), friend);
|
||||
}
|
||||
|
||||
public bool Delete(string principalID, string friend)
|
||||
public override bool Delete(string principalID, string friend)
|
||||
{
|
||||
using (MySqlCommand cmd = new MySqlCommand())
|
||||
{
|
||||
|
||||
@@ -86,11 +86,11 @@ namespace OpenSim.Data.MySQL
|
||||
public GroupData[] RetrieveGroups(string pattern)
|
||||
{
|
||||
if (string.IsNullOrEmpty(pattern))
|
||||
pattern = "1 ORDER BY Name LIMIT 100";
|
||||
pattern = "1";
|
||||
else
|
||||
pattern = string.Format("Name LIKE '%{0}%' ORDER BY Name LIMIT 100", pattern);
|
||||
pattern = string.Format("Name LIKE '%{0}%'", MySqlHelper.EscapeString(pattern));
|
||||
|
||||
return m_Groups.Get(pattern);
|
||||
return m_Groups.Get(string.Format("ShowInList=1 AND ({0}) ORDER BY Name LIMIT 100", pattern));
|
||||
}
|
||||
|
||||
public bool DeleteGroup(UUID groupID)
|
||||
|
||||
@@ -48,6 +48,7 @@ namespace OpenSim.Data.MySQL
|
||||
public class MySQLSimulationData : ISimulationDataStore
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
private static string LogHeader = "[REGION DB MYSQL]";
|
||||
|
||||
private string m_connectionString;
|
||||
private object m_dbLock = new object();
|
||||
@@ -91,7 +92,7 @@ namespace OpenSim.Data.MySQL
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Error("[REGION DB]: MySQL error in ExecuteReader: " + e.Message);
|
||||
m_log.ErrorFormat("{0} MySQL error in ExecuteReader: {1}", LogHeader, e);
|
||||
throw;
|
||||
}
|
||||
|
||||
@@ -572,10 +573,14 @@ namespace OpenSim.Data.MySQL
|
||||
}
|
||||
}
|
||||
|
||||
// Legacy entry point for when terrain was always a 256x256 hieghtmap
|
||||
public void StoreTerrain(double[,] ter, UUID regionID)
|
||||
{
|
||||
m_log.Info("[REGION DB]: Storing terrain");
|
||||
StoreTerrain(new HeightmapTerrainData(ter), regionID);
|
||||
}
|
||||
|
||||
public void StoreTerrain(TerrainData terrData, UUID regionID)
|
||||
{
|
||||
lock (m_dbLock)
|
||||
{
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
@@ -589,11 +594,18 @@ namespace OpenSim.Data.MySQL
|
||||
|
||||
ExecuteNonQuery(cmd);
|
||||
|
||||
cmd.CommandText = "insert into terrain (RegionUUID, " +
|
||||
"Revision, Heightfield) values (?RegionUUID, " +
|
||||
"1, ?Heightfield)";
|
||||
|
||||
cmd.Parameters.AddWithValue("Heightfield", SerializeTerrain(ter));
|
||||
int terrainDBRevision;
|
||||
Array terrainDBblob;
|
||||
terrData.GetDatabaseBlob(out terrainDBRevision, out terrainDBblob);
|
||||
|
||||
m_log.InfoFormat("{0} Storing terrain. X={1}, Y={2}, rev={3}",
|
||||
LogHeader, terrData.SizeX, terrData.SizeY, terrainDBRevision);
|
||||
|
||||
cmd.CommandText = "insert into terrain (RegionUUID, Revision, Heightfield)"
|
||||
+ "values (?RegionUUID, ?Revision, ?Heightfield)";
|
||||
|
||||
cmd.Parameters.AddWithValue("Revision", terrainDBRevision);
|
||||
cmd.Parameters.AddWithValue("Heightfield", terrainDBblob);
|
||||
|
||||
ExecuteNonQuery(cmd);
|
||||
}
|
||||
@@ -601,9 +613,20 @@ namespace OpenSim.Data.MySQL
|
||||
}
|
||||
}
|
||||
|
||||
// Legacy region loading
|
||||
public double[,] LoadTerrain(UUID regionID)
|
||||
{
|
||||
double[,] terrain = null;
|
||||
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;
|
||||
|
||||
lock (m_dbLock)
|
||||
{
|
||||
@@ -623,32 +646,15 @@ namespace OpenSim.Data.MySQL
|
||||
while (reader.Read())
|
||||
{
|
||||
int rev = Convert.ToInt32(reader["Revision"]);
|
||||
|
||||
terrain = new double[(int)Constants.RegionSize, (int)Constants.RegionSize];
|
||||
terrain.Initialize();
|
||||
|
||||
using (MemoryStream mstr = new MemoryStream((byte[])reader["Heightfield"]))
|
||||
{
|
||||
using (BinaryReader br = new BinaryReader(mstr))
|
||||
{
|
||||
for (int x = 0; x < (int)Constants.RegionSize; x++)
|
||||
{
|
||||
for (int y = 0; y < (int)Constants.RegionSize; y++)
|
||||
{
|
||||
terrain[x, y] = br.ReadDouble();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_log.InfoFormat("[REGION DB]: Loaded terrain revision r{0}", rev);
|
||||
}
|
||||
byte[] blob = (byte[])reader["Heightfield"];
|
||||
terrData = TerrainData.CreateFromDatabaseBlobFactory(pSizeX, pSizeY, pSizeZ, rev, blob);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return terrain;
|
||||
return terrData;
|
||||
}
|
||||
|
||||
public void RemoveLandObject(UUID globalID)
|
||||
@@ -689,7 +695,7 @@ namespace OpenSim.Data.MySQL
|
||||
"MusicURL, PassHours, PassPrice, SnapshotUUID, " +
|
||||
"UserLocationX, UserLocationY, UserLocationZ, " +
|
||||
"UserLookAtX, UserLookAtY, UserLookAtZ, " +
|
||||
"AuthbuyerID, OtherCleanTime, MediaType, MediaDescription, " +
|
||||
"AuthbuyerID, OtherCleanTime, Dwell, MediaType, MediaDescription, " +
|
||||
"MediaSize, MediaLoop, ObscureMusic, ObscureMedia) values (" +
|
||||
"?UUID, ?RegionUUID, " +
|
||||
"?LocalLandID, ?Bitmap, ?Name, ?Description, " +
|
||||
@@ -700,7 +706,7 @@ namespace OpenSim.Data.MySQL
|
||||
"?MusicURL, ?PassHours, ?PassPrice, ?SnapshotUUID, " +
|
||||
"?UserLocationX, ?UserLocationY, ?UserLocationZ, " +
|
||||
"?UserLookAtX, ?UserLookAtY, ?UserLookAtZ, " +
|
||||
"?AuthbuyerID, ?OtherCleanTime, ?MediaType, ?MediaDescription, "+
|
||||
"?AuthbuyerID, ?OtherCleanTime, ?Dwell, ?MediaType, ?MediaDescription, "+
|
||||
"CONCAT(?MediaWidth, ',', ?MediaHeight), ?MediaLoop, ?ObscureMusic, ?ObscureMedia)";
|
||||
|
||||
FillLandCommand(cmd, parcel.LandData, parcel.RegionUUID);
|
||||
@@ -1478,6 +1484,7 @@ namespace OpenSim.Data.MySQL
|
||||
UUID.TryParse((string)row["AuthBuyerID"], out authedbuyer);
|
||||
UUID.TryParse((string)row["SnapshotUUID"], out snapshotID);
|
||||
newData.OtherCleanTime = Convert.ToInt32(row["OtherCleanTime"]);
|
||||
newData.Dwell = Convert.ToSingle(row["Dwell"]);
|
||||
|
||||
newData.AuthBuyerID = authedbuyer;
|
||||
newData.SnapshotID = snapshotID;
|
||||
@@ -1524,30 +1531,6 @@ namespace OpenSim.Data.MySQL
|
||||
return entry;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="val"></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>
|
||||
/// Fill the prim command with prim values
|
||||
/// </summary>
|
||||
@@ -1833,6 +1816,7 @@ namespace OpenSim.Data.MySQL
|
||||
cmd.Parameters.AddWithValue("UserLookAtZ", land.UserLookAt.Z);
|
||||
cmd.Parameters.AddWithValue("AuthBuyerID", land.AuthBuyerID);
|
||||
cmd.Parameters.AddWithValue("OtherCleanTime", land.OtherCleanTime);
|
||||
cmd.Parameters.AddWithValue("Dwell", land.Dwell);
|
||||
cmd.Parameters.AddWithValue("MediaDescription", land.MediaDescription);
|
||||
cmd.Parameters.AddWithValue("MediaType", land.MediaType);
|
||||
cmd.Parameters.AddWithValue("MediaWidth", land.MediaWidth);
|
||||
@@ -1840,7 +1824,6 @@ namespace OpenSim.Data.MySQL
|
||||
cmd.Parameters.AddWithValue("MediaLoop", land.MediaLoop);
|
||||
cmd.Parameters.AddWithValue("ObscureMusic", land.ObscureMusic);
|
||||
cmd.Parameters.AddWithValue("ObscureMedia", land.ObscureMedia);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -634,8 +634,6 @@ namespace OpenSim.Data.MySQL
|
||||
{
|
||||
if(reader.HasRows)
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
": Getting data for {0}.", props.UserId);
|
||||
reader.Read();
|
||||
props.WebUrl = (string)reader["profileURL"];
|
||||
UUID.TryParse((string)reader["profileImage"], out props.ImageId);
|
||||
@@ -651,9 +649,6 @@ namespace OpenSim.Data.MySQL
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
": No data for {0}", props.UserId);
|
||||
|
||||
props.WebUrl = string.Empty;
|
||||
props.ImageId = UUID.Zero;
|
||||
props.AboutText = string.Empty;
|
||||
@@ -974,8 +969,8 @@ namespace OpenSim.Data.MySQL
|
||||
dbcon.Open();
|
||||
using (MySqlCommand cmd = new MySqlCommand(query, dbcon))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("?ImViaEmail", pref.IMViaEmail);
|
||||
cmd.Parameters.AddWithValue("?Visible", pref.Visible);
|
||||
cmd.Parameters.AddWithValue("?ImViaEmail", pref.IMViaEmail.ToString().ToLower());
|
||||
cmd.Parameters.AddWithValue("?Visible", pref.Visible.ToString().ToLower());
|
||||
cmd.Parameters.AddWithValue("?uuid", pref.UserId.ToString());
|
||||
|
||||
cmd.ExecuteNonQuery();
|
||||
|
||||
@@ -210,18 +210,18 @@ namespace OpenSim.Data.MySQL
|
||||
using (MySqlTransaction transaction = dbcon.BeginTransaction())
|
||||
{
|
||||
string assetName = asset.Name;
|
||||
if (asset.Name.Length > 64)
|
||||
if (asset.Name.Length > AssetBase.MAX_ASSET_NAME)
|
||||
{
|
||||
assetName = asset.Name.Substring(0, 64);
|
||||
assetName = asset.Name.Substring(0, AssetBase.MAX_ASSET_NAME);
|
||||
m_log.WarnFormat(
|
||||
"[XASSET 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)
|
||||
if (asset.Description.Length > AssetBase.MAX_ASSET_DESC)
|
||||
{
|
||||
assetDescription = asset.Description.Substring(0, 64);
|
||||
assetDescription = asset.Description.Substring(0, AssetBase.MAX_ASSET_DESC);
|
||||
m_log.WarnFormat(
|
||||
"[XASSET DB]: Description '{0}' for asset {1} truncated from {2} to {3} characters on add",
|
||||
asset.Description, asset.ID, asset.Description.Length, assetDescription.Length);
|
||||
@@ -346,7 +346,7 @@ namespace OpenSim.Data.MySQL
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
catch (Exception)
|
||||
{
|
||||
m_log.ErrorFormat(
|
||||
"[XASSET MYSQL DB]: Failure updating access_time for asset {0} with name {1}",
|
||||
@@ -397,45 +397,43 @@ namespace OpenSim.Data.MySQL
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if the asset exists in the database
|
||||
/// Check if the assets exist in the database.
|
||||
/// </summary>
|
||||
/// <param name="uuid">The asset UUID</param>
|
||||
/// <returns>true if it exists, false otherwise.</returns>
|
||||
public bool ExistsAsset(UUID uuid)
|
||||
/// <param name="uuids">The asset UUID's</param>
|
||||
/// <returns>For each asset: true if it exists, false otherwise</returns>
|
||||
public bool[] AssetsExist(UUID[] uuids)
|
||||
{
|
||||
// m_log.DebugFormat("[ASSETS DB]: Checking for asset {0}", uuid);
|
||||
if (uuids.Length == 0)
|
||||
return new bool[0];
|
||||
|
||||
bool assetExists = false;
|
||||
HashSet<UUID> exists = new HashSet<UUID>();
|
||||
|
||||
string ids = "'" + string.Join("','", uuids) + "'";
|
||||
string sql = string.Format("SELECT ID FROM assets WHERE ID IN ({0})", ids);
|
||||
|
||||
lock (m_dbLock)
|
||||
{
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
dbcon.Open();
|
||||
using (MySqlCommand cmd = new MySqlCommand("SELECT ID FROM XAssetsMeta WHERE ID=?ID", dbcon))
|
||||
using (MySqlCommand cmd = new MySqlCommand(sql, dbcon))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("?ID", uuid.ToString());
|
||||
|
||||
try
|
||||
using (MySqlDataReader dbReader = cmd.ExecuteReader())
|
||||
{
|
||||
using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow))
|
||||
while (dbReader.Read())
|
||||
{
|
||||
if (dbReader.Read())
|
||||
{
|
||||
// m_log.DebugFormat("[ASSETS DB]: Found asset {0}", uuid);
|
||||
assetExists = true;
|
||||
}
|
||||
UUID id = DBGuid.FromDB(dbReader["ID"]);
|
||||
exists.Add(id);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Error(string.Format("[XASSETS DB]: MySql failure fetching asset {0}", uuid), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return assetExists;
|
||||
bool[] results = new bool[uuids.Length];
|
||||
for (int i = 0; i < uuids.Length; i++)
|
||||
results[i] = exists.Contains(uuids[i]);
|
||||
return results;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
:VERSION 1 # --------------------------
|
||||
:VERSION 1 # --------------------------
|
||||
|
||||
BEGIN;
|
||||
|
||||
@@ -32,3 +32,11 @@ ALTER TABLE `im_offline`
|
||||
ADD KEY `FromID` (`FromID`);
|
||||
|
||||
COMMIT;
|
||||
|
||||
:VERSION 4 # --------------------------
|
||||
|
||||
BEGIN;
|
||||
|
||||
ALTER TABLE im_offline CONVERT TO CHARACTER SET utf8;
|
||||
|
||||
COMMIT;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
:VERSION 1 # --------------------------
|
||||
:VERSION 1 # --------------------------
|
||||
|
||||
BEGIN;
|
||||
|
||||
@@ -21,3 +21,11 @@ BEGIN;
|
||||
ALTER TABLE `Presence` ADD COLUMN LastSeen timestamp;
|
||||
|
||||
COMMIT;
|
||||
|
||||
:VERSION 3 # --------------------------
|
||||
|
||||
BEGIN;
|
||||
|
||||
CREATE INDEX RegionID ON Presence(RegionID);
|
||||
|
||||
COMMIT;
|
||||
|
||||
@@ -42,7 +42,7 @@ namespace OpenSim.Data.Null
|
||||
|
||||
// private string m_connectionString;
|
||||
|
||||
private Dictionary<uint, EstateSettings> m_knownEstates = new Dictionary<uint, EstateSettings>();
|
||||
// private Dictionary<uint, EstateSettings> m_knownEstates = new Dictionary<uint, EstateSettings>();
|
||||
private EstateSettings m_estate = null;
|
||||
|
||||
private EstateSettings GetEstate()
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace OpenSim.Data.Null
|
||||
{
|
||||
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private static NullPresenceData Instance;
|
||||
public static NullPresenceData Instance;
|
||||
|
||||
Dictionary<UUID, PresenceData> m_presenceData = new Dictionary<UUID, PresenceData>();
|
||||
|
||||
|
||||
@@ -132,15 +132,33 @@ namespace OpenSim.Data.Null
|
||||
return new List<SceneObjectGroup>();
|
||||
}
|
||||
|
||||
Dictionary<UUID, double[,]> m_terrains = new Dictionary<UUID, double[,]>();
|
||||
public void StoreTerrain(double[,] ter, UUID regionID)
|
||||
Dictionary<UUID, TerrainData> m_terrains = new Dictionary<UUID, TerrainData>();
|
||||
public void StoreTerrain(TerrainData ter, UUID regionID)
|
||||
{
|
||||
if (m_terrains.ContainsKey(regionID))
|
||||
m_terrains.Remove(regionID);
|
||||
m_terrains.Add(regionID, ter);
|
||||
}
|
||||
|
||||
// Legacy. Just don't do this.
|
||||
public void StoreTerrain(double[,] ter, UUID regionID)
|
||||
{
|
||||
TerrainData terrData = new HeightmapTerrainData(ter);
|
||||
StoreTerrain(terrData, regionID);
|
||||
}
|
||||
|
||||
// Legacy. Just don't do this.
|
||||
// Returns 'null' if region not found
|
||||
public double[,] LoadTerrain(UUID regionID)
|
||||
{
|
||||
if (m_terrains.ContainsKey(regionID))
|
||||
{
|
||||
return m_terrains[regionID].GetDoubles();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public TerrainData LoadTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ)
|
||||
{
|
||||
if (m_terrains.ContainsKey(regionID))
|
||||
{
|
||||
|
||||
@@ -38,7 +38,7 @@ using OpenSim.Data;
|
||||
|
||||
namespace OpenSim.Data.Null
|
||||
{
|
||||
public class NullXGroupData : NullGenericDataHandler, IXGroupData
|
||||
public class NullXGroupData : IXGroupData
|
||||
{
|
||||
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
@@ -56,35 +56,31 @@ namespace OpenSim.Data.Null
|
||||
return true;
|
||||
}
|
||||
|
||||
public XGroup[] GetGroups(string field, string val)
|
||||
public XGroup GetGroup(UUID groupID)
|
||||
{
|
||||
return GetGroups(new string[] { field }, new string[] { val });
|
||||
XGroup group = null;
|
||||
|
||||
lock (m_groups)
|
||||
m_groups.TryGetValue(groupID, out group);
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
public XGroup[] GetGroups(string[] fields, string[] vals)
|
||||
public Dictionary<UUID, XGroup> GetGroups()
|
||||
{
|
||||
Dictionary<UUID, XGroup> groupsClone = new Dictionary<UUID, XGroup>();
|
||||
|
||||
lock (m_groups)
|
||||
foreach (XGroup group in m_groups.Values)
|
||||
groupsClone[group.groupID] = group.Clone();
|
||||
|
||||
return groupsClone;
|
||||
}
|
||||
|
||||
public bool DeleteGroup(UUID groupID)
|
||||
{
|
||||
lock (m_groups)
|
||||
{
|
||||
List<XGroup> origGroups = Get<XGroup>(fields, vals, m_groups.Values.ToList());
|
||||
|
||||
return origGroups.Select(g => g.Clone()).ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
public bool DeleteGroups(string field, string val)
|
||||
{
|
||||
return DeleteGroups(new string[] { field }, new string[] { val });
|
||||
}
|
||||
|
||||
public bool DeleteGroups(string[] fields, string[] vals)
|
||||
{
|
||||
lock (m_groups)
|
||||
{
|
||||
XGroup[] groupsToDelete = GetGroups(fields, vals);
|
||||
Array.ForEach(groupsToDelete, g => m_groups.Remove(g.groupID));
|
||||
}
|
||||
|
||||
return true;
|
||||
return m_groups.Remove(groupID);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -166,18 +166,18 @@ namespace OpenSim.Data.PGSQL
|
||||
";
|
||||
|
||||
string assetName = asset.Name;
|
||||
if (asset.Name.Length > 64)
|
||||
if (asset.Name.Length > AssetBase.MAX_ASSET_NAME)
|
||||
{
|
||||
assetName = asset.Name.Substring(0, 64);
|
||||
assetName = asset.Name.Substring(0, AssetBase.MAX_ASSET_NAME);
|
||||
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)
|
||||
if (asset.Description.Length > AssetBase.MAX_ASSET_DESC)
|
||||
{
|
||||
assetDescription = asset.Description.Substring(0, 64);
|
||||
assetDescription = asset.Description.Substring(0, AssetBase.MAX_ASSET_DESC);
|
||||
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);
|
||||
@@ -231,17 +231,38 @@ namespace OpenSim.Data.PGSQL
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// Check if asset exist in m_database
|
||||
/// Check if the assets exist in the database.
|
||||
/// </summary>
|
||||
/// <param name="uuid"></param>
|
||||
/// <returns>true if exist.</returns>
|
||||
override public bool ExistsAsset(UUID uuid)
|
||||
/// <param name="uuids">The assets' IDs</param>
|
||||
/// <returns>For each asset: true if it exists, false otherwise</returns>
|
||||
public override bool[] AssetsExist(UUID[] uuids)
|
||||
{
|
||||
if (GetAsset(uuid) != null)
|
||||
if (uuids.Length == 0)
|
||||
return new bool[0];
|
||||
|
||||
HashSet<UUID> exist = new HashSet<UUID>();
|
||||
|
||||
string ids = "'" + string.Join("','", uuids) + "'";
|
||||
string sql = string.Format("SELECT id FROM assets WHERE id IN ({0})", ids);
|
||||
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
||||
{
|
||||
return true;
|
||||
conn.Open();
|
||||
using (NpgsqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
UUID id = DBGuid.FromDB(reader["id"]);
|
||||
exist.Add(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
bool[] results = new bool[uuids.Length];
|
||||
for (int i = 0; i < uuids.Length; i++)
|
||||
results[i] = exist.Contains(uuids[i]);
|
||||
return results;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -51,7 +51,7 @@ namespace OpenSim.Data.PGSQL
|
||||
}
|
||||
|
||||
|
||||
public bool Delete(string principalID, string friend)
|
||||
public override bool Delete(string principalID, string friend)
|
||||
{
|
||||
UUID princUUID = UUID.Zero;
|
||||
|
||||
|
||||
@@ -300,7 +300,6 @@ namespace OpenSim.Data.PGSQL
|
||||
m_Realm, where);
|
||||
cmd.Connection = conn;
|
||||
cmd.CommandText = query;
|
||||
|
||||
//m_log.WarnFormat("[PGSQLGenericTable]: SELECT {0} WHERE {1}", m_Realm, where);
|
||||
|
||||
conn.Open();
|
||||
@@ -308,6 +307,25 @@ namespace OpenSim.Data.PGSQL
|
||||
}
|
||||
}
|
||||
|
||||
public virtual T[] Get(string where, NpgsqlParameter parameter)
|
||||
{
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString))
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand())
|
||||
{
|
||||
|
||||
string query = String.Format("SELECT * FROM {0} WHERE {1}",
|
||||
m_Realm, where);
|
||||
cmd.Connection = conn;
|
||||
cmd.CommandText = query;
|
||||
//m_log.WarnFormat("[PGSQLGenericTable]: SELECT {0} WHERE {1}", m_Realm, where);
|
||||
|
||||
cmd.Parameters.Add(parameter);
|
||||
|
||||
conn.Open();
|
||||
return DoQuery(cmd);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool Store(T row)
|
||||
{
|
||||
List<string> constraintFields = GetConstraints();
|
||||
|
||||
@@ -83,11 +83,15 @@ namespace OpenSim.Data.PGSQL
|
||||
public GroupData[] RetrieveGroups(string pattern)
|
||||
{
|
||||
if (string.IsNullOrEmpty(pattern)) // True for where clause
|
||||
{
|
||||
pattern = " true ORDER BY lower(\"Name\") LIMIT 100";
|
||||
return m_Groups.Get(pattern);
|
||||
}
|
||||
else
|
||||
pattern = string.Format(" lower(\"Name\") LIKE lower('%{0}%') ORDER BY lower(\"Name\") LIMIT 100", pattern);
|
||||
|
||||
return m_Groups.Get(pattern);
|
||||
{
|
||||
pattern = " lower(\"Name\") LIKE lower('%:pattern%') ORDER BY lower(\"Name\") LIMIT 100";
|
||||
return m_Groups.Get(pattern, new NpgsqlParameter("pattern", pattern));
|
||||
}
|
||||
}
|
||||
|
||||
public bool DeleteGroup(UUID groupID)
|
||||
|
||||
@@ -46,6 +46,7 @@ namespace OpenSim.Data.PGSQL
|
||||
public class PGSQLSimulationData : ISimulationDataStore
|
||||
{
|
||||
private const string _migrationStore = "RegionStore";
|
||||
private const string LogHeader = "[REGION DB PGSQL]";
|
||||
|
||||
// private static FileSystemDataStore Instance = new FileSystemDataStore();
|
||||
private static readonly ILog _Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
@@ -523,44 +524,54 @@ namespace OpenSim.Data.PGSQL
|
||||
/// <returns></returns>
|
||||
public double[,] LoadTerrain(UUID regionID)
|
||||
{
|
||||
double[,] terrain = new double[(int)Constants.RegionSize, (int)Constants.RegionSize];
|
||||
terrain.Initialize();
|
||||
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;
|
||||
|
||||
string sql = @"select ""RegionUUID"", ""Revision"", ""Heightfield"" from terrain
|
||||
where ""RegionUUID"" = :RegionUUID order by ""Revision"" desc limit 1; ";
|
||||
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
||||
{
|
||||
// PGSqlParameter param = new PGSqlParameter();
|
||||
cmd.Parameters.Add(_Database.CreateParameter("RegionUUID", regionID));
|
||||
conn.Open();
|
||||
using (NpgsqlDataReader reader = cmd.ExecuteReader())
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
||||
{
|
||||
int rev;
|
||||
if (reader.Read())
|
||||
// PGSqlParameter param = new PGSqlParameter();
|
||||
cmd.Parameters.Add(_Database.CreateParameter("RegionUUID", regionID));
|
||||
conn.Open();
|
||||
using (NpgsqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
MemoryStream str = new MemoryStream((byte[])reader["Heightfield"]);
|
||||
BinaryReader br = new BinaryReader(str);
|
||||
for (int x = 0; x < (int)Constants.RegionSize; x++)
|
||||
int rev;
|
||||
if (reader.Read())
|
||||
{
|
||||
for (int y = 0; y < (int)Constants.RegionSize; y++)
|
||||
{
|
||||
terrain[x, y] = br.ReadDouble();
|
||||
}
|
||||
rev = Convert.ToInt32(reader["Revision"]);
|
||||
byte[] blob = (byte[])reader["Heightfield"];
|
||||
terrData = TerrainData.CreateFromDatabaseBlobFactory(pSizeX, pSizeY, pSizeZ, rev, blob);
|
||||
}
|
||||
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);
|
||||
}
|
||||
else
|
||||
{
|
||||
_Log.Info("[REGION DB]: No terrain found for region");
|
||||
return null;
|
||||
}
|
||||
_Log.Info("[REGION DB]: Loaded terrain revision r" + rev);
|
||||
}
|
||||
}
|
||||
|
||||
return terrain;
|
||||
return terrData;
|
||||
}
|
||||
|
||||
// Legacy entry point for when terrain was always a 256x256 heightmap
|
||||
public void StoreTerrain(double[,] terrain, UUID regionID)
|
||||
{
|
||||
StoreTerrain(new HeightmapTerrainData(terrain), regionID);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -568,35 +579,43 @@ namespace OpenSim.Data.PGSQL
|
||||
/// </summary>
|
||||
/// <param name="terrain">terrain map data.</param>
|
||||
/// <param name="regionID">regionID.</param>
|
||||
public void StoreTerrain(double[,] terrain, UUID regionID)
|
||||
public void StoreTerrain(TerrainData terrData, UUID regionID)
|
||||
{
|
||||
int revision = Util.UnixTimeSinceEpoch();
|
||||
|
||||
//Delete old terrain map
|
||||
string sql = @"delete from terrain where ""RegionUUID""=:RegionUUID";
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.Add(_Database.CreateParameter("RegionUUID", regionID));
|
||||
conn.Open();
|
||||
cmd.ExecuteNonQuery();
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.Add(_Database.CreateParameter("RegionUUID", regionID));
|
||||
conn.Open();
|
||||
cmd.ExecuteNonQuery();
|
||||
|
||||
_Log.InfoFormat("{0} Deleted terrain revision id = {1}", LogHeader, regionID);
|
||||
}
|
||||
}
|
||||
|
||||
_Log.Info("[REGION DB]: Deleted terrain revision r " + revision);
|
||||
int terrainDBRevision;
|
||||
Array terrainDBblob;
|
||||
terrData.GetDatabaseBlob(out terrainDBRevision, out terrainDBblob);
|
||||
|
||||
sql = @"insert into terrain(""RegionUUID"", ""Revision"", ""Heightfield"") values(:RegionUUID, :Revision, :Heightfield)";
|
||||
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
||||
{
|
||||
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();
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(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();
|
||||
|
||||
_Log.InfoFormat("{0} Stored terrain id = {1}, terrainSize = <{2},{3}>",
|
||||
LogHeader, regionID, terrData.SizeX, terrData.SizeY);
|
||||
}
|
||||
}
|
||||
|
||||
_Log.Info("[REGION DB]: Stored terrain revision r " + revision);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1349,30 +1368,6 @@ namespace OpenSim.Data.PGSQL
|
||||
|
||||
#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>
|
||||
|
||||
@@ -406,6 +406,43 @@ namespace OpenSim.Data.PGSQL
|
||||
return exists;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if the assets exist in the database.
|
||||
/// </summary>
|
||||
/// <param name="uuids">The assets' IDs</param>
|
||||
/// <returns>For each asset: true if it exists, false otherwise</returns>
|
||||
public bool[] AssetsExist(UUID[] uuids)
|
||||
{
|
||||
if (uuids.Length == 0)
|
||||
return new bool[0];
|
||||
|
||||
HashSet<UUID> exist = new HashSet<UUID>();
|
||||
|
||||
string ids = "'" + string.Join("','", uuids) + "'";
|
||||
string sql = string.Format(@"SELECT ""ID"" FROM XAssetsMeta WHERE ""ID"" IN ({0})", ids);
|
||||
|
||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
||||
{
|
||||
conn.Open();
|
||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
||||
{
|
||||
using (NpgsqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
UUID id = DBGuid.FromDB(reader["id"]);
|
||||
exist.Add(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool[] results = new bool[uuids.Length];
|
||||
for (int i = 0; i < uuids.Length; i++)
|
||||
results[i] = exist.Contains(uuids[i]);
|
||||
return results;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if the asset exists in the database
|
||||
/// </summary>
|
||||
|
||||
@@ -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.7.6.*")]
|
||||
[assembly : AssemblyVersion("0.8.0.*")]
|
||||
|
||||
|
||||
@@ -134,25 +134,25 @@ namespace OpenSim.Data.SQLite
|
||||
override public void StoreAsset(AssetBase asset)
|
||||
{
|
||||
string assetName = asset.Name;
|
||||
if (asset.Name.Length > 64)
|
||||
if (asset.Name.Length > AssetBase.MAX_ASSET_NAME)
|
||||
{
|
||||
assetName = asset.Name.Substring(0, 64);
|
||||
assetName = asset.Name.Substring(0, AssetBase.MAX_ASSET_NAME);
|
||||
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)
|
||||
if (asset.Description.Length > AssetBase.MAX_ASSET_DESC)
|
||||
{
|
||||
assetDescription = asset.Description.Substring(0, 64);
|
||||
assetDescription = asset.Description.Substring(0, AssetBase.MAX_ASSET_DESC);
|
||||
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.Info("[ASSET DB]: Creating Asset " + asset.FullID.ToString());
|
||||
if (ExistsAsset(asset.FullID))
|
||||
if (AssetsExist(new[] { asset.FullID })[0])
|
||||
{
|
||||
//LogAssetLoad(asset);
|
||||
|
||||
@@ -214,32 +214,39 @@ namespace OpenSim.Data.SQLite
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// Check if an asset exist in database
|
||||
/// Check if the assets exist in the database.
|
||||
/// </summary>
|
||||
/// <param name="uuid">The asset UUID</param>
|
||||
/// <returns>True if exist, or false.</returns>
|
||||
override public bool ExistsAsset(UUID uuid)
|
||||
/// <param name="uuids">The assets' IDs</param>
|
||||
/// <returns>For each asset: true if it exists, false otherwise</returns>
|
||||
public override bool[] AssetsExist(UUID[] uuids)
|
||||
{
|
||||
lock (this)
|
||||
if (uuids.Length == 0)
|
||||
return new bool[0];
|
||||
|
||||
HashSet<UUID> exist = new HashSet<UUID>();
|
||||
|
||||
string ids = "'" + string.Join("','", uuids) + "'";
|
||||
string sql = string.Format("select UUID from assets where UUID in ({0})", ids);
|
||||
|
||||
lock (this)
|
||||
{
|
||||
using (SqliteCommand cmd = new SqliteCommand(SelectAssetSQL, m_conn))
|
||||
using (SqliteCommand cmd = new SqliteCommand(sql, m_conn))
|
||||
{
|
||||
cmd.Parameters.Add(new SqliteParameter(":UUID", uuid.ToString()));
|
||||
using (IDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
if (reader.Read())
|
||||
while (reader.Read())
|
||||
{
|
||||
reader.Close();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
reader.Close();
|
||||
return false;
|
||||
UUID id = new UUID((string)reader["UUID"]);
|
||||
exist.Add(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool[] results = new bool[uuids.Length];
|
||||
for (int i = 0; i < uuids.Length; i++)
|
||||
results[i] = exist.Contains(uuids[i]);
|
||||
return results;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -67,7 +67,7 @@ namespace OpenSim.Data.SQLite
|
||||
return Delete(principalID.ToString(), friend);
|
||||
}
|
||||
|
||||
public bool Delete(string principalID, string friend)
|
||||
public override bool Delete(string principalID, string friend)
|
||||
{
|
||||
using (SqliteCommand cmd = new SqliteCommand())
|
||||
{
|
||||
|
||||
@@ -51,6 +51,7 @@ namespace OpenSim.Data.SQLite
|
||||
public class SQLiteSimulationData : ISimulationDataStore
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
private static readonly string LogHeader = "[REGION DB SQLLITE]";
|
||||
|
||||
private const string primSelect = "select * from prims";
|
||||
private const string shapeSelect = "select * from primshapes";
|
||||
@@ -819,45 +820,44 @@ namespace OpenSim.Data.SQLite
|
||||
prim.Inventory.RestoreInventoryItems(inventory);
|
||||
}
|
||||
|
||||
// Legacy entry point for when terrain was always a 256x256 hieghtmap
|
||||
public void StoreTerrain(double[,] ter, UUID regionID)
|
||||
{
|
||||
StoreTerrain(new HeightmapTerrainData(ter), regionID);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Store a terrain revision in region storage
|
||||
/// </summary>
|
||||
/// <param name="ter">terrain heightfield</param>
|
||||
/// <param name="regionID">region UUID</param>
|
||||
public void StoreTerrain(double[,] ter, UUID regionID)
|
||||
public void StoreTerrain(TerrainData terrData, UUID regionID)
|
||||
{
|
||||
lock (ds)
|
||||
{
|
||||
int revision = Util.UnixTimeSinceEpoch();
|
||||
|
||||
// This is added to get rid of the infinitely growing
|
||||
// terrain databases which negatively impact on SQLite
|
||||
// over time. Before reenabling this feature there
|
||||
// needs to be a limitter put on the number of
|
||||
// revisions in the database, as this old
|
||||
// implementation is a DOS attack waiting to happen.
|
||||
|
||||
using (
|
||||
SqliteCommand cmd =
|
||||
new SqliteCommand("delete from terrain where RegionUUID=:RegionUUID and Revision <= :Revision",
|
||||
m_conn))
|
||||
SqliteCommand cmd = new SqliteCommand("delete from terrain where RegionUUID=:RegionUUID", m_conn))
|
||||
{
|
||||
cmd.Parameters.Add(new SqliteParameter(":RegionUUID", regionID.ToString()));
|
||||
cmd.Parameters.Add(new SqliteParameter(":Revision", revision));
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
// the following is an work around for .NET. The perf
|
||||
// issues associated with it aren't as bad as you think.
|
||||
m_log.Debug("[SQLITE REGION DB]: Storing terrain revision r" + revision.ToString());
|
||||
String sql = "insert into terrain(RegionUUID, Revision, Heightfield)" +
|
||||
" values(:RegionUUID, :Revision, :Heightfield)";
|
||||
|
||||
int terrainDBRevision;
|
||||
Array terrainDBblob;
|
||||
terrData.GetDatabaseBlob(out terrainDBRevision, out terrainDBblob);
|
||||
|
||||
m_log.DebugFormat("{0} Storing terrain revision r {1}", LogHeader, terrainDBRevision);
|
||||
|
||||
using (SqliteCommand cmd = new SqliteCommand(sql, m_conn))
|
||||
{
|
||||
cmd.Parameters.Add(new SqliteParameter(":RegionUUID", regionID.ToString()));
|
||||
cmd.Parameters.Add(new SqliteParameter(":Revision", revision));
|
||||
cmd.Parameters.Add(new SqliteParameter(":Heightfield", serializeTerrain(ter)));
|
||||
cmd.Parameters.Add(new SqliteParameter(":Revision", terrainDBRevision));
|
||||
cmd.Parameters.Add(new SqliteParameter(":Heightfield", terrainDBblob));
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
@@ -870,11 +870,20 @@ namespace OpenSim.Data.SQLite
|
||||
/// <returns>Heightfield data</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;
|
||||
|
||||
lock (ds)
|
||||
{
|
||||
double[,] terret = new double[(int)Constants.RegionSize, (int)Constants.RegionSize];
|
||||
terret.Initialize();
|
||||
|
||||
String sql = "select RegionUUID, Revision, Heightfield from terrain" +
|
||||
" where RegionUUID=:RegionUUID order by Revision desc";
|
||||
|
||||
@@ -887,21 +896,9 @@ namespace OpenSim.Data.SQLite
|
||||
int rev = 0;
|
||||
if (row.Read())
|
||||
{
|
||||
// TODO: put this into a function
|
||||
using (MemoryStream str = new MemoryStream((byte[])row["Heightfield"]))
|
||||
{
|
||||
using (BinaryReader br = new BinaryReader(str))
|
||||
{
|
||||
for (int x = 0; x < (int)Constants.RegionSize; x++)
|
||||
{
|
||||
for (int y = 0; y < (int)Constants.RegionSize; y++)
|
||||
{
|
||||
terret[x, y] = br.ReadDouble();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
rev = Convert.ToInt32(row["Revision"]);
|
||||
byte[] blob = (byte[])row["Heightfield"];
|
||||
terrData = TerrainData.CreateFromDatabaseBlobFactory(pSizeX, pSizeY, pSizeZ, rev, blob);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -912,8 +909,8 @@ namespace OpenSim.Data.SQLite
|
||||
m_log.Debug("[SQLITE REGION DB]: Loaded terrain revision r" + rev.ToString());
|
||||
}
|
||||
}
|
||||
return terret;
|
||||
}
|
||||
return terrData;
|
||||
}
|
||||
|
||||
public void RemoveLandObject(UUID globalID)
|
||||
@@ -1608,7 +1605,7 @@ namespace OpenSim.Data.SQLite
|
||||
prim.SitName = (String)row["SitName"];
|
||||
prim.TouchName = (String)row["TouchName"];
|
||||
// permissions
|
||||
prim.ObjectFlags = Convert.ToUInt32(row["ObjectFlags"]);
|
||||
prim.Flags = (PrimFlags)Convert.ToUInt32(row["ObjectFlags"]);
|
||||
prim.CreatorIdentification = (String)row["CreatorID"];
|
||||
prim.OwnerID = new UUID((String)row["OwnerID"]);
|
||||
prim.GroupID = new UUID((String)row["GroupID"]);
|
||||
@@ -2016,40 +2013,6 @@ namespace OpenSim.Data.SQLite
|
||||
return entry;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="val"></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++)
|
||||
bw.Write(val[x, y]);
|
||||
|
||||
return str.ToArray();
|
||||
}
|
||||
|
||||
// private void fillTerrainRow(DataRow row, UUID regionUUID, int rev, double[,] val)
|
||||
// {
|
||||
// row["RegionUUID"] = regionUUID;
|
||||
// row["Revision"] = rev;
|
||||
|
||||
// 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++)
|
||||
// bw.Write(val[x, y]);
|
||||
|
||||
// row["Heightfield"] = str.ToArray();
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
@@ -2071,7 +2034,7 @@ namespace OpenSim.Data.SQLite
|
||||
row["SitName"] = prim.SitName;
|
||||
row["TouchName"] = prim.TouchName;
|
||||
// permissions
|
||||
row["ObjectFlags"] = prim.ObjectFlags;
|
||||
row["ObjectFlags"] = (uint)prim.Flags;
|
||||
row["CreatorID"] = prim.CreatorIdentification.ToString();
|
||||
row["OwnerID"] = prim.OwnerID.ToString();
|
||||
row["GroupID"] = prim.GroupID.ToString();
|
||||
|
||||
@@ -50,7 +50,6 @@ namespace OpenSim.Data.SQLite
|
||||
private SqliteConnection m_connection;
|
||||
private string m_connectionString;
|
||||
|
||||
private FieldInfo[] m_Fields;
|
||||
private Dictionary<string, FieldInfo> m_FieldMap =
|
||||
new Dictionary<string, FieldInfo>();
|
||||
|
||||
@@ -585,9 +584,6 @@ namespace OpenSim.Data.SQLite
|
||||
}
|
||||
if(reader != null && reader.Read())
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
": Getting data for {0}.", props.UserId);
|
||||
|
||||
props.WebUrl = (string)reader["profileURL"];
|
||||
UUID.TryParse((string)reader["profileImage"], out props.ImageId);
|
||||
props.AboutText = (string)reader["profileAboutText"];
|
||||
@@ -602,9 +598,6 @@ namespace OpenSim.Data.SQLite
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.DebugFormat("[PROFILES_DATA]" +
|
||||
": No data for {0}", props.UserId);
|
||||
|
||||
props.WebUrl = string.Empty;
|
||||
props.ImageId = UUID.Zero;
|
||||
props.AboutText = string.Empty;
|
||||
|
||||
@@ -107,10 +107,11 @@ namespace OpenSim.Data.Tests
|
||||
public void T001_LoadEmpty()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
|
||||
Assert.That(m_db.ExistsAsset(uuid1), Is.False);
|
||||
Assert.That(m_db.ExistsAsset(uuid2), Is.False);
|
||||
Assert.That(m_db.ExistsAsset(uuid3), Is.False);
|
||||
|
||||
bool[] exist = m_db.AssetsExist(new[] { uuid1, uuid2, uuid3 });
|
||||
Assert.IsFalse(exist[0]);
|
||||
Assert.IsFalse(exist[1]);
|
||||
Assert.IsFalse(exist[2]);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -159,9 +160,10 @@ namespace OpenSim.Data.Tests
|
||||
AssetBase a3b = m_db.GetAsset(uuid3);
|
||||
Assert.That(a3b, Constraints.PropertyCompareConstraint(a3a));
|
||||
|
||||
Assert.That(m_db.ExistsAsset(uuid1), Is.True);
|
||||
Assert.That(m_db.ExistsAsset(uuid2), Is.True);
|
||||
Assert.That(m_db.ExistsAsset(uuid3), Is.True);
|
||||
bool[] exist = m_db.AssetsExist(new[] { uuid1, uuid2, uuid3 });
|
||||
Assert.IsTrue(exist[0]);
|
||||
Assert.IsTrue(exist[1]);
|
||||
Assert.IsTrue(exist[2]);
|
||||
|
||||
List<AssetMetadata> metadatas = m_db.FetchAssetMetadataSet(0, 1000);
|
||||
|
||||
|
||||
@@ -99,6 +99,9 @@ namespace OpenSim.Data.Tests
|
||||
if (Directory.Exists("/proc/ppc64") || Directory.Exists("/proc/dasd"))
|
||||
Assert.Ignore();
|
||||
|
||||
if (Util.IsWindows())
|
||||
Util.LoadArchSpecificWindowsDll("sqlite3.dll");
|
||||
|
||||
// for SQLite, if no explicit conn string is specified, use a temp file
|
||||
if (String.IsNullOrEmpty(m_connStr))
|
||||
{
|
||||
|
||||
@@ -321,6 +321,8 @@ namespace OpenSim.Framework
|
||||
Mac = args["mac"].AsString();
|
||||
if (args["id0"] != null)
|
||||
Id0 = args["id0"].AsString();
|
||||
if (args["teleport_flags"] != null)
|
||||
teleportFlags = args["teleport_flags"].AsUInteger();
|
||||
|
||||
if (args["start_pos"] != null)
|
||||
Vector3.TryParse(args["start_pos"].AsString(), out startpos);
|
||||
|
||||
@@ -132,6 +132,11 @@ namespace OpenSim.Framework
|
||||
return base.Equals(obj);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return base.GetHashCode();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "AnimID=" + AnimID.ToString()
|
||||
|
||||
@@ -50,6 +50,9 @@ namespace OpenSim.Framework
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
public static readonly int MAX_ASSET_NAME = 64;
|
||||
public static readonly int MAX_ASSET_DESC = 64;
|
||||
|
||||
/// <summary>
|
||||
/// Data of the Asset
|
||||
/// </summary>
|
||||
|
||||
@@ -98,11 +98,11 @@ namespace OpenSim.Framework
|
||||
/// </remarks>
|
||||
public bool Contains(T item)
|
||||
{
|
||||
if (m_queue.Count < 1 && m_pqueue.Count < 1)
|
||||
return false;
|
||||
|
||||
lock (m_queueSync)
|
||||
{
|
||||
if (m_queue.Count < 1 && m_pqueue.Count < 1)
|
||||
return false;
|
||||
|
||||
if (m_pqueue.Contains(item))
|
||||
return true;
|
||||
return m_queue.Contains(item);
|
||||
@@ -112,12 +112,10 @@ namespace OpenSim.Framework
|
||||
/// <summary>
|
||||
/// Return a count of the number of requests on this queue.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method is not thread-safe. Do not rely on the result without consistent external locking.
|
||||
/// </remarks>
|
||||
public int Count()
|
||||
{
|
||||
return m_queue.Count + m_pqueue.Count;
|
||||
lock (m_queueSync)
|
||||
return m_queue.Count + m_pqueue.Count;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -128,11 +126,11 @@ namespace OpenSim.Framework
|
||||
/// </remarks>
|
||||
public T[] GetQueueArray()
|
||||
{
|
||||
if (m_queue.Count < 1 && m_pqueue.Count < 1)
|
||||
return new T[0];
|
||||
|
||||
lock (m_queueSync)
|
||||
{
|
||||
if (m_queue.Count < 1 && m_pqueue.Count < 1)
|
||||
return new T[0];
|
||||
|
||||
return m_queue.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +35,8 @@ using System.Threading;
|
||||
using System.Web;
|
||||
using log4net;
|
||||
|
||||
using OpenSim.Framework.ServiceAuth;
|
||||
|
||||
namespace OpenSim.Framework.Communications
|
||||
{
|
||||
/// <summary>
|
||||
@@ -298,6 +300,14 @@ namespace OpenSim.Framework.Communications
|
||||
/// Perform a synchronous request
|
||||
/// </summary>
|
||||
public Stream Request()
|
||||
{
|
||||
return Request(null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Perform a synchronous request
|
||||
/// </summary>
|
||||
public Stream Request(IServiceAuth auth)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
@@ -307,6 +317,8 @@ namespace OpenSim.Framework.Communications
|
||||
_request.Timeout = 200000;
|
||||
_request.Method = RequestMethod;
|
||||
_asyncException = null;
|
||||
if (auth != null)
|
||||
auth.AddAuthorization(_request.Headers);
|
||||
|
||||
// IAsyncResult responseAsyncResult = _request.BeginGetResponse(new AsyncCallback(ResponseIsReadyDelegate), _request);
|
||||
try
|
||||
@@ -318,12 +330,12 @@ namespace OpenSim.Framework.Communications
|
||||
HttpWebResponse errorResponse = e.Response as HttpWebResponse;
|
||||
if (null != errorResponse && HttpStatusCode.NotFound == errorResponse.StatusCode)
|
||||
{
|
||||
m_log.Warn("[REST CLIENT] Resource not found (404)");
|
||||
// This is often benign. E.g., requesting a missing asset will return 404.
|
||||
m_log.DebugFormat("[REST CLIENT] Resource not found (404): {0}", _request.Address.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.Error("[REST CLIENT] Error fetching resource from server " + _request.Address.ToString());
|
||||
m_log.Debug(e.ToString());
|
||||
m_log.Error(string.Format("[REST CLIENT] Error fetching resource from server: {0} ", _request.Address.ToString()), e);
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -358,7 +370,7 @@ namespace OpenSim.Framework.Communications
|
||||
}
|
||||
}
|
||||
|
||||
public Stream Request(Stream src)
|
||||
public Stream Request(Stream src, IServiceAuth auth)
|
||||
{
|
||||
_request = (HttpWebRequest) WebRequest.Create(buildUri());
|
||||
_request.KeepAlive = false;
|
||||
@@ -367,6 +379,8 @@ namespace OpenSim.Framework.Communications
|
||||
_request.Method = RequestMethod;
|
||||
_asyncException = null;
|
||||
_request.ContentLength = src.Length;
|
||||
if (auth != null)
|
||||
auth.AddAuthorization(_request.Headers);
|
||||
|
||||
m_log.InfoFormat("[REST]: Request Length {0}", _request.ContentLength);
|
||||
m_log.InfoFormat("[REST]: Sending Web Request {0}", buildUri());
|
||||
@@ -384,7 +398,22 @@ namespace OpenSim.Framework.Communications
|
||||
length = src.Read(buf, 0, 1024);
|
||||
}
|
||||
|
||||
_response = (HttpWebResponse) _request.GetResponse();
|
||||
try
|
||||
{
|
||||
_response = (HttpWebResponse)_request.GetResponse();
|
||||
}
|
||||
catch (WebException e)
|
||||
{
|
||||
m_log.WarnFormat("[REST]: Request {0} {1} failed with status {2} and message {3}",
|
||||
RequestMethod, _request.RequestUri, e.Status, e.Message);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.WarnFormat(
|
||||
"[REST]: Request {0} {1} failed with exception {2} {3}",
|
||||
RequestMethod, _request.RequestUri, e.Message, e.StackTrace);
|
||||
}
|
||||
|
||||
|
||||
// IAsyncResult responseAsyncResult = _request.BeginGetResponse(new AsyncCallback(ResponseIsReadyDelegate), _request);
|
||||
|
||||
@@ -423,7 +452,7 @@ namespace OpenSim.Framework.Communications
|
||||
try
|
||||
{
|
||||
// Perform the operation; if sucessful set the result
|
||||
Stream s = Request();
|
||||
Stream s = Request(null);
|
||||
ar.SetAsCompleted(s, false);
|
||||
}
|
||||
catch (Exception e)
|
||||
|
||||
@@ -1,123 +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.IO;
|
||||
using System.Net;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using log4net;
|
||||
using OpenSim.Framework.Configuration.XML;
|
||||
|
||||
namespace OpenSim.Framework.Configuration.HTTP
|
||||
{
|
||||
public class HTTPConfiguration : IGenericConfig
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private RemoteConfigSettings remoteConfigSettings;
|
||||
|
||||
private XmlConfiguration xmlConfig;
|
||||
|
||||
private string configFileName = String.Empty;
|
||||
|
||||
public HTTPConfiguration()
|
||||
{
|
||||
remoteConfigSettings = new RemoteConfigSettings("remoteconfig.xml");
|
||||
xmlConfig = new XmlConfiguration();
|
||||
}
|
||||
|
||||
public void SetFileName(string fileName)
|
||||
{
|
||||
configFileName = fileName;
|
||||
}
|
||||
|
||||
public void LoadData()
|
||||
{
|
||||
try
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
byte[] buf = new byte[8192];
|
||||
HttpWebRequest request =
|
||||
(HttpWebRequest) WebRequest.Create(remoteConfigSettings.baseConfigURL + configFileName);
|
||||
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
|
||||
{
|
||||
using (Stream resStream = response.GetResponseStream())
|
||||
{
|
||||
string tempString = null;
|
||||
int count = 0;
|
||||
|
||||
do
|
||||
{
|
||||
count = resStream.Read(buf, 0, buf.Length);
|
||||
if (count != 0)
|
||||
{
|
||||
tempString = Util.UTF8.GetString(buf, 0, count);
|
||||
sb.Append(tempString);
|
||||
}
|
||||
}
|
||||
while (count > 0);
|
||||
|
||||
LoadDataFromString(sb.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (WebException)
|
||||
{
|
||||
m_log.Warn("Unable to connect to remote configuration file (" +
|
||||
remoteConfigSettings.baseConfigURL + configFileName +
|
||||
"). Creating local file instead.");
|
||||
xmlConfig.SetFileName(configFileName);
|
||||
xmlConfig.LoadData();
|
||||
}
|
||||
}
|
||||
|
||||
public void LoadDataFromString(string data)
|
||||
{
|
||||
xmlConfig.LoadDataFromString(data);
|
||||
}
|
||||
|
||||
public string GetAttribute(string attributeName)
|
||||
{
|
||||
return xmlConfig.GetAttribute(attributeName);
|
||||
}
|
||||
|
||||
public bool SetAttribute(string attributeName, string attributeValue)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Commit()
|
||||
{
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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.Framework.Configuration.HTTP")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("http://opensimulator.org")]
|
||||
[assembly: AssemblyProduct("OpenSim")]
|
||||
[assembly: AssemblyCopyright("OpenSimulator develoeprs")]
|
||||
[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("cb78b672-d000-4f93-88f9-dae151cc0061")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
[assembly: AssemblyVersion("0.8.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.Framework.Configuration.XML")]
|
||||
[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("eeb880df-0112-4c3d-87ed-b2108d614c55")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
[assembly: AssemblyVersion("0.8.0.*")]
|
||||
|
||||
@@ -1,141 +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.IO;
|
||||
using System.Xml;
|
||||
|
||||
namespace OpenSim.Framework.Configuration.XML
|
||||
{
|
||||
public class XmlConfiguration : IGenericConfig
|
||||
{
|
||||
private XmlDocument doc;
|
||||
private XmlNode rootNode;
|
||||
private XmlNode configNode;
|
||||
private string fileName;
|
||||
private bool createdFile = false;
|
||||
|
||||
public void SetFileName(string file)
|
||||
{
|
||||
fileName = file;
|
||||
}
|
||||
|
||||
private void LoadDataToClass()
|
||||
{
|
||||
rootNode = doc.SelectSingleNode("Root");
|
||||
if (null == rootNode)
|
||||
throw new Exception("Error: Invalid .xml File. Missing <Root>");
|
||||
|
||||
configNode = rootNode.SelectSingleNode("Config");
|
||||
if (null == configNode)
|
||||
throw new Exception("Error: Invalid .xml File. <Root> should contain a <Config>");
|
||||
}
|
||||
|
||||
public void LoadData()
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
doc = new XmlDocument();
|
||||
if (File.Exists(fileName))
|
||||
{
|
||||
XmlTextReader reader = new XmlTextReader(fileName);
|
||||
reader.WhitespaceHandling = WhitespaceHandling.None;
|
||||
doc.Load(reader);
|
||||
reader.Close();
|
||||
}
|
||||
else
|
||||
{
|
||||
createdFile = true;
|
||||
rootNode = doc.CreateNode(XmlNodeType.Element, "Root", String.Empty);
|
||||
doc.AppendChild(rootNode);
|
||||
configNode = doc.CreateNode(XmlNodeType.Element, "Config", String.Empty);
|
||||
rootNode.AppendChild(configNode);
|
||||
}
|
||||
|
||||
LoadDataToClass();
|
||||
|
||||
if (createdFile)
|
||||
{
|
||||
Commit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void LoadDataFromString(string data)
|
||||
{
|
||||
doc = new XmlDocument();
|
||||
doc.LoadXml(data);
|
||||
|
||||
LoadDataToClass();
|
||||
}
|
||||
|
||||
public string GetAttribute(string attributeName)
|
||||
{
|
||||
string result = null;
|
||||
if (configNode.Attributes[attributeName] != null)
|
||||
{
|
||||
result = ((XmlAttribute) configNode.Attributes.GetNamedItem(attributeName)).Value;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public bool SetAttribute(string attributeName, string attributeValue)
|
||||
{
|
||||
if (configNode.Attributes[attributeName] != null)
|
||||
{
|
||||
((XmlAttribute) configNode.Attributes.GetNamedItem(attributeName)).Value = attributeValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
XmlAttribute attri;
|
||||
attri = doc.CreateAttribute(attributeName);
|
||||
attri.Value = attributeValue;
|
||||
configNode.Attributes.Append(attri);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Commit()
|
||||
{
|
||||
if (string.IsNullOrEmpty(fileName))
|
||||
return;
|
||||
|
||||
if (!Directory.Exists(Util.configDir()))
|
||||
{
|
||||
Directory.CreateDirectory(Util.configDir());
|
||||
}
|
||||
doc.Save(fileName);
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
configNode = null;
|
||||
rootNode = null;
|
||||
doc = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,530 +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.Globalization;
|
||||
using System.Net;
|
||||
using System.Reflection;
|
||||
using System.Xml;
|
||||
using log4net;
|
||||
using OpenMetaverse;
|
||||
//using OpenSim.Framework.Console;
|
||||
|
||||
namespace OpenSim.Framework
|
||||
{
|
||||
public class ConfigurationMember
|
||||
{
|
||||
#region Delegates
|
||||
|
||||
public delegate bool ConfigurationOptionResult(string configuration_key, object configuration_result);
|
||||
|
||||
public delegate void ConfigurationOptionsLoad();
|
||||
|
||||
#endregion
|
||||
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
private int cE = 0;
|
||||
|
||||
private string configurationDescription = String.Empty;
|
||||
private string configurationFilename = String.Empty;
|
||||
private XmlNode configurationFromXMLNode = null;
|
||||
private List<ConfigurationOption> configurationOptions = new List<ConfigurationOption>();
|
||||
private IGenericConfig configurationPlugin = null;
|
||||
|
||||
/// <summary>
|
||||
/// This is the default configuration DLL loaded
|
||||
/// </summary>
|
||||
private string configurationPluginFilename = "OpenSim.Framework.Configuration.XML.dll";
|
||||
|
||||
private ConfigurationOptionsLoad loadFunction;
|
||||
private ConfigurationOptionResult resultFunction;
|
||||
|
||||
private bool useConsoleToPromptOnError = true;
|
||||
|
||||
public ConfigurationMember(string configuration_filename, string configuration_description,
|
||||
ConfigurationOptionsLoad load_function, ConfigurationOptionResult result_function, bool use_console_to_prompt_on_error)
|
||||
{
|
||||
configurationFilename = configuration_filename;
|
||||
configurationDescription = configuration_description;
|
||||
loadFunction = load_function;
|
||||
resultFunction = result_function;
|
||||
useConsoleToPromptOnError = use_console_to_prompt_on_error;
|
||||
}
|
||||
|
||||
public ConfigurationMember(XmlNode configuration_xml, string configuration_description,
|
||||
ConfigurationOptionsLoad load_function, ConfigurationOptionResult result_function, bool use_console_to_prompt_on_error)
|
||||
{
|
||||
configurationFilename = String.Empty;
|
||||
configurationFromXMLNode = configuration_xml;
|
||||
configurationDescription = configuration_description;
|
||||
loadFunction = load_function;
|
||||
resultFunction = result_function;
|
||||
useConsoleToPromptOnError = use_console_to_prompt_on_error;
|
||||
}
|
||||
|
||||
public void setConfigurationFilename(string filename)
|
||||
{
|
||||
configurationFilename = filename;
|
||||
}
|
||||
|
||||
public void setConfigurationDescription(string desc)
|
||||
{
|
||||
configurationDescription = desc;
|
||||
}
|
||||
|
||||
public void setConfigurationResultFunction(ConfigurationOptionResult result)
|
||||
{
|
||||
resultFunction = result;
|
||||
}
|
||||
|
||||
public void forceConfigurationPluginLibrary(string dll_filename)
|
||||
{
|
||||
configurationPluginFilename = dll_filename;
|
||||
}
|
||||
|
||||
private void checkAndAddConfigOption(ConfigurationOption option)
|
||||
{
|
||||
if ((option.configurationKey != String.Empty && option.configurationQuestion != String.Empty) ||
|
||||
(option.configurationKey != String.Empty && option.configurationUseDefaultNoPrompt))
|
||||
{
|
||||
if (!configurationOptions.Contains(option))
|
||||
{
|
||||
configurationOptions.Add(option);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.Info(
|
||||
"Required fields for adding a configuration option is invalid. Will not add this option (" +
|
||||
option.configurationKey + ")");
|
||||
}
|
||||
}
|
||||
|
||||
public void addConfigurationOption(string configuration_key,
|
||||
ConfigurationOption.ConfigurationTypes configuration_type,
|
||||
string configuration_question, string configuration_default,
|
||||
bool use_default_no_prompt)
|
||||
{
|
||||
ConfigurationOption configOption = new ConfigurationOption();
|
||||
configOption.configurationKey = configuration_key;
|
||||
configOption.configurationQuestion = configuration_question;
|
||||
configOption.configurationDefault = configuration_default;
|
||||
configOption.configurationType = configuration_type;
|
||||
configOption.configurationUseDefaultNoPrompt = use_default_no_prompt;
|
||||
configOption.shouldIBeAsked = null; //Assumes true, I can ask whenever
|
||||
checkAndAddConfigOption(configOption);
|
||||
}
|
||||
|
||||
public void addConfigurationOption(string configuration_key,
|
||||
ConfigurationOption.ConfigurationTypes configuration_type,
|
||||
string configuration_question, string configuration_default,
|
||||
bool use_default_no_prompt,
|
||||
ConfigurationOption.ConfigurationOptionShouldBeAsked shouldIBeAskedDelegate)
|
||||
{
|
||||
ConfigurationOption configOption = new ConfigurationOption();
|
||||
configOption.configurationKey = configuration_key;
|
||||
configOption.configurationQuestion = configuration_question;
|
||||
configOption.configurationDefault = configuration_default;
|
||||
configOption.configurationType = configuration_type;
|
||||
configOption.configurationUseDefaultNoPrompt = use_default_no_prompt;
|
||||
configOption.shouldIBeAsked = shouldIBeAskedDelegate;
|
||||
checkAndAddConfigOption(configOption);
|
||||
}
|
||||
|
||||
// TEMP - REMOVE
|
||||
public void performConfigurationRetrieve()
|
||||
{
|
||||
if (cE > 1)
|
||||
m_log.Error("READING CONFIGURATION COUT: " + cE.ToString());
|
||||
|
||||
|
||||
configurationPlugin = LoadConfigDll(configurationPluginFilename);
|
||||
configurationOptions.Clear();
|
||||
if (loadFunction == null)
|
||||
{
|
||||
m_log.Error("Load Function for '" + configurationDescription +
|
||||
"' is null. Refusing to run configuration.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (resultFunction == null)
|
||||
{
|
||||
m_log.Error("Result Function for '" + configurationDescription +
|
||||
"' is null. Refusing to run configuration.");
|
||||
return;
|
||||
}
|
||||
|
||||
//m_log.Debug("[CONFIG]: Calling Configuration Load Function...");
|
||||
loadFunction();
|
||||
|
||||
if (configurationOptions.Count <= 0)
|
||||
{
|
||||
m_log.Error("[CONFIG]: No configuration options were specified for '" + configurationOptions +
|
||||
"'. Refusing to continue configuration.");
|
||||
return;
|
||||
}
|
||||
|
||||
bool useFile = true;
|
||||
if (configurationPlugin == null)
|
||||
{
|
||||
m_log.Error("[CONFIG]: Configuration Plugin NOT LOADED!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (configurationFilename.Trim() != String.Empty)
|
||||
{
|
||||
configurationPlugin.SetFileName(configurationFilename);
|
||||
try
|
||||
{
|
||||
configurationPlugin.LoadData();
|
||||
useFile = true;
|
||||
}
|
||||
catch (XmlException e)
|
||||
{
|
||||
m_log.WarnFormat("[CONFIG] Not using {0}: {1}",
|
||||
configurationFilename,
|
||||
e.Message.ToString());
|
||||
//m_log.Error("Error loading " + configurationFilename + ": " + e.ToString());
|
||||
useFile = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (configurationFromXMLNode != null)
|
||||
{
|
||||
m_log.Info("Loading from XML Node, will not save to the file");
|
||||
configurationPlugin.LoadDataFromString(configurationFromXMLNode.OuterXml);
|
||||
}
|
||||
|
||||
m_log.Info("XML Configuration Filename is not valid; will not save to the file.");
|
||||
useFile = false;
|
||||
}
|
||||
|
||||
foreach (ConfigurationOption configOption in configurationOptions)
|
||||
{
|
||||
bool convertSuccess = false;
|
||||
object return_result = null;
|
||||
string errorMessage = String.Empty;
|
||||
bool ignoreNextFromConfig = false;
|
||||
while (convertSuccess == false)
|
||||
{
|
||||
string console_result = String.Empty;
|
||||
string attribute = null;
|
||||
if (useFile || configurationFromXMLNode != null)
|
||||
{
|
||||
if (!ignoreNextFromConfig)
|
||||
{
|
||||
attribute = configurationPlugin.GetAttribute(configOption.configurationKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
ignoreNextFromConfig = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (attribute == null)
|
||||
{
|
||||
if (configOption.configurationUseDefaultNoPrompt || useConsoleToPromptOnError == false)
|
||||
{
|
||||
console_result = configOption.configurationDefault;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((configOption.shouldIBeAsked != null &&
|
||||
configOption.shouldIBeAsked(configOption.configurationKey)) ||
|
||||
configOption.shouldIBeAsked == null)
|
||||
{
|
||||
if (configurationDescription.Trim() != String.Empty)
|
||||
{
|
||||
console_result =
|
||||
MainConsole.Instance.CmdPrompt(
|
||||
configurationDescription + ": " + configOption.configurationQuestion,
|
||||
configOption.configurationDefault);
|
||||
}
|
||||
else
|
||||
{
|
||||
console_result =
|
||||
MainConsole.Instance.CmdPrompt(configOption.configurationQuestion,
|
||||
configOption.configurationDefault);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//Dont Ask! Just use default
|
||||
console_result = configOption.configurationDefault;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
console_result = attribute;
|
||||
}
|
||||
|
||||
// if the first character is a "$", assume it's the name
|
||||
// of an environment variable and substitute with the value of that variable
|
||||
if (console_result.StartsWith("$"))
|
||||
console_result = Environment.GetEnvironmentVariable(console_result.Substring(1));
|
||||
|
||||
switch (configOption.configurationType)
|
||||
{
|
||||
case ConfigurationOption.ConfigurationTypes.TYPE_STRING:
|
||||
return_result = console_result;
|
||||
convertSuccess = true;
|
||||
break;
|
||||
case ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY:
|
||||
if (console_result.Length > 0)
|
||||
{
|
||||
return_result = console_result;
|
||||
convertSuccess = true;
|
||||
}
|
||||
errorMessage = "a string that is not empty";
|
||||
break;
|
||||
case ConfigurationOption.ConfigurationTypes.TYPE_BOOLEAN:
|
||||
bool boolResult;
|
||||
if (Boolean.TryParse(console_result, out boolResult))
|
||||
{
|
||||
convertSuccess = true;
|
||||
return_result = boolResult;
|
||||
}
|
||||
errorMessage = "'true' or 'false' (Boolean)";
|
||||
break;
|
||||
case ConfigurationOption.ConfigurationTypes.TYPE_BYTE:
|
||||
byte byteResult;
|
||||
if (Byte.TryParse(console_result, out byteResult))
|
||||
{
|
||||
convertSuccess = true;
|
||||
return_result = byteResult;
|
||||
}
|
||||
errorMessage = "a byte (Byte)";
|
||||
break;
|
||||
case ConfigurationOption.ConfigurationTypes.TYPE_CHARACTER:
|
||||
char charResult;
|
||||
if (Char.TryParse(console_result, out charResult))
|
||||
{
|
||||
convertSuccess = true;
|
||||
return_result = charResult;
|
||||
}
|
||||
errorMessage = "a character (Char)";
|
||||
break;
|
||||
case ConfigurationOption.ConfigurationTypes.TYPE_INT16:
|
||||
short shortResult;
|
||||
if (Int16.TryParse(console_result, out shortResult))
|
||||
{
|
||||
convertSuccess = true;
|
||||
return_result = shortResult;
|
||||
}
|
||||
errorMessage = "a signed 32 bit integer (short)";
|
||||
break;
|
||||
case ConfigurationOption.ConfigurationTypes.TYPE_INT32:
|
||||
int intResult;
|
||||
if (Int32.TryParse(console_result, out intResult))
|
||||
{
|
||||
convertSuccess = true;
|
||||
return_result = intResult;
|
||||
}
|
||||
errorMessage = "a signed 32 bit integer (int)";
|
||||
break;
|
||||
case ConfigurationOption.ConfigurationTypes.TYPE_INT64:
|
||||
long longResult;
|
||||
if (Int64.TryParse(console_result, out longResult))
|
||||
{
|
||||
convertSuccess = true;
|
||||
return_result = longResult;
|
||||
}
|
||||
errorMessage = "a signed 32 bit integer (long)";
|
||||
break;
|
||||
case ConfigurationOption.ConfigurationTypes.TYPE_IP_ADDRESS:
|
||||
IPAddress ipAddressResult;
|
||||
if (IPAddress.TryParse(console_result, out ipAddressResult))
|
||||
{
|
||||
convertSuccess = true;
|
||||
return_result = ipAddressResult;
|
||||
}
|
||||
errorMessage = "an IP Address (IPAddress)";
|
||||
break;
|
||||
case ConfigurationOption.ConfigurationTypes.TYPE_UUID:
|
||||
UUID uuidResult;
|
||||
if (UUID.TryParse(console_result, out uuidResult))
|
||||
{
|
||||
convertSuccess = true;
|
||||
return_result = uuidResult;
|
||||
}
|
||||
errorMessage = "a UUID (UUID)";
|
||||
break;
|
||||
case ConfigurationOption.ConfigurationTypes.TYPE_UUID_NULL_FREE:
|
||||
UUID uuidResult2;
|
||||
if (UUID.TryParse(console_result, out uuidResult2))
|
||||
{
|
||||
convertSuccess = true;
|
||||
|
||||
if (uuidResult2 == UUID.Zero)
|
||||
uuidResult2 = UUID.Random();
|
||||
|
||||
return_result = uuidResult2;
|
||||
}
|
||||
errorMessage = "a non-null UUID (UUID)";
|
||||
break;
|
||||
case ConfigurationOption.ConfigurationTypes.TYPE_Vector3:
|
||||
Vector3 vectorResult;
|
||||
if (Vector3.TryParse(console_result, out vectorResult))
|
||||
{
|
||||
convertSuccess = true;
|
||||
return_result = vectorResult;
|
||||
}
|
||||
errorMessage = "a vector (Vector3)";
|
||||
break;
|
||||
case ConfigurationOption.ConfigurationTypes.TYPE_UINT16:
|
||||
ushort ushortResult;
|
||||
if (UInt16.TryParse(console_result, out ushortResult))
|
||||
{
|
||||
convertSuccess = true;
|
||||
return_result = ushortResult;
|
||||
}
|
||||
errorMessage = "an unsigned 16 bit integer (ushort)";
|
||||
break;
|
||||
case ConfigurationOption.ConfigurationTypes.TYPE_UINT32:
|
||||
uint uintResult;
|
||||
if (UInt32.TryParse(console_result, out uintResult))
|
||||
{
|
||||
convertSuccess = true;
|
||||
return_result = uintResult;
|
||||
}
|
||||
errorMessage = "an unsigned 32 bit integer (uint)";
|
||||
break;
|
||||
case ConfigurationOption.ConfigurationTypes.TYPE_UINT64:
|
||||
ulong ulongResult;
|
||||
if (UInt64.TryParse(console_result, out ulongResult))
|
||||
{
|
||||
convertSuccess = true;
|
||||
return_result = ulongResult;
|
||||
}
|
||||
errorMessage = "an unsigned 64 bit integer (ulong)";
|
||||
break;
|
||||
case ConfigurationOption.ConfigurationTypes.TYPE_FLOAT:
|
||||
float floatResult;
|
||||
if (
|
||||
float.TryParse(console_result, NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign, Culture.NumberFormatInfo,
|
||||
out floatResult))
|
||||
{
|
||||
convertSuccess = true;
|
||||
return_result = floatResult;
|
||||
}
|
||||
errorMessage = "a single-precision floating point number (float)";
|
||||
break;
|
||||
case ConfigurationOption.ConfigurationTypes.TYPE_DOUBLE:
|
||||
double doubleResult;
|
||||
if (
|
||||
Double.TryParse(console_result, NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign, Culture.NumberFormatInfo,
|
||||
out doubleResult))
|
||||
{
|
||||
convertSuccess = true;
|
||||
return_result = doubleResult;
|
||||
}
|
||||
errorMessage = "an double-precision floating point number (double)";
|
||||
break;
|
||||
}
|
||||
|
||||
if (convertSuccess)
|
||||
{
|
||||
if (useFile)
|
||||
{
|
||||
configurationPlugin.SetAttribute(configOption.configurationKey, console_result);
|
||||
}
|
||||
|
||||
if (!resultFunction(configOption.configurationKey, return_result))
|
||||
{
|
||||
m_log.Info(
|
||||
"The handler for the last configuration option denied that input, please try again.");
|
||||
convertSuccess = false;
|
||||
ignoreNextFromConfig = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (configOption.configurationUseDefaultNoPrompt)
|
||||
{
|
||||
m_log.Error(string.Format(
|
||||
"[CONFIG]: [{3}]:[{1}] is not valid default for parameter [{0}].\nThe configuration result must be parsable to {2}.\n",
|
||||
configOption.configurationKey, console_result, errorMessage,
|
||||
configurationFilename));
|
||||
convertSuccess = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.Warn(string.Format(
|
||||
"[CONFIG]: [{3}]:[{1}] is not a valid value [{0}].\nThe configuration result must be parsable to {2}.\n",
|
||||
configOption.configurationKey, console_result, errorMessage,
|
||||
configurationFilename));
|
||||
ignoreNextFromConfig = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (useFile)
|
||||
{
|
||||
configurationPlugin.Commit();
|
||||
configurationPlugin.Close();
|
||||
}
|
||||
}
|
||||
|
||||
private static IGenericConfig LoadConfigDll(string dllName)
|
||||
{
|
||||
Assembly pluginAssembly = Assembly.LoadFrom(dllName);
|
||||
IGenericConfig plug = null;
|
||||
|
||||
foreach (Type pluginType in pluginAssembly.GetTypes())
|
||||
{
|
||||
if (pluginType.IsPublic)
|
||||
{
|
||||
if (!pluginType.IsAbstract)
|
||||
{
|
||||
Type typeInterface = pluginType.GetInterface("IGenericConfig", true);
|
||||
|
||||
if (typeInterface != null)
|
||||
{
|
||||
plug =
|
||||
(IGenericConfig) Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pluginAssembly = null;
|
||||
return plug;
|
||||
}
|
||||
|
||||
public void forceSetConfigurationOption(string configuration_key, string configuration_value)
|
||||
{
|
||||
configurationPlugin.LoadData();
|
||||
configurationPlugin.SetAttribute(configuration_key, configuration_value);
|
||||
configurationPlugin.Commit();
|
||||
configurationPlugin.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
48
OpenSim/Framework/Console/ConsoleDisplayUtil.cs
Normal file
48
OpenSim/Framework/Console/ConsoleDisplayUtil.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
namespace OpenSim.Framework.Console
|
||||
{
|
||||
/// <summary>
|
||||
/// This will be a set of typical column sizes to allow greater consistency between console commands.
|
||||
/// </summary>
|
||||
public static class ConsoleDisplayUtil
|
||||
{
|
||||
public const int CoordTupleSize = 11;
|
||||
public const int PortSize = 5;
|
||||
|
||||
public const int EstateNameSize = 20;
|
||||
public const int ParcelNameSize = 40;
|
||||
public const int RegionNameSize = 20;
|
||||
public const int UserNameSize = 35;
|
||||
|
||||
public const int UuidSize = 36;
|
||||
public const int VectorSize = 15;
|
||||
}
|
||||
}
|
||||
@@ -252,24 +252,82 @@ namespace OpenSim.Framework.Console
|
||||
/// The strings "~" and "-~" are valid in components. The first substitutes float.MaxValue whilst the second is float.MinValue
|
||||
/// Other than that, component values must be numeric.
|
||||
/// </param>
|
||||
/// <param name='blankComponentFunc'></param>
|
||||
/// <param name='blankComponentFunc'>
|
||||
/// Behaviour if component is blank. If null then conversion fails on a blank component.
|
||||
/// </param>
|
||||
/// <param name='vector'></param>
|
||||
/// <returns></returns>
|
||||
public static bool TryParseConsoleVector(
|
||||
string rawConsoleVector, Func<string, string> blankComponentFunc, out Vector3 vector)
|
||||
{
|
||||
List<string> components = rawConsoleVector.Split(VectorSeparatorChars).ToList();
|
||||
|
||||
if (components.Count < 1 || components.Count > 3)
|
||||
return Vector3.TryParse(CookVector(rawConsoleVector, 3, blankComponentFunc), out vector);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert a vector input from the console to an OpenMetaverse.Vector2
|
||||
/// </summary>
|
||||
/// <param name='rawConsoleVector'>
|
||||
/// A string in the form <x>,<y> where there is no space between values.
|
||||
/// Any component can be missing (e.g. ,40). blankComponentFunc is invoked to replace the blank with a suitable value
|
||||
/// Also, if the blank component is at the end, then the comma can be missed off entirely (e.g. 40)
|
||||
/// The strings "~" and "-~" are valid in components. The first substitutes float.MaxValue whilst the second is float.MinValue
|
||||
/// Other than that, component values must be numeric.
|
||||
/// </param>
|
||||
/// <param name='blankComponentFunc'>
|
||||
/// Behaviour if component is blank. If null then conversion fails on a blank component.
|
||||
/// </param>
|
||||
/// <param name='vector'></param>
|
||||
/// <returns></returns>
|
||||
public static bool TryParseConsole2DVector(
|
||||
string rawConsoleVector, Func<string, string> blankComponentFunc, out Vector2 vector)
|
||||
{
|
||||
// We don't use Vector2.TryParse() for now because for some reason it expects an input with 3 components
|
||||
// rather than 2.
|
||||
string cookedVector = CookVector(rawConsoleVector, 2, blankComponentFunc);
|
||||
|
||||
if (cookedVector == null)
|
||||
{
|
||||
vector = Vector3.Zero;
|
||||
vector = Vector2.Zero;
|
||||
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
string[] cookedComponents = cookedVector.Split(VectorSeparatorChars);
|
||||
|
||||
vector = new Vector2(float.Parse(cookedComponents[0]), float.Parse(cookedComponents[1]));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//return Vector2.TryParse(CookVector(rawConsoleVector, 2, blankComponentFunc), out vector);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert a raw console vector into a vector that can be be parsed by the relevant OpenMetaverse.TryParse()
|
||||
/// </summary>
|
||||
/// <param name='rawConsoleVector'></param>
|
||||
/// <param name='dimensions'></param>
|
||||
/// <param name='blankComponentFunc'></param>
|
||||
/// <returns>null if conversion was not possible</returns>
|
||||
private static string CookVector(
|
||||
string rawConsoleVector, int dimensions, Func<string, string> blankComponentFunc)
|
||||
{
|
||||
List<string> components = rawConsoleVector.Split(VectorSeparatorChars).ToList();
|
||||
|
||||
for (int i = components.Count; i < 3; i++)
|
||||
components.Add("");
|
||||
if (components.Count < 1 || components.Count > dimensions)
|
||||
return null;
|
||||
|
||||
List<string> semiDigestedComponents
|
||||
if (components.Count < dimensions)
|
||||
{
|
||||
if (blankComponentFunc == null)
|
||||
return null;
|
||||
else
|
||||
for (int i = components.Count; i < dimensions; i++)
|
||||
components.Add("");
|
||||
}
|
||||
|
||||
List<string> cookedComponents
|
||||
= components.ConvertAll<string>(
|
||||
c =>
|
||||
{
|
||||
@@ -283,11 +341,7 @@ namespace OpenSim.Framework.Console
|
||||
return c;
|
||||
});
|
||||
|
||||
string semiDigestedConsoleVector = string.Join(VectorSeparator, semiDigestedComponents.ToArray());
|
||||
|
||||
// m_log.DebugFormat("[CONSOLE UTIL]: Parsing {0} into OpenMetaverse.Vector3", semiDigestedConsoleVector);
|
||||
|
||||
return Vector3.TryParse(semiDigestedConsoleVector, out vector);
|
||||
return string.Join(VectorSeparator, cookedComponents.ToArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -46,6 +46,11 @@ namespace OpenSim.Framework.Console
|
||||
// private readonly object m_syncRoot = new object();
|
||||
private const string LOGLEVEL_NONE = "(none)";
|
||||
|
||||
// Used to extract categories for colourization.
|
||||
private Regex m_categoryRegex
|
||||
= new Regex(
|
||||
@"^(?<Front>.*?)\[(?<Category>[^\]]+)\]:?(?<End>.*)", RegexOptions.Singleline | RegexOptions.Compiled);
|
||||
|
||||
private int m_cursorYPosition = -1;
|
||||
private int m_cursorXPosition = 0;
|
||||
private StringBuilder m_commandLine = new StringBuilder();
|
||||
@@ -280,11 +285,8 @@ namespace OpenSim.Framework.Console
|
||||
string outText = text;
|
||||
|
||||
if (level != LOGLEVEL_NONE)
|
||||
{
|
||||
string regex = @"^(?<Front>.*?)\[(?<Category>[^\]]+)\]:?(?<End>.*)";
|
||||
|
||||
Regex RE = new Regex(regex, RegexOptions.Multiline);
|
||||
MatchCollection matches = RE.Matches(text);
|
||||
{
|
||||
MatchCollection matches = m_categoryRegex.Matches(text);
|
||||
|
||||
if (matches.Count == 1)
|
||||
{
|
||||
|
||||
@@ -40,7 +40,9 @@ namespace OpenSim.Framework.Console
|
||||
/// </summary>
|
||||
public class MockConsole : ICommandConsole
|
||||
{
|
||||
#pragma warning disable 0067
|
||||
public event OnOutputDelegate OnOutput;
|
||||
#pragma warning restore 0067
|
||||
|
||||
private MockCommands m_commands = new MockCommands();
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace OpenSim.Framework
|
||||
@@ -411,5 +412,23 @@ namespace OpenSim.Framework
|
||||
{
|
||||
return l_EstateGroups.Contains(groupID);
|
||||
}
|
||||
|
||||
public Dictionary<string, object> ToMap()
|
||||
{
|
||||
Dictionary<string, object> map = new Dictionary<string, object>();
|
||||
PropertyInfo[] properties = this.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
|
||||
foreach (PropertyInfo p in properties)
|
||||
map[p.Name] = p.GetValue(this, null);
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
public EstateSettings(Dictionary<string, object> map)
|
||||
{
|
||||
PropertyInfo[] properties = this.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
|
||||
foreach (PropertyInfo p in properties)
|
||||
p.SetValue(this, map[p.Name], null);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ namespace OpenSim.Framework
|
||||
int GetParcelMaxPrimCount();
|
||||
int GetSimulatorMaxPrimCount();
|
||||
int GetPrimsFree();
|
||||
Dictionary<UUID, int> GetLandObjectOwners();
|
||||
|
||||
LandData LandData { get; set; }
|
||||
bool[,] LandBitmap { get; set; }
|
||||
|
||||
@@ -35,6 +35,10 @@ namespace OpenSim.Framework
|
||||
/// </summary>
|
||||
public class InventoryItemBase : InventoryNodeBase, ICloneable
|
||||
{
|
||||
public static readonly string SUITCASE_FOLDER_NAME = "My Suitcase";
|
||||
public static readonly sbyte SUITCASE_FOLDER_TYPE = 100;
|
||||
public static readonly sbyte SUITCASE_FOLDER_FAKE_TYPE = 8;
|
||||
|
||||
/// <value>
|
||||
/// The inventory type of the item. This is slightly different from the asset type in some situations.
|
||||
/// </value>
|
||||
@@ -82,12 +86,15 @@ namespace OpenSim.Framework
|
||||
set
|
||||
{
|
||||
m_creatorId = value;
|
||||
|
||||
if ((m_creatorId == null) || !UUID.TryParse(m_creatorId, out m_creatorIdAsUuid))
|
||||
m_creatorIdAsUuid = UUID.Zero;
|
||||
}
|
||||
}
|
||||
protected string m_creatorId;
|
||||
|
||||
/// <value>
|
||||
/// The CreatorId expressed as a UUID.tely
|
||||
/// The CreatorId expressed as a UUID.
|
||||
/// </value>
|
||||
public UUID CreatorIdAsUuid
|
||||
{
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
using System;
|
||||
using OpenMetaverse;
|
||||
using OpenMetaverse.StructuredData;
|
||||
|
||||
namespace OpenSim.Framework
|
||||
{
|
||||
@@ -40,9 +41,26 @@ namespace OpenSim.Framework
|
||||
public byte WaterHeight;
|
||||
public ushort X;
|
||||
public ushort Y;
|
||||
public ushort SizeX;
|
||||
public ushort SizeY;
|
||||
|
||||
public MapBlockData()
|
||||
{
|
||||
}
|
||||
|
||||
public OSDMap ToOSD()
|
||||
{
|
||||
OSDMap map = new OSDMap();
|
||||
map["X"] = X;
|
||||
map["Y"] = Y;
|
||||
map["SizeX"] = SizeX;
|
||||
map["SizeY"] = SizeY;
|
||||
map["Name"] = Name;
|
||||
map["Access"] = Access;
|
||||
map["RegionFlags"] = RegionFlags;
|
||||
map["WaterHeight"] = WaterHeight;
|
||||
map["MapImageID"] = MapImageId;
|
||||
return map;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
*/
|
||||
|
||||
using OpenMetaverse;
|
||||
using OpenMetaverse.StructuredData;
|
||||
|
||||
namespace OpenSim.Framework
|
||||
{
|
||||
@@ -37,5 +38,37 @@ namespace OpenSim.Framework
|
||||
public int Extra;
|
||||
public int Extra2;
|
||||
public string name;
|
||||
|
||||
public mapItemReply(uint pX, uint pY, UUID pId, string pName, int pExt1, int pExt2)
|
||||
{
|
||||
x = pX;
|
||||
y = pY;
|
||||
id = pId;
|
||||
name = pName;
|
||||
Extra = pExt1;
|
||||
Extra2 = pExt2;
|
||||
}
|
||||
|
||||
public OSDMap ToOSD()
|
||||
{
|
||||
OSDMap map = new OSDMap();
|
||||
map["X"] = OSD.FromInteger((int)x);
|
||||
map["Y"] = OSD.FromInteger((int)y);
|
||||
map["ID"] = OSD.FromUUID(id);
|
||||
map["Name"] = OSD.FromString(name);
|
||||
map["Extra"] = OSD.FromInteger(Extra);
|
||||
map["Extra2"] = OSD.FromInteger(Extra2);
|
||||
return map;
|
||||
}
|
||||
|
||||
public void FromOSD(OSDMap map)
|
||||
{
|
||||
x = (uint) map["X"].AsInteger();
|
||||
y = (uint) map["Y"].AsInteger();
|
||||
id = map["ID"].AsUUID();
|
||||
Extra = map["Extra"].AsInteger();
|
||||
Extra2 = map["Extra2"].AsInteger();
|
||||
name = map["Name"].AsString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,10 @@
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Timers;
|
||||
using log4net;
|
||||
|
||||
@@ -45,13 +48,22 @@ namespace OpenSim.Framework.Monitoring
|
||||
public static void RegisterConsoleCommands(ICommandConsole console)
|
||||
{
|
||||
console.Commands.AddCommand(
|
||||
"Debug",
|
||||
"General",
|
||||
false,
|
||||
"debug stats record",
|
||||
"debug stats record start|stop",
|
||||
"stats record",
|
||||
"stats record start|stop",
|
||||
"Control whether stats are being regularly recorded to a separate file.",
|
||||
"For debug purposes. Experimental.",
|
||||
HandleStatsRecordCommand);
|
||||
|
||||
console.Commands.AddCommand(
|
||||
"General",
|
||||
false,
|
||||
"stats save",
|
||||
"stats save <path>",
|
||||
"Save stats snapshot to a file. If the file already exists, then the report is appended.",
|
||||
"For debug purposes. Experimental.",
|
||||
HandleStatsSaveCommand);
|
||||
}
|
||||
|
||||
public static void HandleStatsRecordCommand(string module, string[] cmd)
|
||||
@@ -76,6 +88,27 @@ namespace OpenSim.Framework.Monitoring
|
||||
}
|
||||
}
|
||||
|
||||
public static void HandleStatsSaveCommand(string module, string[] cmd)
|
||||
{
|
||||
ICommandConsole con = MainConsole.Instance;
|
||||
|
||||
if (cmd.Length != 3)
|
||||
{
|
||||
con.Output("Usage: stats save <path>");
|
||||
return;
|
||||
}
|
||||
|
||||
string path = cmd[2];
|
||||
|
||||
using (StreamWriter sw = new StreamWriter(path, true))
|
||||
{
|
||||
foreach (string line in GetReport())
|
||||
sw.WriteLine(line);
|
||||
}
|
||||
|
||||
MainConsole.Instance.OutputFormat("Stats saved to file {0}", path);
|
||||
}
|
||||
|
||||
public static void Start()
|
||||
{
|
||||
if (m_loggingTimer != null)
|
||||
@@ -97,12 +130,22 @@ namespace OpenSim.Framework.Monitoring
|
||||
|
||||
private static void Log(object sender, ElapsedEventArgs e)
|
||||
{
|
||||
m_statsLog.InfoFormat("*** STATS REPORT AT {0} ***", DateTime.Now);
|
||||
|
||||
foreach (string report in StatsManager.GetAllStatsReports())
|
||||
m_statsLog.Info(report);
|
||||
foreach (string line in GetReport())
|
||||
m_statsLog.Info(line);
|
||||
|
||||
m_loggingTimer.Start();
|
||||
}
|
||||
|
||||
private static List<string> GetReport()
|
||||
{
|
||||
List<string> lines = new List<string>();
|
||||
|
||||
lines.Add(string.Format("*** STATS REPORT AT {0} ***", DateTime.Now));
|
||||
|
||||
foreach (string report in StatsManager.GetAllStatsReports())
|
||||
lines.Add(report);
|
||||
|
||||
return lines;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -72,8 +72,8 @@ namespace OpenSim.Framework.Monitoring
|
||||
console.Commands.AddCommand(
|
||||
"General",
|
||||
false,
|
||||
"show stats",
|
||||
"show stats [list|all|(<category>[.<container>])+",
|
||||
"stats show",
|
||||
"stats show [list|all|(<category>[.<container>])+",
|
||||
"Show statistical information for this server",
|
||||
"If no final argument is specified then legacy statistics information is currently shown.\n"
|
||||
+ "'list' argument will show statistic categories.\n"
|
||||
@@ -84,6 +84,14 @@ namespace OpenSim.Framework.Monitoring
|
||||
+ "THIS STATS FACILITY IS EXPERIMENTAL AND DOES NOT YET CONTAIN ALL STATS",
|
||||
HandleShowStatsCommand);
|
||||
|
||||
console.Commands.AddCommand(
|
||||
"General",
|
||||
false,
|
||||
"show stats",
|
||||
"show stats [list|all|(<category>[.<container>])+",
|
||||
"Alias for 'stats show' command",
|
||||
HandleShowStatsCommand);
|
||||
|
||||
StatsLogger.RegisterConsoleCommands(console);
|
||||
}
|
||||
|
||||
@@ -99,6 +107,7 @@ namespace OpenSim.Framework.Monitoring
|
||||
|
||||
string categoryName = components[0];
|
||||
string containerName = components.Length > 1 ? components[1] : null;
|
||||
string statName = components.Length > 2 ? components[2] : null;
|
||||
|
||||
if (categoryName == AllSubCommand)
|
||||
{
|
||||
@@ -128,7 +137,23 @@ namespace OpenSim.Framework.Monitoring
|
||||
SortedDictionary<string, Stat> container;
|
||||
if (category.TryGetValue(containerName, out container))
|
||||
{
|
||||
OutputContainerStatsToConsole(con, container);
|
||||
if (String.IsNullOrEmpty(statName))
|
||||
{
|
||||
OutputContainerStatsToConsole(con, container);
|
||||
}
|
||||
else
|
||||
{
|
||||
Stat stat;
|
||||
if (container.TryGetValue(statName, out stat))
|
||||
{
|
||||
OutputStatToConsole(con, stat);
|
||||
}
|
||||
else
|
||||
{
|
||||
con.OutputFormat(
|
||||
"No such stat {0} in {1}.{2}", statName, categoryName, containerName);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -200,6 +225,11 @@ namespace OpenSim.Framework.Monitoring
|
||||
con.Output(report);
|
||||
}
|
||||
|
||||
private static void OutputStatToConsole(ICommandConsole con, Stat stat)
|
||||
{
|
||||
con.Output(stat.ToConsoleString());
|
||||
}
|
||||
|
||||
// Creates an OSDMap of the format:
|
||||
// { categoryName: {
|
||||
// containerName: {
|
||||
|
||||
@@ -82,12 +82,32 @@ namespace OpenSim.Framework.Monitoring
|
||||
/// </summary>
|
||||
public Func<string> AlarmMethod { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Stat structure associated with this thread.
|
||||
/// </summary>
|
||||
public Stat Stat { get; set; }
|
||||
|
||||
public ThreadWatchdogInfo(Thread thread, int timeout)
|
||||
{
|
||||
Thread = thread;
|
||||
Timeout = timeout;
|
||||
FirstTick = Environment.TickCount & Int32.MaxValue;
|
||||
LastTick = FirstTick;
|
||||
|
||||
Stat
|
||||
= new Stat(
|
||||
thread.Name,
|
||||
string.Format("Last update of thread {0}", thread.Name),
|
||||
"",
|
||||
"ms",
|
||||
"server",
|
||||
"thread",
|
||||
StatType.Pull,
|
||||
MeasuresOfInterest.None,
|
||||
stat => stat.Value = Environment.TickCount & Int32.MaxValue - LastTick,
|
||||
StatVerbosity.Debug);
|
||||
|
||||
StatsManager.RegisterStat(Stat);
|
||||
}
|
||||
|
||||
public ThreadWatchdogInfo(ThreadWatchdogInfo previousTwi)
|
||||
@@ -100,6 +120,11 @@ namespace OpenSim.Framework.Monitoring
|
||||
AlarmIfTimeout = previousTwi.AlarmIfTimeout;
|
||||
AlarmMethod = previousTwi.AlarmMethod;
|
||||
}
|
||||
|
||||
public void Cleanup()
|
||||
{
|
||||
StatsManager.DeregisterStat(Stat);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -238,6 +263,7 @@ namespace OpenSim.Framework.Monitoring
|
||||
m_log.DebugFormat(
|
||||
"[WATCHDOG]: Removing thread {0}, ID {1}", twi.Thread.Name, twi.Thread.ManagedThreadId);
|
||||
|
||||
twi.Cleanup();
|
||||
m_threads.Remove(threadID);
|
||||
|
||||
return true;
|
||||
|
||||
@@ -215,7 +215,7 @@ namespace OpenSim.Framework
|
||||
AddinManager.AddinLoadError += on_addinloaderror_;
|
||||
AddinManager.AddinLoaded += on_addinloaded_;
|
||||
|
||||
clear_registry_();
|
||||
clear_registry_(dir);
|
||||
|
||||
suppress_console_output_(true);
|
||||
AddinManager.Initialize(dir);
|
||||
@@ -239,18 +239,19 @@ namespace OpenSim.Framework
|
||||
+ args.Exception.StackTrace);
|
||||
}
|
||||
|
||||
private void clear_registry_()
|
||||
private void clear_registry_(string dir)
|
||||
{
|
||||
// The Mono addin manager (in Mono.Addins.dll version 0.2.0.0)
|
||||
// occasionally seems to corrupt its addin cache
|
||||
// Hence, as a temporary solution we'll remove it before each startup
|
||||
|
||||
try
|
||||
{
|
||||
if (Directory.Exists("addin-db-000"))
|
||||
Directory.Delete("addin-db-000", true);
|
||||
if (Directory.Exists(dir + "/addin-db-000"))
|
||||
Directory.Delete(dir + "/addin-db-000", true);
|
||||
|
||||
if (Directory.Exists("addin-db-001"))
|
||||
Directory.Delete("addin-db-001", true);
|
||||
if (Directory.Exists(dir + "/addin-db-001"))
|
||||
Directory.Delete(dir + "/addin-db-001", true);
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
|
||||
@@ -102,7 +102,6 @@ namespace OpenSim.Framework
|
||||
private static readonly string LogHeader = "[REGION INFO]";
|
||||
|
||||
public bool commFailTF = false;
|
||||
public ConfigurationMember configMember;
|
||||
public string RegionFile = String.Empty;
|
||||
public bool isSandbox = false;
|
||||
public bool Persistent = true;
|
||||
@@ -127,6 +126,7 @@ namespace OpenSim.Framework
|
||||
private int m_physPrimMax = 0;
|
||||
private bool m_clampPrimSize = false;
|
||||
private int m_objectCapacity = 0;
|
||||
private int m_maxPrimsPerUser = -1;
|
||||
private int m_linksetCapacity = 0;
|
||||
private int m_agentCapacity = 0;
|
||||
private string m_regionType = String.Empty;
|
||||
@@ -147,11 +147,32 @@ namespace OpenSim.Framework
|
||||
public uint WorldLocX = 0;
|
||||
public uint WorldLocY = 0;
|
||||
public uint WorldLocZ = 0;
|
||||
|
||||
/// <summary>
|
||||
/// X dimension of the region.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If this is a varregion then the default size set here will be replaced when we load the region config.
|
||||
/// </remarks>
|
||||
public uint RegionSizeX = Constants.RegionSize;
|
||||
|
||||
/// <summary>
|
||||
/// X dimension of the region.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If this is a varregion then the default size set here will be replaced when we load the region config.
|
||||
/// </remarks>
|
||||
public uint RegionSizeY = Constants.RegionSize;
|
||||
|
||||
/// <summary>
|
||||
/// Z dimension of the region.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// XXX: Unknown if this accounts for regions with negative Z.
|
||||
/// </remarks>
|
||||
public uint RegionSizeZ = Constants.RegionHeight;
|
||||
|
||||
private Dictionary<String, String> m_otherSettings = new Dictionary<string, string>();
|
||||
private Dictionary<String, String> m_extraSettings = new Dictionary<string, string>();
|
||||
|
||||
// Apparently, we're applying the same estatesettings regardless of whether it's local or remote.
|
||||
|
||||
@@ -203,7 +224,6 @@ namespace OpenSim.Framework
|
||||
try
|
||||
{
|
||||
// This will throw if it's not legal Nini XML format
|
||||
// and thereby toss it to the legacy loader
|
||||
//
|
||||
IConfigSource xmlsource = new XmlConfigSource(filename);
|
||||
|
||||
@@ -216,21 +236,18 @@ namespace OpenSim.Framework
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
|
||||
configMember =
|
||||
new ConfigurationMember(filename, description, loadConfigurationOptions, handleIncomingConfiguration, !skipConsoleConfig);
|
||||
configMember.performConfigurationRetrieve();
|
||||
RegionFile = filename;
|
||||
}
|
||||
|
||||
// The web loader uses this
|
||||
//
|
||||
public RegionInfo(string description, XmlNode xmlNode, bool skipConsoleConfig, IConfigSource configSource)
|
||||
{
|
||||
// m_configSource = configSource;
|
||||
configMember =
|
||||
new ConfigurationMember(xmlNode, description, loadConfigurationOptions, handleIncomingConfiguration, !skipConsoleConfig);
|
||||
configMember.performConfigurationRetrieve();
|
||||
XmlElement elem = (XmlElement)xmlNode;
|
||||
string name = elem.GetAttribute("Name");
|
||||
string xmlstr = "<Nini>" + xmlNode.OuterXml + "</Nini>";
|
||||
XmlConfigSource source = new XmlConfigSource(XmlReader.Create(new StringReader(xmlstr)));
|
||||
ReadNiniConfig(source, name);
|
||||
|
||||
m_serverURI = string.Empty;
|
||||
}
|
||||
|
||||
@@ -325,6 +342,11 @@ namespace OpenSim.Framework
|
||||
get { return m_objectCapacity; }
|
||||
}
|
||||
|
||||
public int MaxPrimsPerUser
|
||||
{
|
||||
get { return m_maxPrimsPerUser; }
|
||||
}
|
||||
|
||||
public int LinksetCapacity
|
||||
{
|
||||
get { return m_linksetCapacity; }
|
||||
@@ -349,6 +371,8 @@ namespace OpenSim.Framework
|
||||
{
|
||||
get { return m_maptileStaticUUID; }
|
||||
}
|
||||
|
||||
public string MaptileStaticFile { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The port by which http communication occurs with the region (most noticeably, CAPS communication)
|
||||
@@ -498,20 +522,20 @@ namespace OpenSim.Framework
|
||||
m_internalEndPoint = tmpEPE;
|
||||
}
|
||||
|
||||
public string GetOtherSetting(string key)
|
||||
public string GetSetting(string key)
|
||||
{
|
||||
string val;
|
||||
string keylower = key.ToLower();
|
||||
if (m_otherSettings.TryGetValue(keylower, out val))
|
||||
if (m_extraSettings.TryGetValue(keylower, out val))
|
||||
return val;
|
||||
m_log.DebugFormat("[RegionInfo] Could not locate value for parameter {0}", key);
|
||||
return null;
|
||||
}
|
||||
|
||||
public void SetOtherSetting(string key, string value)
|
||||
private void SetExtraSetting(string key, string value)
|
||||
{
|
||||
string keylower = key.ToLower();
|
||||
m_otherSettings[keylower] = value;
|
||||
m_extraSettings[keylower] = value;
|
||||
}
|
||||
|
||||
private void ReadNiniConfig(IConfigSource source, string name)
|
||||
@@ -707,6 +731,9 @@ namespace OpenSim.Framework
|
||||
m_objectCapacity = config.GetInt("MaxPrims", 15000);
|
||||
allKeys.Remove("MaxPrims");
|
||||
|
||||
m_maxPrimsPerUser = config.GetInt("MaxPrimsPerUser", -1);
|
||||
allKeys.Remove("MaxPrimsPerUser");
|
||||
|
||||
m_linksetCapacity = config.GetInt("LinksetPrims", 0);
|
||||
allKeys.Remove("LinksetPrims");
|
||||
|
||||
@@ -716,6 +743,9 @@ namespace OpenSim.Framework
|
||||
{
|
||||
config.Set("MaptileStaticUUID", m_maptileStaticUUID.ToString());
|
||||
}
|
||||
|
||||
MaptileStaticFile = config.GetString("MaptileStaticFile", String.Empty);
|
||||
allKeys.Remove("MaptileStaticFile");
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -729,7 +759,7 @@ namespace OpenSim.Framework
|
||||
|
||||
foreach (String s in allKeys)
|
||||
{
|
||||
SetOtherSetting(s, config.GetString(s));
|
||||
SetExtraSetting(s, config.GetString(s));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -829,6 +859,9 @@ namespace OpenSim.Framework
|
||||
if (m_objectCapacity > 0)
|
||||
config.Set("MaxPrims", m_objectCapacity);
|
||||
|
||||
if (m_maxPrimsPerUser > -1)
|
||||
config.Set("MaxPrimsPerUser", m_maxPrimsPerUser);
|
||||
|
||||
if (m_linksetCapacity > 0)
|
||||
config.Set("LinksetPrims", m_linksetCapacity);
|
||||
|
||||
@@ -843,6 +876,9 @@ namespace OpenSim.Framework
|
||||
|
||||
if (m_maptileStaticUUID != UUID.Zero)
|
||||
config.Set("MaptileStaticUUID", m_maptileStaticUUID.ToString());
|
||||
|
||||
if (MaptileStaticFile != String.Empty)
|
||||
config.Set("MaptileStaticFile", MaptileStaticFile);
|
||||
}
|
||||
|
||||
public bool ignoreIncomingConfiguration(string configuration_key, object configuration_result)
|
||||
@@ -869,249 +905,14 @@ namespace OpenSim.Framework
|
||||
|
||||
return;
|
||||
}
|
||||
else if (filename.ToLower().EndsWith(".xml"))
|
||||
{
|
||||
configMember = new ConfigurationMember(filename, description, loadConfigurationOptionsFromMe,
|
||||
ignoreIncomingConfiguration, false);
|
||||
configMember.performConfigurationRetrieve();
|
||||
RegionFile = filename;
|
||||
}
|
||||
else
|
||||
throw new Exception("Invalid file type for region persistence.");
|
||||
}
|
||||
|
||||
public void loadConfigurationOptionsFromMe()
|
||||
{
|
||||
configMember.addConfigurationOption("sim_UUID", ConfigurationOption.ConfigurationTypes.TYPE_UUID_NULL_FREE,
|
||||
"UUID of Region (Default is recommended, random UUID)",
|
||||
RegionID.ToString(), true);
|
||||
configMember.addConfigurationOption("sim_name", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY,
|
||||
"Region Name", RegionName, true);
|
||||
|
||||
configMember.addConfigurationOption("sim_location_x", ConfigurationOption.ConfigurationTypes.TYPE_UINT32,
|
||||
"Grid Location (X Axis)", RegionLocX.ToString(), true);
|
||||
configMember.addConfigurationOption("sim_location_y", ConfigurationOption.ConfigurationTypes.TYPE_UINT32,
|
||||
"Grid Location (Y Axis)", RegionLocY.ToString(), true);
|
||||
configMember.addConfigurationOption("sim_size_x", ConfigurationOption.ConfigurationTypes.TYPE_UINT32,
|
||||
"Size of region in X dimension", RegionSizeX.ToString(), true);
|
||||
configMember.addConfigurationOption("sim_size_y", ConfigurationOption.ConfigurationTypes.TYPE_UINT32,
|
||||
"Size of region in Y dimension", RegionSizeY.ToString(), true);
|
||||
configMember.addConfigurationOption("sim_size_z", ConfigurationOption.ConfigurationTypes.TYPE_UINT32,
|
||||
"Size of region in Z dimension", RegionSizeZ.ToString(), true);
|
||||
|
||||
//m_configMember.addConfigurationOption("datastore", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, "Filename for local storage", "OpenSim.db", false);
|
||||
configMember.addConfigurationOption("internal_ip_address",
|
||||
ConfigurationOption.ConfigurationTypes.TYPE_IP_ADDRESS,
|
||||
"Internal IP Address for incoming UDP client connections",
|
||||
m_internalEndPoint.Address.ToString(),
|
||||
true);
|
||||
configMember.addConfigurationOption("internal_ip_port", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
|
||||
"Internal IP Port for incoming UDP client connections",
|
||||
m_internalEndPoint.Port.ToString(), true);
|
||||
configMember.addConfigurationOption("allow_alternate_ports",
|
||||
ConfigurationOption.ConfigurationTypes.TYPE_BOOLEAN,
|
||||
"Allow sim to find alternate UDP ports when ports are in use?",
|
||||
m_allow_alternate_ports.ToString(), true);
|
||||
configMember.addConfigurationOption("external_host_name",
|
||||
ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY,
|
||||
"External Host Name", m_externalHostName, true);
|
||||
configMember.addConfigurationOption("lastmap_uuid", ConfigurationOption.ConfigurationTypes.TYPE_UUID,
|
||||
"Last Map UUID", lastMapUUID.ToString(), true);
|
||||
configMember.addConfigurationOption("lastmap_refresh", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY,
|
||||
"Last Map Refresh", Util.UnixTimeSinceEpoch().ToString(), true);
|
||||
|
||||
configMember.addConfigurationOption("nonphysical_prim_min", ConfigurationOption.ConfigurationTypes.TYPE_FLOAT,
|
||||
"Minimum size for nonphysical prims", m_nonphysPrimMin.ToString(), true);
|
||||
|
||||
configMember.addConfigurationOption("nonphysical_prim_max", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
|
||||
"Maximum size for nonphysical prims", m_nonphysPrimMax.ToString(), true);
|
||||
|
||||
configMember.addConfigurationOption("physical_prim_min", ConfigurationOption.ConfigurationTypes.TYPE_FLOAT,
|
||||
"Minimum size for nonphysical prims", m_physPrimMin.ToString(), true);
|
||||
|
||||
configMember.addConfigurationOption("physical_prim_max", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
|
||||
"Maximum size for physical prims", m_physPrimMax.ToString(), true);
|
||||
|
||||
configMember.addConfigurationOption("clamp_prim_size", ConfigurationOption.ConfigurationTypes.TYPE_BOOLEAN,
|
||||
"Clamp prims to max size", m_clampPrimSize.ToString(), true);
|
||||
|
||||
configMember.addConfigurationOption("object_capacity", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
|
||||
"Max objects this sim will hold", m_objectCapacity.ToString(), true);
|
||||
|
||||
configMember.addConfigurationOption("linkset_capacity", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
|
||||
"Max prims an object will hold", m_linksetCapacity.ToString(), true);
|
||||
|
||||
configMember.addConfigurationOption("agent_capacity", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
|
||||
"Max avatars this sim will hold", m_agentCapacity.ToString(), true);
|
||||
|
||||
configMember.addConfigurationOption("scope_id", ConfigurationOption.ConfigurationTypes.TYPE_UUID,
|
||||
"Scope ID for this region", ScopeID.ToString(), true);
|
||||
|
||||
configMember.addConfigurationOption("region_type", ConfigurationOption.ConfigurationTypes.TYPE_STRING,
|
||||
"Free form string describing the type of region", String.Empty, true);
|
||||
|
||||
configMember.addConfigurationOption("region_static_maptile", ConfigurationOption.ConfigurationTypes.TYPE_UUID,
|
||||
"UUID of a texture to use as the map for this region", m_maptileStaticUUID.ToString(), true);
|
||||
}
|
||||
|
||||
public void loadConfigurationOptions()
|
||||
{
|
||||
configMember.addConfigurationOption("sim_UUID", ConfigurationOption.ConfigurationTypes.TYPE_UUID,
|
||||
"UUID of Region (Default is recommended, random UUID)",
|
||||
UUID.Random().ToString(), true);
|
||||
configMember.addConfigurationOption("sim_name", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY,
|
||||
"Region Name", "OpenSim Test", false);
|
||||
|
||||
configMember.addConfigurationOption("sim_location_x", ConfigurationOption.ConfigurationTypes.TYPE_UINT32,
|
||||
"Grid Location (X Axis)", "1000", false);
|
||||
configMember.addConfigurationOption("sim_location_y", ConfigurationOption.ConfigurationTypes.TYPE_UINT32,
|
||||
"Grid Location (Y Axis)", "1000", false);
|
||||
configMember.addConfigurationOption("sim_size_x", ConfigurationOption.ConfigurationTypes.TYPE_UINT32,
|
||||
"Size of region in X dimension", Constants.RegionSize.ToString(), false);
|
||||
configMember.addConfigurationOption("sim_size_y", ConfigurationOption.ConfigurationTypes.TYPE_UINT32,
|
||||
"Size of region in Y dimension", Constants.RegionSize.ToString(), false);
|
||||
configMember.addConfigurationOption("sim_size_z", ConfigurationOption.ConfigurationTypes.TYPE_UINT32,
|
||||
"Size of region in Z dimension", Constants.RegionHeight.ToString(), false);
|
||||
|
||||
//m_configMember.addConfigurationOption("datastore", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, "Filename for local storage", "OpenSim.db", false);
|
||||
configMember.addConfigurationOption("internal_ip_address",
|
||||
ConfigurationOption.ConfigurationTypes.TYPE_IP_ADDRESS,
|
||||
"Internal IP Address for incoming UDP client connections", "0.0.0.0",
|
||||
false);
|
||||
configMember.addConfigurationOption("internal_ip_port", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
|
||||
"Internal IP Port for incoming UDP client connections",
|
||||
ConfigSettings.DefaultRegionHttpPort.ToString(), false);
|
||||
configMember.addConfigurationOption("allow_alternate_ports", ConfigurationOption.ConfigurationTypes.TYPE_BOOLEAN,
|
||||
"Allow sim to find alternate UDP ports when ports are in use?",
|
||||
"false", true);
|
||||
configMember.addConfigurationOption("external_host_name",
|
||||
ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY,
|
||||
"External Host Name", "127.0.0.1", false);
|
||||
configMember.addConfigurationOption("lastmap_uuid", ConfigurationOption.ConfigurationTypes.TYPE_UUID,
|
||||
"Last Map UUID", lastMapUUID.ToString(), true);
|
||||
|
||||
configMember.addConfigurationOption("lastmap_refresh", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY,
|
||||
"Last Map Refresh", Util.UnixTimeSinceEpoch().ToString(), true);
|
||||
|
||||
configMember.addConfigurationOption("nonphysical_prim_max", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
|
||||
"Maximum size for nonphysical prims", "0", true);
|
||||
|
||||
configMember.addConfigurationOption("physical_prim_max", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
|
||||
"Maximum size for physical prims", "0", true);
|
||||
|
||||
configMember.addConfigurationOption("clamp_prim_size", ConfigurationOption.ConfigurationTypes.TYPE_BOOLEAN,
|
||||
"Clamp prims to max size", "false", true);
|
||||
|
||||
configMember.addConfigurationOption("object_capacity", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
|
||||
"Max objects this sim will hold", "15000", true);
|
||||
|
||||
configMember.addConfigurationOption("agent_capacity", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
|
||||
"Max avatars this sim will hold", "100", true);
|
||||
|
||||
configMember.addConfigurationOption("scope_id", ConfigurationOption.ConfigurationTypes.TYPE_UUID,
|
||||
"Scope ID for this region", UUID.Zero.ToString(), true);
|
||||
|
||||
configMember.addConfigurationOption("region_type", ConfigurationOption.ConfigurationTypes.TYPE_STRING,
|
||||
"Region Type", String.Empty, true);
|
||||
|
||||
configMember.addConfigurationOption("region_static_maptile", ConfigurationOption.ConfigurationTypes.TYPE_UUID,
|
||||
"UUID of a texture to use as the map for this region", String.Empty, true);
|
||||
}
|
||||
|
||||
public bool handleIncomingConfiguration(string configuration_key, object configuration_result)
|
||||
{
|
||||
switch (configuration_key)
|
||||
{
|
||||
case "sim_UUID":
|
||||
RegionID = (UUID) configuration_result;
|
||||
originRegionID = (UUID) configuration_result;
|
||||
break;
|
||||
case "sim_name":
|
||||
RegionName = (string) configuration_result;
|
||||
break;
|
||||
case "sim_location_x":
|
||||
RegionLocX = (uint) configuration_result;
|
||||
break;
|
||||
case "sim_location_y":
|
||||
RegionLocY = (uint) configuration_result;
|
||||
break;
|
||||
case "sim_size_x":
|
||||
RegionSizeX = (uint) configuration_result;
|
||||
break;
|
||||
case "sim_size_y":
|
||||
RegionSizeY = (uint) configuration_result;
|
||||
break;
|
||||
case "sim_size_z":
|
||||
RegionSizeZ = (uint) configuration_result;
|
||||
break;
|
||||
case "internal_ip_address":
|
||||
IPAddress address = (IPAddress) configuration_result;
|
||||
m_internalEndPoint = new IPEndPoint(address, 0);
|
||||
break;
|
||||
case "internal_ip_port":
|
||||
m_internalEndPoint.Port = (int) configuration_result;
|
||||
break;
|
||||
case "allow_alternate_ports":
|
||||
m_allow_alternate_ports = (bool) configuration_result;
|
||||
break;
|
||||
case "external_host_name":
|
||||
if ((string) configuration_result != "SYSTEMIP")
|
||||
{
|
||||
m_externalHostName = (string) configuration_result;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_externalHostName = Util.GetLocalHost().ToString();
|
||||
}
|
||||
break;
|
||||
case "lastmap_uuid":
|
||||
lastMapUUID = (UUID)configuration_result;
|
||||
break;
|
||||
case "lastmap_refresh":
|
||||
lastMapRefresh = (string)configuration_result;
|
||||
break;
|
||||
case "nonphysical_prim_max":
|
||||
m_nonphysPrimMax = (int)configuration_result;
|
||||
break;
|
||||
case "physical_prim_max":
|
||||
m_physPrimMax = (int)configuration_result;
|
||||
break;
|
||||
case "clamp_prim_size":
|
||||
m_clampPrimSize = (bool)configuration_result;
|
||||
break;
|
||||
case "object_capacity":
|
||||
m_objectCapacity = (int)configuration_result;
|
||||
break;
|
||||
case "linkset_capacity":
|
||||
m_linksetCapacity = (int)configuration_result;
|
||||
break;
|
||||
case "agent_capacity":
|
||||
m_agentCapacity = (int)configuration_result;
|
||||
break;
|
||||
case "scope_id":
|
||||
ScopeID = (UUID)configuration_result;
|
||||
break;
|
||||
case "region_type":
|
||||
m_regionType = (string)configuration_result;
|
||||
break;
|
||||
case "region_static_maptile":
|
||||
m_maptileStaticUUID = (UUID)configuration_result;
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void SaveLastMapUUID(UUID mapUUID)
|
||||
{
|
||||
lastMapUUID = mapUUID;
|
||||
lastMapRefresh = Util.UnixTimeSinceEpoch().ToString();
|
||||
|
||||
if (configMember == null)
|
||||
return;
|
||||
|
||||
configMember.forceSetConfigurationOption("lastmap_uuid", mapUUID.ToString());
|
||||
configMember.forceSetConfigurationOption("lastmap_refresh", lastMapRefresh);
|
||||
}
|
||||
|
||||
public OSDMap PackRegionInfoData()
|
||||
|
||||
@@ -98,7 +98,7 @@ namespace OpenSim.Framework.RegionLoader.Web
|
||||
xmlSource.Length);
|
||||
XmlDocument xmlDoc = new XmlDocument();
|
||||
xmlDoc.LoadXml(xmlSource);
|
||||
if (xmlDoc.FirstChild.Name == "Regions")
|
||||
if (xmlDoc.FirstChild.Name == "Nini")
|
||||
{
|
||||
regionCount = xmlDoc.FirstChild.ChildNodes.Count;
|
||||
|
||||
@@ -144,4 +144,4 @@ namespace OpenSim.Framework.RegionLoader.Web
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
@@ -161,7 +161,7 @@ namespace OpenSim.Framework.Serialization.External
|
||||
if (!hasCreatorData && creator != null)
|
||||
{
|
||||
XmlElement creatorData = doc.CreateElement("CreatorData");
|
||||
creatorData.InnerText = homeURL + ";" + creator.FirstName + " " + creator.LastName;
|
||||
creatorData.InnerText = CalcCreatorData(homeURL, creator.FirstName + " " + creator.LastName);
|
||||
sop.AppendChild(creatorData);
|
||||
}
|
||||
}
|
||||
@@ -172,5 +172,15 @@ namespace OpenSim.Framework.Serialization.External
|
||||
return wr.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public static string CalcCreatorData(string homeURL, string name)
|
||||
{
|
||||
return homeURL + ";" + name;
|
||||
}
|
||||
|
||||
internal static string CalcCreatorData(string homeURL, UUID uuid, string name)
|
||||
{
|
||||
return homeURL + "/" + uuid + ";" + name;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -213,8 +213,13 @@ namespace OpenSim.Framework.Serialization.External
|
||||
xtw.WriteElementString("ClaimDate", Convert.ToString(landData.ClaimDate));
|
||||
xtw.WriteElementString("ClaimPrice", Convert.ToString(landData.ClaimPrice));
|
||||
xtw.WriteElementString("GlobalID", landData.GlobalID.ToString());
|
||||
xtw.WriteElementString("GroupID", landData.GroupID.ToString());
|
||||
xtw.WriteElementString("IsGroupOwned", Convert.ToString(landData.IsGroupOwned));
|
||||
|
||||
UUID groupID = options.ContainsKey("wipe-owners") ? UUID.Zero : landData.GroupID;
|
||||
xtw.WriteElementString("GroupID", groupID.ToString());
|
||||
|
||||
bool isGroupOwned = options.ContainsKey("wipe-owners") ? false : landData.IsGroupOwned;
|
||||
xtw.WriteElementString("IsGroupOwned", Convert.ToString(isGroupOwned));
|
||||
|
||||
xtw.WriteElementString("Bitmap", Convert.ToBase64String(landData.Bitmap));
|
||||
xtw.WriteElementString("Description", landData.Description);
|
||||
xtw.WriteElementString("Flags", Convert.ToString((uint)landData.Flags));
|
||||
@@ -227,13 +232,8 @@ namespace OpenSim.Framework.Serialization.External
|
||||
xtw.WriteElementString("MediaURL", landData.MediaURL);
|
||||
xtw.WriteElementString("MusicURL", landData.MusicURL);
|
||||
|
||||
UUID ownerIdToWrite;
|
||||
if (options != null && options.ContainsKey("wipe-owners"))
|
||||
ownerIdToWrite = UUID.Zero;
|
||||
else
|
||||
ownerIdToWrite = landData.OwnerID;
|
||||
|
||||
xtw.WriteElementString("OwnerID", ownerIdToWrite.ToString());
|
||||
UUID ownerID = options.ContainsKey("wipe-owners") ? UUID.Zero : landData.OwnerID;
|
||||
xtw.WriteElementString("OwnerID", ownerID.ToString());
|
||||
|
||||
xtw.WriteStartElement("ParcelAccessList");
|
||||
foreach (LandAccessEntry pal in landData.ParcelAccessList)
|
||||
|
||||
@@ -286,7 +286,8 @@ namespace OpenSim.Framework.Serialization.External
|
||||
UserAccount account = userAccountService.GetUserAccount(UUID.Zero, inventoryItem.CreatorIdAsUuid);
|
||||
if (account != null)
|
||||
{
|
||||
writer.WriteElementString("CreatorData", (string)options["home"] + "/" + inventoryItem.CreatorIdAsUuid + ";" + account.FirstName + " " + account.LastName);
|
||||
string creatorData = ExternalRepresentationUtils.CalcCreatorData((string)options["home"], inventoryItem.CreatorIdAsUuid, account.FirstName + " " + account.LastName);
|
||||
writer.WriteElementString("CreatorData", creatorData);
|
||||
}
|
||||
writer.WriteElementString("CreatorID", inventoryItem.CreatorId);
|
||||
}
|
||||
|
||||
@@ -121,7 +121,8 @@ namespace OpenSim.Framework.Serialization.Tests
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
LandData ld = LandDataSerializer.Deserialize(LandDataSerializer.Serialize(this.land, null));
|
||||
Dictionary<string, object> options = new Dictionary<string, object>();
|
||||
LandData ld = LandDataSerializer.Deserialize(LandDataSerializer.Serialize(this.land, options));
|
||||
Assert.That(ld, Is.Not.Null, "Deserialize(string) returned null");
|
||||
// Assert.That(ld.AABBMax, Is.EqualTo(land.AABBMax));
|
||||
// Assert.That(ld.AABBMin, Is.EqualTo(land.AABBMin));
|
||||
|
||||
@@ -45,6 +45,7 @@ using OpenSim.Framework.Monitoring;
|
||||
using OpenSim.Framework.Servers;
|
||||
using OpenSim.Framework.Servers.HttpServer;
|
||||
using Timer=System.Timers.Timer;
|
||||
using Nini.Config;
|
||||
|
||||
namespace OpenSim.Framework.Servers
|
||||
{
|
||||
@@ -55,10 +56,16 @@ namespace OpenSim.Framework.Servers
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
/// <summary>
|
||||
/// Used by tests to suppress Environment.Exit(0) so that post-run operations are possible.
|
||||
/// </summary>
|
||||
public bool SuppressExit { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// This will control a periodic log printout of the current 'show stats' (if they are active) for this
|
||||
/// server.
|
||||
/// </summary>
|
||||
private int m_periodDiagnosticTimerMS = 60 * 60 * 1000;
|
||||
private Timer m_periodicDiagnosticsTimer = new Timer(60 * 60 * 1000);
|
||||
|
||||
/// <summary>
|
||||
@@ -77,8 +84,6 @@ namespace OpenSim.Framework.Servers
|
||||
// Random uuid for private data
|
||||
m_osSecret = UUID.Random().ToString();
|
||||
|
||||
m_periodicDiagnosticsTimer.Elapsed += new ElapsedEventHandler(LogDiagnostics);
|
||||
m_periodicDiagnosticsTimer.Enabled = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -89,6 +94,16 @@ namespace OpenSim.Framework.Servers
|
||||
StatsManager.SimExtraStats = new SimExtraStatsCollector();
|
||||
RegisterCommonCommands();
|
||||
RegisterCommonComponents(Config);
|
||||
|
||||
IConfig startupConfig = Config.Configs["Startup"];
|
||||
int logShowStatsSeconds = startupConfig.GetInt("LogShowStatsSeconds", m_periodDiagnosticTimerMS / 1000);
|
||||
m_periodDiagnosticTimerMS = logShowStatsSeconds * 1000;
|
||||
m_periodicDiagnosticsTimer.Elapsed += new ElapsedEventHandler(LogDiagnostics);
|
||||
if (m_periodDiagnosticTimerMS != 0)
|
||||
{
|
||||
m_periodicDiagnosticsTimer.Interval = m_periodDiagnosticTimerMS;
|
||||
m_periodicDiagnosticsTimer.Enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void ShutdownSpecific()
|
||||
@@ -99,7 +114,8 @@ namespace OpenSim.Framework.Servers
|
||||
|
||||
base.ShutdownSpecific();
|
||||
|
||||
Environment.Exit(0);
|
||||
if (!SuppressExit)
|
||||
Environment.Exit(0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -46,6 +46,7 @@ using CoolHTTPListener = HttpServer.HttpListener;
|
||||
using HttpListener=System.Net.HttpListener;
|
||||
using LogPrio=HttpServer.LogPrio;
|
||||
using OpenSim.Framework.Monitoring;
|
||||
using System.IO.Compression;
|
||||
|
||||
namespace OpenSim.Framework.Servers.HttpServer
|
||||
{
|
||||
@@ -113,7 +114,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
|
||||
protected IPAddress m_listenIPAddress = IPAddress.Any;
|
||||
|
||||
private PollServiceRequestManager m_PollServiceManager;
|
||||
public PollServiceRequestManager PollServiceRequestManager { get; private set; }
|
||||
|
||||
public uint SSLPort
|
||||
{
|
||||
@@ -374,7 +375,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
return true;
|
||||
}
|
||||
|
||||
private void OnRequest(object source, RequestEventArgs args)
|
||||
public void OnRequest(object source, RequestEventArgs args)
|
||||
{
|
||||
RequestNumber++;
|
||||
|
||||
@@ -429,7 +430,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
psEvArgs.Request(psreq.RequestID, keysvals);
|
||||
}
|
||||
|
||||
m_PollServiceManager.Enqueue(psreq);
|
||||
PollServiceRequestManager.Enqueue(psreq);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -491,8 +492,8 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
try
|
||||
{
|
||||
byte[] buffer500 = SendHTML500(response);
|
||||
response.Body.Write(buffer500,0,buffer500.Length);
|
||||
response.Body.Close();
|
||||
response.OutputStream.Write(buffer500, 0, buffer500.Length);
|
||||
response.Send();
|
||||
}
|
||||
catch
|
||||
{
|
||||
@@ -690,6 +691,23 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
|
||||
if (buffer != null)
|
||||
{
|
||||
if (WebUtil.DebugLevel >= 5)
|
||||
{
|
||||
string output = System.Text.Encoding.UTF8.GetString(buffer);
|
||||
|
||||
if (WebUtil.DebugLevel >= 6)
|
||||
{
|
||||
// Always truncate binary blobs. We don't have a ContentType, so detect them using the request name.
|
||||
if ((requestHandler != null && requestHandler.Name == "GetMesh"))
|
||||
{
|
||||
if (output.Length > WebUtil.MaxRequestDiagLength)
|
||||
output = output.Substring(0, WebUtil.MaxRequestDiagLength) + "...";
|
||||
}
|
||||
}
|
||||
|
||||
WebUtil.LogResponseDetail(RequestNumber, output);
|
||||
}
|
||||
|
||||
if (!response.SendChunked && response.ContentLength64 <= 0)
|
||||
response.ContentLength64 = buffer.LongLength;
|
||||
|
||||
@@ -720,16 +738,16 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
m_log.Error(String.Format("[BASE HTTP SERVER]: HandleRequest() threw {0} ", e.StackTrace), e);
|
||||
m_log.Error("[BASE HTTP SERVER]: HandleRequest() threw exception ", e);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Error(String.Format("[BASE HTTP SERVER]: HandleRequest() threw {0} ", e.StackTrace), e);
|
||||
m_log.Error("[BASE HTTP SERVER]: HandleRequest() threw exception ", e);
|
||||
try
|
||||
{
|
||||
byte[] buffer500 = SendHTML500(response);
|
||||
response.Body.Write(buffer500, 0, buffer500.Length);
|
||||
response.Body.Close();
|
||||
response.OutputStream.Write(buffer500, 0, buffer500.Length);
|
||||
response.Send();
|
||||
}
|
||||
catch
|
||||
{
|
||||
@@ -743,7 +761,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
if (tickdiff > 3000 && requestHandler != null && requestHandler.Name != "GetTexture")
|
||||
{
|
||||
m_log.InfoFormat(
|
||||
"[BASE HTTP SERVER]: Slow handling of {0} {1} {2} {3} {4} from {5} took {6}ms",
|
||||
"[LOGHTTP] Slow handling of {0} {1} {2} {3} {4} from {5} took {6}ms",
|
||||
RequestNumber,
|
||||
requestMethod,
|
||||
uriString,
|
||||
@@ -755,7 +773,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
else if (DebugLevel >= 4)
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"[BASE HTTP SERVER]: HTTP IN {0} :{1} took {2}ms",
|
||||
"[LOGHTTP] HTTP IN {0} :{1} took {2}ms",
|
||||
RequestNumber,
|
||||
Port,
|
||||
tickdiff);
|
||||
@@ -766,7 +784,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
private void LogIncomingToStreamHandler(OSHttpRequest request, IRequestHandler requestHandler)
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"[BASE HTTP SERVER]: HTTP IN {0} :{1} stream handler {2} {3} {4} {5} from {6}",
|
||||
"[LOGHTTP] HTTP IN {0} :{1} stream handler {2} {3} {4} {5} from {6}",
|
||||
RequestNumber,
|
||||
Port,
|
||||
request.HttpMethod,
|
||||
@@ -782,7 +800,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
private void LogIncomingToContentTypeHandler(OSHttpRequest request)
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"[BASE HTTP SERVER]: HTTP IN {0} :{1} {2} content type handler {3} {4} from {5}",
|
||||
"[LOGHTTP] HTTP IN {0} :{1} {2} content type handler {3} {4} from {5}",
|
||||
RequestNumber,
|
||||
Port,
|
||||
string.IsNullOrEmpty(request.ContentType) ? "not set" : request.ContentType,
|
||||
@@ -797,7 +815,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
private void LogIncomingToXmlRpcHandler(OSHttpRequest request)
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"[BASE HTTP SERVER]: HTTP IN {0} :{1} assumed generic XMLRPC request {2} {3} from {4}",
|
||||
"[LOGHTTP] HTTP IN {0} :{1} assumed generic XMLRPC request {2} {3} from {4}",
|
||||
RequestNumber,
|
||||
Port,
|
||||
request.HttpMethod,
|
||||
@@ -810,29 +828,37 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
|
||||
private void LogIncomingInDetail(OSHttpRequest request)
|
||||
{
|
||||
using (StreamReader reader = new StreamReader(Util.Copy(request.InputStream), Encoding.UTF8))
|
||||
if (request.ContentType == "application/octet-stream")
|
||||
return; // never log these; they're just binary data
|
||||
|
||||
Stream inputStream = Util.Copy(request.InputStream);
|
||||
|
||||
if ((request.Headers["Content-Encoding"] == "gzip") || (request.Headers["X-Content-Encoding"] == "gzip"))
|
||||
inputStream = new GZipStream(inputStream, System.IO.Compression.CompressionMode.Decompress);
|
||||
|
||||
using (StreamReader reader = new StreamReader(inputStream, Encoding.UTF8))
|
||||
{
|
||||
string output;
|
||||
|
||||
if (DebugLevel == 5)
|
||||
{
|
||||
const int sampleLength = 80;
|
||||
char[] sampleChars = new char[sampleLength + 3];
|
||||
reader.Read(sampleChars, 0, sampleLength);
|
||||
sampleChars[80] = '.';
|
||||
sampleChars[81] = '.';
|
||||
sampleChars[82] = '.';
|
||||
output = new string(sampleChars);
|
||||
char[] chars = new char[WebUtil.MaxRequestDiagLength + 1]; // +1 so we know to add "..." only if needed
|
||||
int len = reader.Read(chars, 0, WebUtil.MaxRequestDiagLength + 1);
|
||||
output = new string(chars, 0, Math.Min(len, WebUtil.MaxRequestDiagLength));
|
||||
if (len > WebUtil.MaxRequestDiagLength)
|
||||
output += "...";
|
||||
}
|
||||
else
|
||||
{
|
||||
output = reader.ReadToEnd();
|
||||
}
|
||||
|
||||
m_log.DebugFormat("[BASE HTTP SERVER]: {0}", output.Replace("\n", @"\n"));
|
||||
m_log.DebugFormat("[LOGHTTP] {0}", Util.BinaryToASCII(output));
|
||||
}
|
||||
}
|
||||
|
||||
private readonly string HANDLER_SEPARATORS = "/?&#-";
|
||||
|
||||
private bool TryGetStreamHandler(string handlerKey, out IRequestHandler streamHandler)
|
||||
{
|
||||
string bestMatch = null;
|
||||
@@ -841,7 +867,8 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
{
|
||||
foreach (string pattern in m_streamHandlers.Keys)
|
||||
{
|
||||
if (handlerKey.StartsWith(pattern))
|
||||
if ((handlerKey == pattern)
|
||||
|| (handlerKey.StartsWith(pattern) && (HANDLER_SEPARATORS.IndexOf(handlerKey[pattern.Length]) >= 0)))
|
||||
{
|
||||
if (String.IsNullOrEmpty(bestMatch) || pattern.Length > bestMatch.Length)
|
||||
{
|
||||
@@ -871,7 +898,8 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
{
|
||||
foreach (string pattern in m_pollHandlers.Keys)
|
||||
{
|
||||
if (handlerKey.StartsWith(pattern))
|
||||
if ((handlerKey == pattern)
|
||||
|| (handlerKey.StartsWith(pattern) && (HANDLER_SEPARATORS.IndexOf(handlerKey[pattern.Length]) >= 0)))
|
||||
{
|
||||
if (String.IsNullOrEmpty(bestMatch) || pattern.Length > bestMatch.Length)
|
||||
{
|
||||
@@ -903,7 +931,8 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
{
|
||||
foreach (string pattern in m_HTTPHandlers.Keys)
|
||||
{
|
||||
if (handlerKey.StartsWith(pattern))
|
||||
if ((handlerKey == pattern)
|
||||
|| (handlerKey.StartsWith(pattern) && (HANDLER_SEPARATORS.IndexOf(handlerKey[pattern.Length]) >= 0)))
|
||||
{
|
||||
if (String.IsNullOrEmpty(bestMatch) || pattern.Length > bestMatch.Length)
|
||||
{
|
||||
@@ -954,6 +983,9 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
{
|
||||
Stream requestStream = request.InputStream;
|
||||
|
||||
if ((request.Headers["Content-Encoding"] == "gzip") || (request.Headers["X-Content-Encoding"] == "gzip"))
|
||||
requestStream = new GZipStream(requestStream, System.IO.Compression.CompressionMode.Decompress);
|
||||
|
||||
Encoding encoding = Encoding.UTF8;
|
||||
StreamReader reader = new StreamReader(requestStream, encoding);
|
||||
|
||||
@@ -1781,10 +1813,17 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
|
||||
public void Start()
|
||||
{
|
||||
StartHTTP();
|
||||
Start(true);
|
||||
}
|
||||
|
||||
private void StartHTTP()
|
||||
/// <summary>
|
||||
/// Start the http server
|
||||
/// </summary>
|
||||
/// <param name='processPollRequestsAsync'>
|
||||
/// If true then poll responses are performed asynchronsly.
|
||||
/// Option exists to allow regression tests to perform processing synchronously.
|
||||
/// </param>
|
||||
public void Start(bool performPollResponsesAsync)
|
||||
{
|
||||
m_log.InfoFormat(
|
||||
"[BASE HTTP SERVER]: Starting {0} server on port {1}", UseSSL ? "HTTPS" : "HTTP", Port);
|
||||
@@ -1822,8 +1861,9 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
m_httpListener2.Start(64);
|
||||
|
||||
// Long Poll Service Manager with 3 worker threads a 25 second timeout for no events
|
||||
m_PollServiceManager = new PollServiceRequestManager(this, 3, 25000);
|
||||
m_PollServiceManager.Start();
|
||||
PollServiceRequestManager = new PollServiceRequestManager(this, performPollResponsesAsync, 3, 25000);
|
||||
PollServiceRequestManager.Start();
|
||||
|
||||
HTTPDRunning = true;
|
||||
|
||||
//HttpListenerContext context;
|
||||
@@ -1892,7 +1932,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
|
||||
try
|
||||
{
|
||||
m_PollServiceManager.Stop();
|
||||
PollServiceRequestManager.Stop();
|
||||
|
||||
m_httpListener2.ExceptionThrown -= httpServerException;
|
||||
//m_httpListener2.DisconnectHandler = null;
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
*/
|
||||
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using OpenSim.Framework.ServiceAuth;
|
||||
|
||||
namespace OpenSim.Framework.Servers.HttpServer
|
||||
{
|
||||
@@ -37,15 +39,30 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
/// </remarks>
|
||||
public abstract class BaseStreamHandler : BaseRequestHandler, IStreamedRequestHandler
|
||||
{
|
||||
protected BaseStreamHandler(string httpMethod, string path) : this(httpMethod, path, null, null) {}
|
||||
protected IServiceAuth m_Auth;
|
||||
|
||||
protected BaseStreamHandler(string httpMethod, string path) : this(httpMethod, path, null, null) { }
|
||||
|
||||
protected BaseStreamHandler(string httpMethod, string path, string name, string description)
|
||||
: base(httpMethod, path, name, description) {}
|
||||
|
||||
protected BaseStreamHandler(string httpMethod, string path, IServiceAuth auth)
|
||||
: base(httpMethod, path, null, null)
|
||||
{
|
||||
m_Auth = auth;
|
||||
}
|
||||
|
||||
public virtual byte[] Handle(
|
||||
string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
||||
{
|
||||
RequestsReceived++;
|
||||
if (m_Auth != null && !m_Auth.Authenticate(httpRequest.Headers, httpResponse.AddHeader))
|
||||
{
|
||||
|
||||
httpResponse.StatusCode = (int)HttpStatusCode.Unauthorized;
|
||||
httpResponse.ContentType = "text/plain";
|
||||
return new byte[0];
|
||||
}
|
||||
|
||||
byte[] result = ProcessRequest(path, request, httpRequest, httpResponse);
|
||||
|
||||
|
||||
190
OpenSim/Framework/Servers/HttpServer/JsonRpcRequestManager.cs
Normal file
190
OpenSim/Framework/Servers/HttpServer/JsonRpcRequestManager.cs
Normal file
@@ -0,0 +1,190 @@
|
||||
/*
|
||||
* 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.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
using OpenMetaverse.StructuredData;
|
||||
using OpenMetaverse;
|
||||
using log4net;
|
||||
|
||||
namespace OpenSim.Framework.Servers.HttpServer
|
||||
{
|
||||
/// <summary>
|
||||
/// Json rpc request manager.
|
||||
/// </summary>
|
||||
public class JsonRpcRequestManager
|
||||
{
|
||||
static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
public JsonRpcRequestManager()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends json-rpc request with a serializable type.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// OSD Map.
|
||||
/// </returns>
|
||||
/// <param name='parameters'>
|
||||
/// Serializable type .
|
||||
/// </param>
|
||||
/// <param name='method'>
|
||||
/// Json-rpc method to call.
|
||||
/// </param>
|
||||
/// <param name='uri'>
|
||||
/// URI of json-rpc service.
|
||||
/// </param>
|
||||
/// <param name='jsonId'>
|
||||
/// Id for our call.
|
||||
/// </param>
|
||||
public bool JsonRpcRequest(ref object parameters, string method, string uri, string jsonId)
|
||||
{
|
||||
if (jsonId == null)
|
||||
throw new ArgumentNullException("jsonId");
|
||||
if (uri == null)
|
||||
throw new ArgumentNullException("uri");
|
||||
if (method == null)
|
||||
throw new ArgumentNullException("method");
|
||||
if (parameters == null)
|
||||
throw new ArgumentNullException("parameters");
|
||||
|
||||
OSDMap request = new OSDMap();
|
||||
request.Add("jsonrpc", OSD.FromString("2.0"));
|
||||
request.Add("id", OSD.FromString(jsonId));
|
||||
request.Add("method", OSD.FromString(method));
|
||||
request.Add("params", OSD.SerializeMembers(parameters));
|
||||
|
||||
OSDMap response;
|
||||
try
|
||||
{
|
||||
response = WebUtil.PostToService(uri, request, 10000, true);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Debug(string.Format("JsonRpc request '{0}' to {1} failed", method, uri), e);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!response.ContainsKey("_Result"))
|
||||
{
|
||||
m_log.DebugFormat("JsonRpc request '{0}' to {1} returned an invalid response: {2}",
|
||||
method, uri, OSDParser.SerializeJsonString(response));
|
||||
return false;
|
||||
}
|
||||
response = (OSDMap)response["_Result"];
|
||||
|
||||
OSD data;
|
||||
|
||||
if (response.ContainsKey("error"))
|
||||
{
|
||||
data = response["error"];
|
||||
m_log.DebugFormat("JsonRpc request '{0}' to {1} returned an error: {2}",
|
||||
method, uri, OSDParser.SerializeJsonString(data));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!response.ContainsKey("result"))
|
||||
{
|
||||
m_log.DebugFormat("JsonRpc request '{0}' to {1} returned an invalid response: {2}",
|
||||
method, uri, OSDParser.SerializeJsonString(response));
|
||||
return false;
|
||||
}
|
||||
|
||||
data = response["result"];
|
||||
OSD.DeserializeMembers(ref parameters, (OSDMap)data);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends json-rpc request with OSD parameter.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The rpc request.
|
||||
/// </returns>
|
||||
/// <param name='data'>
|
||||
/// data - incoming as parameters, outgoing as result/error
|
||||
/// </param>
|
||||
/// <param name='method'>
|
||||
/// Json-rpc method to call.
|
||||
/// </param>
|
||||
/// <param name='uri'>
|
||||
/// URI of json-rpc service.
|
||||
/// </param>
|
||||
/// <param name='jsonId'>
|
||||
/// If set to <c>true</c> json identifier.
|
||||
/// </param>
|
||||
public bool JsonRpcRequest(ref OSD data, string method, string uri, string jsonId)
|
||||
{
|
||||
if (string.IsNullOrEmpty(jsonId))
|
||||
jsonId = UUID.Random().ToString();
|
||||
|
||||
OSDMap request = new OSDMap();
|
||||
request.Add("jsonrpc", OSD.FromString("2.0"));
|
||||
request.Add("id", OSD.FromString(jsonId));
|
||||
request.Add("method", OSD.FromString(method));
|
||||
request.Add("params", data);
|
||||
|
||||
OSDMap response;
|
||||
try
|
||||
{
|
||||
response = WebUtil.PostToService(uri, request, 10000, true);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Debug(string.Format("JsonRpc request '{0}' to {1} failed", method, uri), e);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!response.ContainsKey("_Result"))
|
||||
{
|
||||
m_log.DebugFormat("JsonRpc request '{0}' to {1} returned an invalid response: {2}",
|
||||
method, uri, OSDParser.SerializeJsonString(response));
|
||||
return false;
|
||||
}
|
||||
response = (OSDMap)response["_Result"];
|
||||
|
||||
if (response.ContainsKey("error"))
|
||||
{
|
||||
data = response["error"];
|
||||
m_log.DebugFormat("JsonRpc request '{0}' to {1} returned an error: {2}",
|
||||
method, uri, OSDParser.SerializeJsonString(data));
|
||||
return false;
|
||||
}
|
||||
|
||||
data = response;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -182,11 +182,22 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
_context = context;
|
||||
|
||||
if (null != req.Headers["content-encoding"])
|
||||
_contentEncoding = Encoding.GetEncoding(_request.Headers["content-encoding"]);
|
||||
{
|
||||
try
|
||||
{
|
||||
_contentEncoding = Encoding.GetEncoding(_request.Headers["content-encoding"]);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
if (null != req.Headers["content-type"])
|
||||
_contentType = _request.Headers["content-type"];
|
||||
if (null != req.Headers["user-agent"])
|
||||
_userAgent = req.Headers["user-agent"];
|
||||
|
||||
if (null != req.Headers["remote_addr"])
|
||||
{
|
||||
try
|
||||
|
||||
@@ -44,6 +44,25 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
/// <summary>
|
||||
/// Is the poll service request manager running?
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Can be running either synchronously or asynchronously
|
||||
/// </remarks>
|
||||
public bool IsRunning { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Is the poll service performing responses asynchronously (with its own threads) or synchronously (via
|
||||
/// external calls)?
|
||||
/// </summary>
|
||||
public bool PerformResponsesAsync { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Number of responses actually processed and sent to viewer (or aborted due to error).
|
||||
/// </summary>
|
||||
public int ResponsesProcessed { get; private set; }
|
||||
|
||||
private readonly BaseHttpServer m_server;
|
||||
|
||||
private BlockingQueue<PollServiceHttpRequest> m_requests = new BlockingQueue<PollServiceHttpRequest>();
|
||||
@@ -52,48 +71,79 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
private uint m_WorkerThreadCount = 0;
|
||||
private Thread[] m_workerThreads;
|
||||
|
||||
private bool m_running = true;
|
||||
|
||||
private SmartThreadPool m_threadPool = new SmartThreadPool(20000, 12, 2);
|
||||
|
||||
// private int m_timeout = 1000; // increase timeout 250; now use the event one
|
||||
|
||||
public PollServiceRequestManager(BaseHttpServer pSrv, uint pWorkerThreadCount, int pTimeout)
|
||||
public PollServiceRequestManager(
|
||||
BaseHttpServer pSrv, bool performResponsesAsync, uint pWorkerThreadCount, int pTimeout)
|
||||
{
|
||||
m_server = pSrv;
|
||||
PerformResponsesAsync = performResponsesAsync;
|
||||
m_WorkerThreadCount = pWorkerThreadCount;
|
||||
m_workerThreads = new Thread[m_WorkerThreadCount];
|
||||
|
||||
StatsManager.RegisterStat(
|
||||
new Stat(
|
||||
"QueuedPollResponses",
|
||||
"Number of poll responses queued for processing.",
|
||||
"",
|
||||
"",
|
||||
"httpserver",
|
||||
m_server.Port.ToString(),
|
||||
StatType.Pull,
|
||||
MeasuresOfInterest.AverageChangeOverTime,
|
||||
stat => stat.Value = m_requests.Count(),
|
||||
StatVerbosity.Debug));
|
||||
|
||||
StatsManager.RegisterStat(
|
||||
new Stat(
|
||||
"ProcessedPollResponses",
|
||||
"Number of poll responses processed.",
|
||||
"",
|
||||
"",
|
||||
"httpserver",
|
||||
m_server.Port.ToString(),
|
||||
StatType.Pull,
|
||||
MeasuresOfInterest.AverageChangeOverTime,
|
||||
stat => stat.Value = ResponsesProcessed,
|
||||
StatVerbosity.Debug));
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
//startup worker threads
|
||||
for (uint i = 0; i < m_WorkerThreadCount; i++)
|
||||
{
|
||||
m_workerThreads[i]
|
||||
= Watchdog.StartThread(
|
||||
PoolWorkerJob,
|
||||
string.Format("PollServiceWorkerThread{0}:{1}", i, m_server.Port),
|
||||
ThreadPriority.Normal,
|
||||
false,
|
||||
false,
|
||||
null,
|
||||
int.MaxValue);
|
||||
}
|
||||
IsRunning = true;
|
||||
|
||||
Watchdog.StartThread(
|
||||
this.CheckLongPollThreads,
|
||||
string.Format("LongPollServiceWatcherThread:{0}", m_server.Port),
|
||||
ThreadPriority.Normal,
|
||||
false,
|
||||
true,
|
||||
null,
|
||||
1000 * 60 * 10);
|
||||
if (PerformResponsesAsync)
|
||||
{
|
||||
//startup worker threads
|
||||
for (uint i = 0; i < m_WorkerThreadCount; i++)
|
||||
{
|
||||
m_workerThreads[i]
|
||||
= Watchdog.StartThread(
|
||||
PoolWorkerJob,
|
||||
string.Format("PollServiceWorkerThread{0}:{1}", i, m_server.Port),
|
||||
ThreadPriority.Normal,
|
||||
false,
|
||||
false,
|
||||
null,
|
||||
int.MaxValue);
|
||||
}
|
||||
|
||||
Watchdog.StartThread(
|
||||
this.CheckLongPollThreads,
|
||||
string.Format("LongPollServiceWatcherThread:{0}", m_server.Port),
|
||||
ThreadPriority.Normal,
|
||||
false,
|
||||
true,
|
||||
null,
|
||||
1000 * 60 * 10);
|
||||
}
|
||||
}
|
||||
|
||||
private void ReQueueEvent(PollServiceHttpRequest req)
|
||||
{
|
||||
if (m_running)
|
||||
if (IsRunning)
|
||||
{
|
||||
// delay the enqueueing for 100ms. There's no need to have the event
|
||||
// actively on the queue
|
||||
@@ -109,7 +159,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
|
||||
public void Enqueue(PollServiceHttpRequest req)
|
||||
{
|
||||
if (m_running)
|
||||
if (IsRunning)
|
||||
{
|
||||
if (req.PollServiceArgs.Type == PollServiceEventArgs.EventType.LongPoll)
|
||||
{
|
||||
@@ -129,7 +179,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
// All other types of tasks (Inventory handlers, http-in, etc) don't have the long-poll nature,
|
||||
// so if they aren't ready to be served by a worker thread (no events), they are placed
|
||||
// directly back in the "ready-to-serve" queue by the worker thread.
|
||||
while (m_running)
|
||||
while (IsRunning)
|
||||
{
|
||||
Thread.Sleep(500);
|
||||
Watchdog.UpdateThread();
|
||||
@@ -137,7 +187,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
// List<PollServiceHttpRequest> not_ready = new List<PollServiceHttpRequest>();
|
||||
lock (m_longPollRequests)
|
||||
{
|
||||
if (m_longPollRequests.Count > 0 && m_running)
|
||||
if (m_longPollRequests.Count > 0 && IsRunning)
|
||||
{
|
||||
List<PollServiceHttpRequest> ready = m_longPollRequests.FindAll(req =>
|
||||
(req.PollServiceArgs.HasEvents(req.RequestID, req.PollServiceArgs.Id) || // there are events in this EQ
|
||||
@@ -158,7 +208,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
m_running = false;
|
||||
IsRunning = false;
|
||||
// m_timeout = -10000; // cause all to expire
|
||||
Thread.Sleep(1000); // let the world move
|
||||
|
||||
@@ -169,7 +219,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
|
||||
lock (m_longPollRequests)
|
||||
{
|
||||
if (m_longPollRequests.Count > 0 && m_running)
|
||||
if (m_longPollRequests.Count > 0 && IsRunning)
|
||||
m_longPollRequests.ForEach(req => m_requests.Enqueue(req));
|
||||
}
|
||||
|
||||
@@ -178,6 +228,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
try
|
||||
{
|
||||
wreq = m_requests.Dequeue(0);
|
||||
ResponsesProcessed++;
|
||||
wreq.DoHTTPGruntWork(
|
||||
m_server, wreq.PollServiceArgs.NoEvents(wreq.RequestID, wreq.PollServiceArgs.Id));
|
||||
}
|
||||
@@ -194,69 +245,86 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
|
||||
private void PoolWorkerJob()
|
||||
{
|
||||
while (m_running)
|
||||
while (IsRunning)
|
||||
{
|
||||
PollServiceHttpRequest req = m_requests.Dequeue(5000);
|
||||
//m_log.WarnFormat("[YYY]: Dequeued {0}", (req == null ? "null" : req.PollServiceArgs.Type.ToString()));
|
||||
|
||||
Watchdog.UpdateThread();
|
||||
if (req != null)
|
||||
WaitPerformResponse();
|
||||
}
|
||||
}
|
||||
|
||||
public void WaitPerformResponse()
|
||||
{
|
||||
PollServiceHttpRequest req = m_requests.Dequeue(5000);
|
||||
// m_log.DebugFormat("[YYY]: Dequeued {0}", (req == null ? "null" : req.PollServiceArgs.Type.ToString()));
|
||||
|
||||
if (req != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
try
|
||||
if (req.PollServiceArgs.HasEvents(req.RequestID, req.PollServiceArgs.Id))
|
||||
{
|
||||
if (req.PollServiceArgs.HasEvents(req.RequestID, req.PollServiceArgs.Id))
|
||||
Hashtable responsedata = req.PollServiceArgs.GetEvents(req.RequestID, req.PollServiceArgs.Id);
|
||||
|
||||
if (responsedata == null)
|
||||
return;
|
||||
|
||||
// This is the event queue.
|
||||
// Even if we're not running we can still perform responses by explicit request.
|
||||
if (req.PollServiceArgs.Type == PollServiceEventArgs.EventType.LongPoll
|
||||
|| !PerformResponsesAsync)
|
||||
{
|
||||
Hashtable responsedata = req.PollServiceArgs.GetEvents(req.RequestID, req.PollServiceArgs.Id);
|
||||
|
||||
if (responsedata == null)
|
||||
continue;
|
||||
|
||||
if (req.PollServiceArgs.Type == PollServiceEventArgs.EventType.LongPoll) // This is the event queue
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
req.DoHTTPGruntWork(m_server, responsedata);
|
||||
}
|
||||
catch (ObjectDisposedException) // Browser aborted before we could read body, server closed the stream
|
||||
{
|
||||
// Ignore it, no need to reply
|
||||
}
|
||||
ResponsesProcessed++;
|
||||
req.DoHTTPGruntWork(m_server, responsedata);
|
||||
}
|
||||
else
|
||||
catch (ObjectDisposedException e) // Browser aborted before we could read body, server closed the stream
|
||||
{
|
||||
m_threadPool.QueueWorkItem(x =>
|
||||
{
|
||||
try
|
||||
{
|
||||
req.DoHTTPGruntWork(m_server, responsedata);
|
||||
}
|
||||
catch (ObjectDisposedException) // Browser aborted before we could read body, server closed the stream
|
||||
{
|
||||
// Ignore it, no need to reply
|
||||
}
|
||||
|
||||
return null;
|
||||
}, null);
|
||||
// Ignore it, no need to reply
|
||||
m_log.Error(e);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((Environment.TickCount - req.RequestTime) > req.PollServiceArgs.TimeOutms)
|
||||
m_threadPool.QueueWorkItem(x =>
|
||||
{
|
||||
req.DoHTTPGruntWork(
|
||||
m_server, req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id));
|
||||
}
|
||||
else
|
||||
{
|
||||
ReQueueEvent(req);
|
||||
}
|
||||
try
|
||||
{
|
||||
ResponsesProcessed++;
|
||||
req.DoHTTPGruntWork(m_server, responsedata);
|
||||
}
|
||||
catch (ObjectDisposedException e) // Browser aborted before we could read body, server closed the stream
|
||||
{
|
||||
// Ignore it, no need to reply
|
||||
m_log.Error(e);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Error(e);
|
||||
}
|
||||
|
||||
return null;
|
||||
}, null);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
else
|
||||
{
|
||||
m_log.ErrorFormat("Exception in poll service thread: " + e.ToString());
|
||||
if ((Environment.TickCount - req.RequestTime) > req.PollServiceArgs.TimeOutms)
|
||||
{
|
||||
ResponsesProcessed++;
|
||||
req.DoHTTPGruntWork(
|
||||
m_server, req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id));
|
||||
}
|
||||
else
|
||||
{
|
||||
ReQueueEvent(req);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat("Exception in poll service thread: " + e.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -279,6 +279,17 @@ namespace OpenSim.Framework.Servers
|
||||
"debug threadpool status",
|
||||
"Show current debug threadpool parameters.",
|
||||
HandleDebugThreadpoolStatus);
|
||||
|
||||
m_console.Commands.AddCommand(
|
||||
"Debug", false, "debug threadpool level",
|
||||
"debug threadpool level 0.." + Util.MAX_THREADPOOL_LEVEL,
|
||||
"Turn on logging of activity in the main thread pool.",
|
||||
"Log levels:\n"
|
||||
+ " 0 = no logging\n"
|
||||
+ " 1 = only first line of stack trace; don't log common threads\n"
|
||||
+ " 2 = full stack trace; don't log common threads\n"
|
||||
+ " 3 = full stack trace, including common threads\n",
|
||||
HandleDebugThreadpoolLevel);
|
||||
|
||||
m_console.Commands.AddCommand(
|
||||
"Debug", false, "force gc",
|
||||
@@ -432,6 +443,33 @@ namespace OpenSim.Framework.Servers
|
||||
}
|
||||
}
|
||||
|
||||
private static void HandleDebugThreadpoolLevel(string module, string[] cmdparams)
|
||||
{
|
||||
if (cmdparams.Length < 4)
|
||||
{
|
||||
MainConsole.Instance.Output("Usage: debug threadpool level 0.." + Util.MAX_THREADPOOL_LEVEL);
|
||||
return;
|
||||
}
|
||||
|
||||
string rawLevel = cmdparams[3];
|
||||
int newLevel;
|
||||
|
||||
if (!int.TryParse(rawLevel, out newLevel))
|
||||
{
|
||||
MainConsole.Instance.OutputFormat("{0} is not a valid debug level", rawLevel);
|
||||
return;
|
||||
}
|
||||
|
||||
if (newLevel < 0 || newLevel > Util.MAX_THREADPOOL_LEVEL)
|
||||
{
|
||||
MainConsole.Instance.OutputFormat("{0} is outside the valid debug level range of 0.." + Util.MAX_THREADPOOL_LEVEL, newLevel);
|
||||
return;
|
||||
}
|
||||
|
||||
Util.LogThreadPool = newLevel;
|
||||
MainConsole.Instance.OutputFormat("LogThreadPool set to {0}", newLevel);
|
||||
}
|
||||
|
||||
private void HandleForceGc(string module, string[] args)
|
||||
{
|
||||
Notice("Manually invoking runtime garbage collection");
|
||||
|
||||
@@ -41,323 +41,7 @@ namespace OpenSim.Framework.Servers.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class OSHttpTests : OpenSimTestCase
|
||||
{
|
||||
// we need an IHttpClientContext for our tests
|
||||
public class TestHttpClientContext: IHttpClientContext
|
||||
{
|
||||
private bool _secured;
|
||||
public bool IsSecured
|
||||
{
|
||||
get { return _secured; }
|
||||
}
|
||||
public bool Secured
|
||||
{
|
||||
get { return _secured; }
|
||||
}
|
||||
|
||||
public TestHttpClientContext(bool secured)
|
||||
{
|
||||
_secured = secured;
|
||||
}
|
||||
|
||||
public void Disconnect(SocketError error) {}
|
||||
public void Respond(string httpVersion, HttpStatusCode statusCode, string reason, string body) {}
|
||||
public void Respond(string httpVersion, HttpStatusCode statusCode, string reason) {}
|
||||
public void Respond(string body) {}
|
||||
public void Send(byte[] buffer) {}
|
||||
public void Send(byte[] buffer, int offset, int size) {}
|
||||
public void Respond(string httpVersion, HttpStatusCode statusCode, string reason, string body, string contentType) {}
|
||||
public void Close() { }
|
||||
public bool EndWhenDone { get { return false;} set { return;}}
|
||||
|
||||
public HTTPNetworkContext GiveMeTheNetworkStreamIKnowWhatImDoing()
|
||||
{
|
||||
return new HTTPNetworkContext();
|
||||
}
|
||||
|
||||
public event EventHandler<DisconnectedEventArgs> Disconnected = delegate { };
|
||||
/// <summary>
|
||||
/// A request have been received in the context.
|
||||
/// </summary>
|
||||
public event EventHandler<RequestEventArgs> RequestReceived = delegate { };
|
||||
|
||||
}
|
||||
|
||||
public class TestHttpRequest: IHttpRequest
|
||||
{
|
||||
private string _uriPath;
|
||||
public bool BodyIsComplete
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
public string[] AcceptTypes
|
||||
{
|
||||
get {return _acceptTypes; }
|
||||
}
|
||||
private string[] _acceptTypes;
|
||||
public Stream Body
|
||||
{
|
||||
get { return _body; }
|
||||
set { _body = value;}
|
||||
}
|
||||
private Stream _body;
|
||||
public ConnectionType Connection
|
||||
{
|
||||
get { return _connection; }
|
||||
set { _connection = value; }
|
||||
}
|
||||
private ConnectionType _connection;
|
||||
public int ContentLength
|
||||
{
|
||||
get { return _contentLength; }
|
||||
set { _contentLength = value; }
|
||||
}
|
||||
private int _contentLength;
|
||||
public NameValueCollection Headers
|
||||
{
|
||||
get { return _headers; }
|
||||
}
|
||||
private NameValueCollection _headers = new NameValueCollection();
|
||||
public string HttpVersion
|
||||
{
|
||||
get { return _httpVersion; }
|
||||
set { _httpVersion = value; }
|
||||
}
|
||||
private string _httpVersion = null;
|
||||
public string Method
|
||||
{
|
||||
get { return _method; }
|
||||
set { _method = value; }
|
||||
}
|
||||
private string _method = null;
|
||||
public HttpInput QueryString
|
||||
{
|
||||
get { return _queryString; }
|
||||
}
|
||||
private HttpInput _queryString = null;
|
||||
public Uri Uri
|
||||
{
|
||||
get { return _uri; }
|
||||
set { _uri = value; }
|
||||
}
|
||||
private Uri _uri = null;
|
||||
public string[] UriParts
|
||||
{
|
||||
get { return _uri.Segments; }
|
||||
}
|
||||
public HttpParam Param
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
public HttpForm Form
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
public bool IsAjax
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
public RequestCookies Cookies
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
public TestHttpRequest() {}
|
||||
|
||||
public TestHttpRequest(string contentEncoding, string contentType, string userAgent,
|
||||
string remoteAddr, string remotePort, string[] acceptTypes,
|
||||
ConnectionType connectionType, int contentLength, Uri uri)
|
||||
{
|
||||
_headers["content-encoding"] = contentEncoding;
|
||||
_headers["content-type"] = contentType;
|
||||
_headers["user-agent"] = userAgent;
|
||||
_headers["remote_addr"] = remoteAddr;
|
||||
_headers["remote_port"] = remotePort;
|
||||
|
||||
_acceptTypes = acceptTypes;
|
||||
_connection = connectionType;
|
||||
_contentLength = contentLength;
|
||||
_uri = uri;
|
||||
}
|
||||
|
||||
public void DecodeBody(FormDecoderProvider providers) {}
|
||||
public void SetCookies(RequestCookies cookies) {}
|
||||
public void AddHeader(string name, string value)
|
||||
{
|
||||
_headers.Add(name, value);
|
||||
}
|
||||
public int AddToBody(byte[] bytes, int offset, int length)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
public void Clear() {}
|
||||
|
||||
public object Clone()
|
||||
{
|
||||
TestHttpRequest clone = new TestHttpRequest();
|
||||
clone._acceptTypes = _acceptTypes;
|
||||
clone._connection = _connection;
|
||||
clone._contentLength = _contentLength;
|
||||
clone._uri = _uri;
|
||||
clone._headers = new NameValueCollection(_headers);
|
||||
|
||||
return clone;
|
||||
}
|
||||
public IHttpResponse CreateResponse(IHttpClientContext context)
|
||||
{
|
||||
return new HttpResponse(context, this);
|
||||
}
|
||||
/// <summary>
|
||||
/// Path and query (will be merged with the host header) and put in Uri
|
||||
/// </summary>
|
||||
/// <see cref="Uri"/>
|
||||
public string UriPath
|
||||
{
|
||||
get { return _uriPath; }
|
||||
set
|
||||
{
|
||||
_uriPath = value;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class TestHttpResponse: IHttpResponse
|
||||
{
|
||||
public Stream Body
|
||||
{
|
||||
get { return _body; }
|
||||
|
||||
set { _body = value; }
|
||||
}
|
||||
private Stream _body;
|
||||
|
||||
public string ProtocolVersion
|
||||
{
|
||||
get { return _protocolVersion; }
|
||||
set { _protocolVersion = value; }
|
||||
}
|
||||
private string _protocolVersion;
|
||||
|
||||
public bool Chunked
|
||||
{
|
||||
get { return _chunked; }
|
||||
|
||||
set { _chunked = value; }
|
||||
}
|
||||
private bool _chunked;
|
||||
|
||||
public ConnectionType Connection
|
||||
{
|
||||
get { return _connection; }
|
||||
|
||||
set { _connection = value; }
|
||||
}
|
||||
private ConnectionType _connection;
|
||||
|
||||
public Encoding Encoding
|
||||
{
|
||||
get { return _encoding; }
|
||||
|
||||
set { _encoding = value; }
|
||||
}
|
||||
private Encoding _encoding;
|
||||
|
||||
public int KeepAlive
|
||||
{
|
||||
get { return _keepAlive; }
|
||||
|
||||
set { _keepAlive = value; }
|
||||
}
|
||||
private int _keepAlive;
|
||||
|
||||
public HttpStatusCode Status
|
||||
{
|
||||
get { return _status; }
|
||||
|
||||
set { _status = value; }
|
||||
}
|
||||
private HttpStatusCode _status;
|
||||
|
||||
public string Reason
|
||||
{
|
||||
get { return _reason; }
|
||||
|
||||
set { _reason = value; }
|
||||
}
|
||||
private string _reason;
|
||||
|
||||
public long ContentLength
|
||||
{
|
||||
get { return _contentLength; }
|
||||
|
||||
set { _contentLength = value; }
|
||||
}
|
||||
private long _contentLength;
|
||||
|
||||
public string ContentType
|
||||
{
|
||||
get { return _contentType; }
|
||||
|
||||
set { _contentType = value; }
|
||||
}
|
||||
private string _contentType;
|
||||
|
||||
public bool HeadersSent
|
||||
{
|
||||
get { return _headersSent; }
|
||||
}
|
||||
private bool _headersSent;
|
||||
|
||||
public bool Sent
|
||||
{
|
||||
get { return _sent; }
|
||||
}
|
||||
private bool _sent;
|
||||
|
||||
public ResponseCookies Cookies
|
||||
{
|
||||
get { return _cookies; }
|
||||
}
|
||||
private ResponseCookies _cookies = null;
|
||||
|
||||
public TestHttpResponse()
|
||||
{
|
||||
_headersSent = false;
|
||||
_sent = false;
|
||||
}
|
||||
|
||||
public void AddHeader(string name, string value) {}
|
||||
public void Send()
|
||||
{
|
||||
if (!_headersSent) SendHeaders();
|
||||
if (_sent) throw new InvalidOperationException("stuff already sent");
|
||||
_sent = true;
|
||||
}
|
||||
|
||||
public void SendBody(byte[] buffer, int offset, int count)
|
||||
{
|
||||
if (!_headersSent) SendHeaders();
|
||||
_sent = true;
|
||||
}
|
||||
public void SendBody(byte[] buffer)
|
||||
{
|
||||
if (!_headersSent) SendHeaders();
|
||||
_sent = true;
|
||||
}
|
||||
|
||||
public void SendHeaders()
|
||||
{
|
||||
if (_headersSent) throw new InvalidOperationException("headers already sent");
|
||||
_headersSent = true;
|
||||
}
|
||||
|
||||
public void Redirect(Uri uri) {}
|
||||
public void Redirect(string url) {}
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
public OSHttpRequest req0;
|
||||
public OSHttpRequest req1;
|
||||
|
||||
@@ -429,4 +113,4 @@ namespace OpenSim.Framework.Servers.Tests
|
||||
Assert.That(rsp0.ContentType, Is.EqualTo("text/xml"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -29,8 +29,8 @@ namespace OpenSim
|
||||
{
|
||||
public class VersionInfo
|
||||
{
|
||||
private const string VERSION_NUMBER = "0.8.0";
|
||||
private const Flavour VERSION_FLAVOUR = Flavour.Dev;
|
||||
private const string VERSION_NUMBER = "0.8";
|
||||
private const Flavour VERSION_FLAVOUR = Flavour.Post_Fixes;
|
||||
|
||||
public enum Flavour
|
||||
{
|
||||
@@ -38,6 +38,7 @@ namespace OpenSim
|
||||
Dev,
|
||||
RC1,
|
||||
RC2,
|
||||
RC3,
|
||||
Release,
|
||||
Post_Fixes,
|
||||
Extended
|
||||
|
||||
79
OpenSim/Framework/ServiceAuth/BasicHttpAuthentication.cs
Normal file
79
OpenSim/Framework/ServiceAuth/BasicHttpAuthentication.cs
Normal file
@@ -0,0 +1,79 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Reflection;
|
||||
|
||||
using Nini.Config;
|
||||
using log4net;
|
||||
|
||||
namespace OpenSim.Framework.ServiceAuth
|
||||
{
|
||||
public class BasicHttpAuthentication : IServiceAuth
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private string m_Username, m_Password;
|
||||
private string m_CredentialsB64;
|
||||
|
||||
private string remove_me;
|
||||
|
||||
public string Credentials
|
||||
{
|
||||
get { return m_CredentialsB64; }
|
||||
}
|
||||
|
||||
public BasicHttpAuthentication(IConfigSource config, string section)
|
||||
{
|
||||
remove_me = section;
|
||||
m_Username = Util.GetConfigVarFromSections<string>(config, "HttpAuthUsername", new string[] { "Network", section }, string.Empty);
|
||||
m_Password = Util.GetConfigVarFromSections<string>(config, "HttpAuthPassword", new string[] { "Network", section }, string.Empty);
|
||||
string str = m_Username + ":" + m_Password;
|
||||
byte[] encData_byte = Util.UTF8.GetBytes(str);
|
||||
|
||||
m_CredentialsB64 = Convert.ToBase64String(encData_byte);
|
||||
m_log.DebugFormat("[HTTP BASIC AUTH]: {0} {1} [{2}]", m_Username, m_Password, section);
|
||||
}
|
||||
|
||||
public void AddAuthorization(NameValueCollection headers)
|
||||
{
|
||||
//m_log.DebugFormat("[HTTP BASIC AUTH]: Adding authorization for {0}", remove_me);
|
||||
headers["Authorization"] = "Basic " + m_CredentialsB64;
|
||||
}
|
||||
|
||||
public bool Authenticate(string data)
|
||||
{
|
||||
string recovered = Util.Base64ToString(data);
|
||||
if (!String.IsNullOrEmpty(recovered))
|
||||
{
|
||||
string[] parts = recovered.Split(new char[] { ':' });
|
||||
if (parts.Length >= 2)
|
||||
{
|
||||
return m_Username.Equals(parts[0]) && m_Password.Equals(parts[1]);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool Authenticate(NameValueCollection requestHeaders, AddHeaderDelegate d)
|
||||
{
|
||||
//m_log.DebugFormat("[HTTP BASIC AUTH]: Authenticate in {0}", remove_me);
|
||||
if (requestHeaders != null)
|
||||
{
|
||||
string value = requestHeaders.Get("Authorization");
|
||||
if (value != null)
|
||||
{
|
||||
value = value.Trim();
|
||||
if (value.StartsWith("Basic "))
|
||||
{
|
||||
value = value.Replace("Basic ", string.Empty);
|
||||
if (Authenticate(value))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
d("WWW-Authenticate", "Basic realm = \"Asset Server\"");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
15
OpenSim/Framework/ServiceAuth/IServiceAuth.cs
Normal file
15
OpenSim/Framework/ServiceAuth/IServiceAuth.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
|
||||
namespace OpenSim.Framework.ServiceAuth
|
||||
{
|
||||
public delegate void AddHeaderDelegate(string key, string value);
|
||||
|
||||
public interface IServiceAuth
|
||||
{
|
||||
bool Authenticate(string data);
|
||||
bool Authenticate(NameValueCollection headers, AddHeaderDelegate d);
|
||||
void AddAuthorization(NameValueCollection headers);
|
||||
}
|
||||
}
|
||||
23
OpenSim/Framework/ServiceAuth/ServiceAuth.cs
Normal file
23
OpenSim/Framework/ServiceAuth/ServiceAuth.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using Nini.Config;
|
||||
|
||||
namespace OpenSim.Framework.ServiceAuth
|
||||
{
|
||||
public class ServiceAuth
|
||||
{
|
||||
public static IServiceAuth Create(IConfigSource config, string section)
|
||||
{
|
||||
string authType = Util.GetConfigVarFromSections<string>(config, "AuthType", new string[] { "Network", section }, "None");
|
||||
|
||||
switch (authType)
|
||||
{
|
||||
case "BasicHttpAuthentication":
|
||||
return new BasicHttpAuthentication(config, section);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user