Compare commits
758 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
288f5bd727 | ||
|
|
5b40389352 | ||
|
|
8fac7c0650 | ||
|
|
9d22110c23 | ||
|
|
cc1fe354d0 | ||
|
|
859a804d59 | ||
|
|
c95c8ab246 | ||
|
|
7d2a3dc174 | ||
|
|
37370a8102 | ||
|
|
4ae4b14b5d | ||
|
|
522d6261f1 | ||
|
|
c4efb97d49 | ||
|
|
de19dc3024 | ||
|
|
a4cc5f628f | ||
|
|
8fb3e71b14 | ||
|
|
42f1b88eb2 | ||
|
|
e15917f465 | ||
|
|
1129b80629 | ||
|
|
5484c9b585 | ||
|
|
cda4cd6b55 | ||
|
|
bd991fc95f | ||
|
|
1084d8f6a2 | ||
|
|
61affee814 | ||
|
|
2d62484f11 | ||
|
|
62b3e74bc5 | ||
|
|
8880aea728 | ||
|
|
618277e797 | ||
|
|
df73833a2c | ||
|
|
f09a90d8a7 | ||
|
|
07ba28f1de | ||
|
|
c14f0a22d4 | ||
|
|
88bd71b978 | ||
|
|
306af9934a | ||
|
|
dea0935361 | ||
|
|
62b2450529 | ||
|
|
56cd7d9685 | ||
|
|
00f8946bd4 | ||
|
|
294120c9d3 | ||
|
|
ea0f78c971 | ||
|
|
dab6387bba | ||
|
|
44a491f36b | ||
|
|
7f318277f1 | ||
|
|
517932722b | ||
|
|
728fd0b1b8 | ||
|
|
9c32b131fd | ||
|
|
7531851bec | ||
|
|
de28c9cd24 | ||
|
|
1dd904b78e | ||
|
|
7cafc2e46e | ||
|
|
28961dd1cf | ||
|
|
bea2e0f32b | ||
|
|
655935db49 | ||
|
|
42790f021f | ||
|
|
086bf9f15d | ||
|
|
f5eace6781 | ||
|
|
9615292133 | ||
|
|
96a3b68086 | ||
|
|
bd5d2cb043 | ||
|
|
3e7960d161 | ||
|
|
08bd16285d | ||
|
|
7cadb89a0f | ||
|
|
03f6734f43 | ||
|
|
d7a516d885 | ||
|
|
e6cd4defdb | ||
|
|
3d4d3427cd | ||
|
|
405a5b097b | ||
|
|
4bf3adffb8 | ||
|
|
1a8f5b97b9 | ||
|
|
5beee42809 | ||
|
|
b903d2ca96 | ||
|
|
c6ec573d10 | ||
|
|
05a4bedc30 | ||
|
|
0cb0140a1d | ||
|
|
cf73afec35 | ||
|
|
5e579b71fd | ||
|
|
9f75eaf50e | ||
|
|
9cc2d0b60a | ||
|
|
af59352c4c | ||
|
|
9ab951a954 | ||
|
|
66dec3b874 | ||
|
|
5c1fa968ab | ||
|
|
e6eb0d9a6f | ||
|
|
dbcfb25a52 | ||
|
|
26b471f25a | ||
|
|
af7c6c5f39 | ||
|
|
9c0a03731d | ||
|
|
15ea82e925 | ||
|
|
01146bb3e3 | ||
|
|
3e86064d6b | ||
|
|
cc8897127b | ||
|
|
712d44635a | ||
|
|
e30651b931 | ||
|
|
8b83c4a433 | ||
|
|
1bf29d60e1 | ||
|
|
616e672fce | ||
|
|
c491cdcb95 | ||
|
|
7eca929686 | ||
|
|
10d883dc88 | ||
|
|
63bf710237 | ||
|
|
095b3e5756 | ||
|
|
083ba72b28 | ||
|
|
ca9a054bba | ||
|
|
7d58b5fa15 | ||
|
|
3aa86d22d1 | ||
|
|
e69f246b86 | ||
|
|
899d109e82 | ||
|
|
8c703022c1 | ||
|
|
d3c03658aa | ||
|
|
54839d28ad | ||
|
|
5a5206449f | ||
|
|
32444d98cb | ||
|
|
2acfff9f6d | ||
|
|
1809aaf74c | ||
|
|
ddc733cd3d | ||
|
|
91f59f246f | ||
|
|
9e4153f16b | ||
|
|
04bafd2122 | ||
|
|
a90e1cf3aa | ||
|
|
1de68b34d9 | ||
|
|
37a5cf5783 | ||
|
|
953611af53 | ||
|
|
e7a515bab0 | ||
|
|
b705ad477e | ||
|
|
b281163457 | ||
|
|
17dab7245f | ||
|
|
be357f8fee | ||
|
|
96dce3e16c | ||
|
|
648866b597 | ||
|
|
18037d41c4 | ||
|
|
80a2b81d52 | ||
|
|
795b56e695 | ||
|
|
d4d894c20f | ||
|
|
1615e7d29f | ||
|
|
b7700428ec | ||
|
|
33a894f3d2 | ||
|
|
21708b832b | ||
|
|
23f10f1d22 | ||
|
|
15a514fcbc | ||
|
|
5f3ffc195f | ||
|
|
ae614c1264 | ||
|
|
040ad11e61 | ||
|
|
dc61bf4b1f | ||
|
|
1dba047e4d | ||
|
|
002313bf13 | ||
|
|
fcbed6479a | ||
|
|
6c692d2e21 | ||
|
|
04d42860fe | ||
|
|
cf42fcd978 | ||
|
|
4b4c5e69e5 | ||
|
|
d5dc8133fc | ||
|
|
6d4432f440 | ||
|
|
21f1b68fdf | ||
|
|
73d913dad2 | ||
|
|
9ba4511d3e | ||
|
|
801b7f18a7 | ||
|
|
5eeee480d4 | ||
|
|
274e354006 | ||
|
|
0e0d40c810 | ||
|
|
ccf07f6ae3 | ||
|
|
b9ec625dbf | ||
|
|
cf3ffe5bb4 | ||
|
|
97b207240e | ||
|
|
014cd4f8bb | ||
|
|
805ba268d5 | ||
|
|
4a101080ee | ||
|
|
34aed96a2f | ||
|
|
ce011d7e44 | ||
|
|
afd5469eec | ||
|
|
1f3ce48be1 | ||
|
|
d328046efb | ||
|
|
2eaadf2dc0 | ||
|
|
138a5e04b8 | ||
|
|
940a248c3d | ||
|
|
7cf4bb5256 | ||
|
|
db91044593 | ||
|
|
d74686fd51 | ||
|
|
c587b0a3a3 | ||
|
|
9469c62098 | ||
|
|
f9a367e2f6 | ||
|
|
5a11cffd23 | ||
|
|
20a4367827 | ||
|
|
8254116dc6 | ||
|
|
2f1ac1d144 | ||
|
|
94a8ab80c8 | ||
|
|
2307d9a2f9 | ||
|
|
5e231acdce | ||
|
|
2787207aa2 | ||
|
|
384cb79a1a | ||
|
|
a0a0c64cb1 | ||
|
|
bb5b396fc5 | ||
|
|
c9e6b7bd10 | ||
|
|
3146f4bae0 | ||
|
|
fef73a1a10 | ||
|
|
49258350e8 | ||
|
|
8d29d490a1 | ||
|
|
45c37ef494 | ||
|
|
c1a34cd8da | ||
|
|
d8f886ccdb | ||
|
|
eb8b6b7d52 | ||
|
|
6b51d8a10e | ||
|
|
4a9b8184f7 | ||
|
|
acfdca34fd | ||
|
|
bd5d35ee32 | ||
|
|
696bd44833 | ||
|
|
d73c424078 | ||
|
|
57e54d84d6 | ||
|
|
d3c10e609e | ||
|
|
0bbf7c21d7 | ||
|
|
c58b32e7ba | ||
|
|
601257f8b6 | ||
|
|
66eb537d0c | ||
|
|
eb431f91c0 | ||
|
|
8d866ae8c3 | ||
|
|
96ee87e39b | ||
|
|
e29e50798a | ||
|
|
fd3a7ab70c | ||
|
|
8c95c83562 | ||
|
|
0784791a44 | ||
|
|
dc772c608d | ||
|
|
e8f09cd5f7 | ||
|
|
e870442e31 | ||
|
|
9a6ad1535e | ||
|
|
70ea625447 | ||
|
|
e19843a0ee | ||
|
|
b80dfb6572 | ||
|
|
dcb4b2de09 | ||
|
|
77625dae36 | ||
|
|
d0bcaf1f16 | ||
|
|
90c6fa89be | ||
|
|
78ff82bfe9 | ||
|
|
ed142ead25 | ||
|
|
4b88f04c0a | ||
|
|
76e0afe83f | ||
|
|
16ac5413dd | ||
|
|
aebd46a434 | ||
|
|
2169cf04f9 | ||
|
|
65c4b8d37b | ||
|
|
0a1bbc27d2 | ||
|
|
d23d37d2aa | ||
|
|
a21e98ae1a | ||
|
|
b1ae930c6b | ||
|
|
50945dd560 | ||
|
|
83ca5a101d | ||
|
|
5d694a224f | ||
|
|
b3a4b10531 | ||
|
|
3d4cc93a8e | ||
|
|
1aa1711893 | ||
|
|
36f7d36fa1 | ||
|
|
29093df1a7 | ||
|
|
ee22569c92 | ||
|
|
cace6eaa8a | ||
|
|
4402851b08 | ||
|
|
951ffad81e | ||
|
|
7f499ff3f3 | ||
|
|
fb92678b83 | ||
|
|
5d6c9644fa | ||
|
|
4cb8d6379d | ||
|
|
195c1dc9b8 | ||
|
|
cba54090c7 | ||
|
|
92e96d394a | ||
|
|
795c8e6c22 | ||
|
|
6ab5ca2bda | ||
|
|
0e9dda91cb | ||
|
|
57cc180fd5 | ||
|
|
e869eeb0bf | ||
|
|
916d1b7511 | ||
|
|
3e16a0fbdd | ||
|
|
1677587532 | ||
|
|
78d8ce3816 | ||
|
|
6878049952 | ||
|
|
eec54adac5 | ||
|
|
e37f8cf902 | ||
|
|
85e07c78fb | ||
|
|
83ba35a26b | ||
|
|
2b26d2f1a5 | ||
|
|
76f46b2545 | ||
|
|
dad1d6df18 | ||
|
|
bda1a4be45 | ||
|
|
cba40de109 | ||
|
|
c6c91e6599 | ||
|
|
ba89fc3aa1 | ||
|
|
f18780d0e3 | ||
|
|
82f41fdcb5 | ||
|
|
7d35bf8193 | ||
|
|
1a2518d19b | ||
|
|
c3f579046c | ||
|
|
7640b5abf6 | ||
|
|
94d496cf2b | ||
|
|
1918402cb1 | ||
|
|
54ce029342 | ||
|
|
f999acd095 | ||
|
|
c678b75d65 | ||
|
|
61a931490d | ||
|
|
831f933ce6 | ||
|
|
7b2b47530e | ||
|
|
fc64cc2439 | ||
|
|
7f6f100c5a | ||
|
|
ba0c65e028 | ||
|
|
6f913e8caf | ||
|
|
a2f5b4ac9a | ||
|
|
0299cb060e | ||
|
|
6ab01b338f | ||
|
|
31fb6b2d72 | ||
|
|
61d49d4f63 | ||
|
|
31cea17f8e | ||
|
|
21d8a6b0e8 | ||
|
|
d78fe44191 | ||
|
|
e0503d397c | ||
|
|
a333c60f28 | ||
|
|
2964467708 | ||
|
|
b7a3f36c65 | ||
|
|
c1c0d780ee | ||
|
|
797def8aa4 | ||
|
|
6e4ec29722 | ||
|
|
68a5fe0431 | ||
|
|
30e816bfa2 | ||
|
|
0c23764ce2 | ||
|
|
1c126e6e22 | ||
|
|
f9689f5cc9 | ||
|
|
74b23210a7 | ||
|
|
c122489e09 | ||
|
|
b7f81d3492 | ||
|
|
d2220da205 | ||
|
|
17e9d61f43 | ||
|
|
e6fb9d74ef | ||
|
|
8d33a2eaa1 | ||
|
|
b6ac1c46cd | ||
|
|
59f548cda8 | ||
|
|
05e94ff27e | ||
|
|
f9d6a91252 | ||
|
|
40a78db182 | ||
|
|
ccb4b76242 | ||
|
|
f79df6f43f | ||
|
|
f32dbef647 | ||
|
|
6618948ff9 | ||
|
|
509200d5cd | ||
|
|
dfa2f7d715 | ||
|
|
2102964826 | ||
|
|
434091d3f4 | ||
|
|
b757583662 | ||
|
|
aea7007533 | ||
|
|
450bdb3657 | ||
|
|
d041276517 | ||
|
|
bd8f538f80 | ||
|
|
196a774b24 | ||
|
|
454312f5bc | ||
|
|
f1ce17071d | ||
|
|
e08be91c84 | ||
|
|
4f4d080461 | ||
|
|
49a3740ee9 | ||
|
|
9fc59e2bf2 | ||
|
|
d917010433 | ||
|
|
310a685220 | ||
|
|
4197f66052 | ||
|
|
b0eacadeb4 | ||
|
|
122e01949d | ||
|
|
7791c1fd1e | ||
|
|
c4c6b457c3 | ||
|
|
835352aee9 | ||
|
|
2f5995f5c0 | ||
|
|
6d866ba6d5 | ||
|
|
9a5e0ede7c | ||
|
|
84c68c61bd | ||
|
|
5043be13fb | ||
|
|
f3c5a5b745 | ||
|
|
2a39d0cdb0 | ||
|
|
3f0d8f3cbf | ||
|
|
9c6227da66 | ||
|
|
8c3eb324c4 | ||
|
|
c4ffcd4b7d | ||
|
|
04eaca2af8 | ||
|
|
a95f2fe4b3 | ||
|
|
5c012cac54 | ||
|
|
2e83b48873 | ||
|
|
c2de0c930c | ||
|
|
4cdc8806fb | ||
|
|
96174595da | ||
|
|
504de8bc47 | ||
|
|
ea58aee338 | ||
|
|
4eaca4884e | ||
|
|
be9b4ad23a | ||
|
|
f0895028e9 | ||
|
|
fcaa4f6012 | ||
|
|
667b54f5a2 | ||
|
|
869883f2dc | ||
|
|
aadc4eb3b8 | ||
|
|
3c09f918ad | ||
|
|
5ffec1cd64 | ||
|
|
fa696c2eb2 | ||
|
|
4cbc912375 | ||
|
|
705f70064e | ||
|
|
0e52010c0e | ||
|
|
6ac0bc7259 | ||
|
|
02e54c57c4 | ||
|
|
d8228f4374 | ||
|
|
71ef4a8fb3 | ||
|
|
56830bfe07 | ||
|
|
f97278610c | ||
|
|
6426492da0 | ||
|
|
630e11cbe1 | ||
|
|
e1ce106790 | ||
|
|
0a09c45726 | ||
|
|
d2d67a1abf | ||
|
|
69c2d3434a | ||
|
|
703d130e96 | ||
|
|
1c758ae01c | ||
|
|
81fe1cfad6 | ||
|
|
2c11f7fc38 | ||
|
|
3270bd560e | ||
|
|
9fc7d65df7 | ||
|
|
51c47677a1 | ||
|
|
cbaa4aa88f | ||
|
|
c768d18c92 | ||
|
|
f5623b5c39 | ||
|
|
ee829a71c2 | ||
|
|
c50533659a | ||
|
|
ec1ecd3633 | ||
|
|
25c532f2ec | ||
|
|
9dd5a24495 | ||
|
|
bc3679b67d | ||
|
|
0ef29da9b2 | ||
|
|
62325829ec | ||
|
|
1fdb16f1cd | ||
|
|
b2722e984a | ||
|
|
97f1edfd95 | ||
|
|
4b9ef4f39c | ||
|
|
7c468cda36 | ||
|
|
c94dc95844 | ||
|
|
430a4aeba8 | ||
|
|
86f45f6fe7 | ||
|
|
6fc74b36d1 | ||
|
|
aec3b58a57 | ||
|
|
3f8e571b78 | ||
|
|
bdd340b9fc | ||
|
|
e9a739f45f | ||
|
|
dd2564d7ec | ||
|
|
f5ddf37112 | ||
|
|
9a80adf33a | ||
|
|
122745fe1c | ||
|
|
2b68ac4ba3 | ||
|
|
4b5a6b655b | ||
|
|
df2a59d31b | ||
|
|
0f9882db5b | ||
|
|
6f9b855719 | ||
|
|
982e71b6b8 | ||
|
|
c82f19e41c | ||
|
|
3fc12e7224 | ||
|
|
2b339b7d2b | ||
|
|
27fae36a21 | ||
|
|
50bd48542c | ||
|
|
6179879308 | ||
|
|
da7340b9fb | ||
|
|
18652eb87e | ||
|
|
7247ca1644 | ||
|
|
a9ba9d4a9e | ||
|
|
0ee7a5ee81 | ||
|
|
3e5b2d52ff | ||
|
|
b5fcd2caba | ||
|
|
e9dbe54ab1 | ||
|
|
b55076990c | ||
|
|
c7dbd7cbd0 | ||
|
|
8dff9d564d | ||
|
|
8925fb5537 | ||
|
|
bb402d0d95 | ||
|
|
cc69d12d54 | ||
|
|
7fac07d9ab | ||
|
|
c7e8529122 | ||
|
|
0d64155bb5 | ||
|
|
938b4f8bf8 | ||
|
|
e434ba5e8e | ||
|
|
08dc07dc76 | ||
|
|
5158ec0913 | ||
|
|
bf1b8397bb | ||
|
|
3e456163dd | ||
|
|
1f3e42adf3 | ||
|
|
d31e0a67f7 | ||
|
|
f75f906e35 | ||
|
|
7442f064f5 | ||
|
|
df0e5cc9fe | ||
|
|
3dcc15ede3 | ||
|
|
38f0cf4bf4 | ||
|
|
616f3844b6 | ||
|
|
dbd954d701 | ||
|
|
b9cbe92f30 | ||
|
|
51d6c58d10 | ||
|
|
24efb021ff | ||
|
|
8e44a8e2b9 | ||
|
|
0badf3718d | ||
|
|
2f3d0e209f | ||
|
|
ce85675e70 | ||
|
|
6a15464b0a | ||
|
|
01b98c2e62 | ||
|
|
e68ae44b6b | ||
|
|
c6d4304a04 | ||
|
|
c964114f7e | ||
|
|
b59b1ff3d9 | ||
|
|
9c9b3e3976 | ||
|
|
457ba9d1a2 | ||
|
|
59aedbc94b | ||
|
|
f99b89990c | ||
|
|
6963b8b046 | ||
|
|
df586c9d25 | ||
|
|
f680c13495 | ||
|
|
52c3671aa0 | ||
|
|
b983f38e2a | ||
|
|
04f8d0e45d | ||
|
|
c920ff9d1d | ||
|
|
e7abf834d1 | ||
|
|
d79c6c8820 | ||
|
|
5e8900dfd0 | ||
|
|
c3d82bdcb1 | ||
|
|
a048ec3f95 | ||
|
|
192bd1057e | ||
|
|
5700c582ba | ||
|
|
e8ad8593b6 | ||
|
|
40300c886c | ||
|
|
b18ef976ff | ||
|
|
29034bc0e0 | ||
|
|
36df9ae79a | ||
|
|
1dcad4ac66 | ||
|
|
3bda7711b3 | ||
|
|
2fbc98fa5c | ||
|
|
e91861fff2 | ||
|
|
4e30361f63 | ||
|
|
281e80ccf3 | ||
|
|
fedfa02b64 | ||
|
|
06d5989f4d | ||
|
|
f45746613d | ||
|
|
47cf9c8fe0 | ||
|
|
719e0702be | ||
|
|
30482e7ae5 | ||
|
|
d2fc23c034 | ||
|
|
af8773d6d0 | ||
|
|
cb02fc44f5 | ||
|
|
f58de55c84 | ||
|
|
bebc51a6e0 | ||
|
|
5dc785bbf2 | ||
|
|
46f5893d55 | ||
|
|
b8e7258051 | ||
|
|
bb4cb16512 | ||
|
|
513d63455e | ||
|
|
ed12e38480 | ||
|
|
fba961c63f | ||
|
|
e765759f50 | ||
|
|
759e855566 | ||
|
|
e41093635a | ||
|
|
9f72fbcb75 | ||
|
|
2d2c29ef3e | ||
|
|
a9b7487fcb | ||
|
|
03feb50a72 | ||
|
|
5c18ebf424 | ||
|
|
5f927dc104 | ||
|
|
c84a1bd99f | ||
|
|
1b4c08730e | ||
|
|
3f0b8db0c1 | ||
|
|
22f25fae38 | ||
|
|
ee92f22f2a | ||
|
|
80010f8908 | ||
|
|
ffa790d69d | ||
|
|
882d5c82b3 | ||
|
|
e11c959400 | ||
|
|
36e2054760 | ||
|
|
23bf773dea | ||
|
|
698cd0b3c2 | ||
|
|
5daac0584a | ||
|
|
296774495b | ||
|
|
56dcc51094 | ||
|
|
7545692f32 | ||
|
|
0dd3281caf | ||
|
|
afb1248e39 | ||
|
|
1a0a9d2290 | ||
|
|
1cad116b1d | ||
|
|
75199a0d2c | ||
|
|
37a7c16734 | ||
|
|
de20f0603f | ||
|
|
7974349262 | ||
|
|
302d72701d | ||
|
|
1b7fec0842 | ||
|
|
f4f55c4d6b | ||
|
|
6ae73aea49 | ||
|
|
163ee82168 | ||
|
|
7819b4a794 | ||
|
|
409738726d | ||
|
|
ad84728aba | ||
|
|
29da57e380 | ||
|
|
289c8fe1bc | ||
|
|
7a4fbdac7c | ||
|
|
5b7ab50319 | ||
|
|
bbe489e64a | ||
|
|
603dbea190 | ||
|
|
822b9e085f | ||
|
|
c62ccc75a1 | ||
|
|
ecb28ae130 | ||
|
|
ab11835aeb | ||
|
|
0e4db3ca39 | ||
|
|
9b1d3f0c38 | ||
|
|
dc978d02a7 | ||
|
|
4b9de140ab | ||
|
|
95e050130c | ||
|
|
2e77518c6d | ||
|
|
07d7c1cd2d | ||
|
|
78c16da544 | ||
|
|
fd57c91b4a | ||
|
|
06e254c392 | ||
|
|
e1ca77a0db | ||
|
|
d992779397 | ||
|
|
a1c16a4200 | ||
|
|
e07d71d298 | ||
|
|
5f311c91c7 | ||
|
|
0ae022d688 | ||
|
|
487cb51f69 | ||
|
|
9a62bfab0e | ||
|
|
39e878eb8f | ||
|
|
c7cef650db | ||
|
|
b13b54c526 | ||
|
|
fc7e17baf7 | ||
|
|
c7bdb66a1f | ||
|
|
804fe2d9b0 | ||
|
|
08db3c5a8e | ||
|
|
b5518dc906 | ||
|
|
eeac2275c9 | ||
|
|
98d1e7768a | ||
|
|
387b228d68 | ||
|
|
9149ef6c89 | ||
|
|
d780500c58 | ||
|
|
2bc8dcfdbd | ||
|
|
8d3a8a0a81 | ||
|
|
e3e1f6308d | ||
|
|
4cf60c5d9d | ||
|
|
326c46ba70 | ||
|
|
49e4e53928 | ||
|
|
2a46f756d6 | ||
|
|
1bd712c541 | ||
|
|
80fc607d75 | ||
|
|
9759b2a4bb | ||
|
|
90f657d77d | ||
|
|
61f1c2b2c5 | ||
|
|
39323055bd | ||
|
|
eabfc9ca15 | ||
|
|
3307db5d4a | ||
|
|
02b40670be | ||
|
|
41627bdf8a | ||
|
|
f5d82350bb | ||
|
|
1a23d322ac | ||
|
|
dce0e46eaa | ||
|
|
e77ca65e57 | ||
|
|
6861606b6d | ||
|
|
78e76bba38 | ||
|
|
a41051f1dd | ||
|
|
205b2f7ea4 | ||
|
|
fe471b6424 | ||
|
|
12b1cbf8bf | ||
|
|
fe890554fb | ||
|
|
896f039513 | ||
|
|
1543fd7fff | ||
|
|
66004a9375 | ||
|
|
d09210da86 | ||
|
|
527e10a04e | ||
|
|
cf86ba5559 | ||
|
|
623706d988 | ||
|
|
fde3e704d3 | ||
|
|
4ea89f39f2 | ||
|
|
7772640ae8 | ||
|
|
e33cedfd42 | ||
|
|
995b893e4c | ||
|
|
76c60f1f99 | ||
|
|
dfa4442319 | ||
|
|
b8e2ee6978 | ||
|
|
b000d4f67f | ||
|
|
2a12d143c2 | ||
|
|
6312eea459 | ||
|
|
458a8c6d0b | ||
|
|
65c71050cc | ||
|
|
3c15c0b264 | ||
|
|
61bf2bf2dd | ||
|
|
4696a9c95e | ||
|
|
f2f30a7890 | ||
|
|
c13acdf5a1 | ||
|
|
43ecc46a22 | ||
|
|
3fa54a156a | ||
|
|
46cdd442a8 | ||
|
|
777f57d946 | ||
|
|
0a430bbffb | ||
|
|
ac4d080aaf | ||
|
|
984b801dd9 | ||
|
|
4b9e446c62 | ||
|
|
b0ed0e63dc | ||
|
|
54096db30b | ||
|
|
5fb0455e92 | ||
|
|
a3e0895f12 | ||
|
|
c43ad8a0e7 | ||
|
|
8bacf56e46 | ||
|
|
929bdba346 | ||
|
|
aed6e74080 | ||
|
|
5711ada5c9 | ||
|
|
c67fa72d56 | ||
|
|
8129e64e2a | ||
|
|
392d270264 | ||
|
|
c4b265aeae | ||
|
|
44371118a2 | ||
|
|
b81a304baa | ||
|
|
e14b7ec9e1 | ||
|
|
d473d9975e | ||
|
|
7ea6dfecd9 | ||
|
|
d671dbb7c7 | ||
|
|
5cb7d8bc71 | ||
|
|
d5326197ac | ||
|
|
16fae059bb | ||
|
|
3326e417b4 | ||
|
|
c7e18f9017 | ||
|
|
d2c2a4301b | ||
|
|
99f42c0a6e | ||
|
|
6f4a2685cf | ||
|
|
28cd03cda5 | ||
|
|
44d5821c4e | ||
|
|
b0c9696de0 | ||
|
|
e9988a3728 | ||
|
|
fcef4688a8 | ||
|
|
76525be7b2 | ||
|
|
4e4db749eb | ||
|
|
0af5bb239f | ||
|
|
4087a453dc | ||
|
|
d60f525baa | ||
|
|
36f9d55c36 | ||
|
|
31d07859f9 | ||
|
|
abae859e7a | ||
|
|
07acb4d321 | ||
|
|
0d29f73916 | ||
|
|
f02fbdbc68 | ||
|
|
5cbb203efb | ||
|
|
b17afe43c4 | ||
|
|
0c58a9e680 | ||
|
|
3e54aad76c | ||
|
|
4d324f1b74 | ||
|
|
03525959c9 | ||
|
|
b000d9ba72 | ||
|
|
91ec1a572a | ||
|
|
3270f4353e | ||
|
|
c7e46e8a51 | ||
|
|
ab855e6f8d | ||
|
|
d9889ae2e7 | ||
|
|
6f4d079fc5 | ||
|
|
587b17e23b | ||
|
|
5c2168cae7 | ||
|
|
38ef8ba430 | ||
|
|
e398c33648 | ||
|
|
932db1c374 | ||
|
|
ef3f6b4e63 | ||
|
|
a8913141c0 | ||
|
|
e19031849e | ||
|
|
1b106c3928 | ||
|
|
28c25d8477 | ||
|
|
24f28d3534 | ||
|
|
336665e035 | ||
|
|
fed3cc630e | ||
|
|
58c53c41de | ||
|
|
80457111e0 | ||
|
|
d21e9c755f |
@@ -14,6 +14,7 @@ people that make the day to day of OpenSim happen.
|
||||
* Marck
|
||||
* Mic Bowman (Intel)
|
||||
* BlueWall (James Hughes)
|
||||
* Snoopy Pfeffer
|
||||
|
||||
= Core Developers Following the White Rabbit =
|
||||
Core developers who have temporarily (we hope) gone chasing the white rabbit.
|
||||
@@ -111,9 +112,12 @@ what it is today.
|
||||
* Mircea Kitsune
|
||||
* mpallari
|
||||
* MrMonkE
|
||||
* Nebadon Izumi (Michael Cerquoni - http://OSgrid.org)
|
||||
* Neil Canham
|
||||
* nornalbion
|
||||
* Omar Vera Ustariz (IBM)
|
||||
* openlifegrid.com
|
||||
* Oren Hurvitz (Kitely)
|
||||
* otakup0pe
|
||||
* ralphos
|
||||
* RemedyTomm
|
||||
@@ -127,7 +131,6 @@ what it is today.
|
||||
* Salahzar Stenvaag
|
||||
* sempuki
|
||||
* SignpostMarv
|
||||
* Snoopy
|
||||
* Strawberry Fride
|
||||
* tglion
|
||||
* tlaukkan/Tommil (Tommi S. E. Laukkanen, Bubble Cloud)
|
||||
|
||||
@@ -812,6 +812,14 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||
// ok, client wants us to use an explicit UUID
|
||||
// regardless of what the avatar name provided
|
||||
userID = new UUID((string) requestData["estate_owner_uuid"]);
|
||||
|
||||
// Check that the specified user exists
|
||||
Scene currentOrFirst = m_application.SceneManager.CurrentOrFirstScene;
|
||||
IUserAccountService accountService = currentOrFirst.UserAccountService;
|
||||
UserAccount user = accountService.GetUserAccount(currentOrFirst.RegionInfo.ScopeID, userID);
|
||||
|
||||
if (user == null)
|
||||
throw new Exception("Specified user was not found.");
|
||||
}
|
||||
else if (requestData.ContainsKey("estate_owner_first") & requestData.ContainsKey("estate_owner_last"))
|
||||
{
|
||||
@@ -823,6 +831,11 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||
IUserAccountService accountService = currentOrFirst.UserAccountService;
|
||||
UserAccount user = accountService.GetUserAccount(currentOrFirst.RegionInfo.ScopeID,
|
||||
ownerFirst, ownerLast);
|
||||
|
||||
// Check that the specified user exists
|
||||
if (user == null)
|
||||
throw new Exception("Specified user was not found.");
|
||||
|
||||
userID = user.PrincipalID;
|
||||
}
|
||||
else
|
||||
@@ -2304,6 +2317,10 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||
/// <description>UUID of the region</description></item>
|
||||
/// <item><term>region_name</term>
|
||||
/// <description>region name</description></item>
|
||||
/// <item><term>merge</term>
|
||||
/// <description>true if oar should be merged</description></item>
|
||||
/// <item><term>skip-assets</term>
|
||||
/// <description>true if assets should be skiped</description></item>
|
||||
/// </list>
|
||||
///
|
||||
/// <code>region_uuid</code> takes precedence over
|
||||
@@ -2362,10 +2379,22 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||
throw new Exception(String.Format("failed to switch to region {0}", region_name));
|
||||
}
|
||||
else throw new Exception("neither region_name nor region_uuid given");
|
||||
|
||||
bool mergeOar = false;
|
||||
bool skipAssets = false;
|
||||
|
||||
if ((string)requestData["merge"] == "true")
|
||||
{
|
||||
mergeOar = true;
|
||||
}
|
||||
if ((string)requestData["skip-assets"] == "true")
|
||||
{
|
||||
skipAssets = true;
|
||||
}
|
||||
|
||||
IRegionArchiverModule archiver = scene.RequestModuleInterface<IRegionArchiverModule>();
|
||||
if (archiver != null)
|
||||
archiver.DearchiveRegion(filename);
|
||||
archiver.DearchiveRegion(filename, mergeOar, skipAssets, Guid.Empty);
|
||||
else
|
||||
throw new Exception("Archiver module not present for scene");
|
||||
|
||||
@@ -2405,6 +2434,10 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||
/// <description>UUID of the region</description></item>
|
||||
/// <item><term>region_name</term>
|
||||
/// <description>region name</description></item>
|
||||
/// <item><term>profile</term>
|
||||
/// <description>profile url</description></item>
|
||||
/// <item><term>noassets</term>
|
||||
/// <description>true if no assets should be saved</description></item>
|
||||
/// </list>
|
||||
///
|
||||
/// <code>region_uuid</code> takes precedence over
|
||||
@@ -2462,12 +2495,29 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||
}
|
||||
else throw new Exception("neither region_name nor region_uuid given");
|
||||
|
||||
Dictionary<string, object> options = new Dictionary<string, object>();
|
||||
|
||||
//if (requestData.Contains("version"))
|
||||
//{
|
||||
// options["version"] = (string)requestData["version"];
|
||||
//}
|
||||
|
||||
if (requestData.Contains("profile"))
|
||||
{
|
||||
options["profile"] = (string)requestData["profile"];
|
||||
}
|
||||
|
||||
if (requestData["noassets"] == "true")
|
||||
{
|
||||
options["noassets"] = (string)requestData["noassets"] ;
|
||||
}
|
||||
|
||||
IRegionArchiverModule archiver = scene.RequestModuleInterface<IRegionArchiverModule>();
|
||||
|
||||
if (archiver != null)
|
||||
{
|
||||
scene.EventManager.OnOarFileSaved += RemoteAdminOarSaveCompleted;
|
||||
archiver.ArchiveRegion(filename, new Dictionary<string, object>());
|
||||
archiver.ArchiveRegion(filename, options);
|
||||
lock (m_saveOarLock) Monitor.Wait(m_saveOarLock,5000);
|
||||
scene.EventManager.OnOarFileSaved -= RemoteAdminOarSaveCompleted;
|
||||
}
|
||||
|
||||
@@ -488,11 +488,11 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
|
||||
rdata.userAppearance.AvatarHeight = (float) Convert.ToDouble(xml.Value);
|
||||
indata = true;
|
||||
}
|
||||
if (xml.MoveToAttribute("Owner"))
|
||||
{
|
||||
rdata.userAppearance.Owner = (UUID)xml.Value;
|
||||
indata = true;
|
||||
}
|
||||
// if (xml.MoveToAttribute("Owner"))
|
||||
// {
|
||||
// rdata.userAppearance.Owner = (UUID)xml.Value;
|
||||
// indata = true;
|
||||
// }
|
||||
if (xml.MoveToAttribute("Serial"))
|
||||
{
|
||||
rdata.userAppearance.Serial = Convert.ToInt32(xml.Value);
|
||||
@@ -747,8 +747,8 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
|
||||
rdata.writer.WriteStartElement("Appearance");
|
||||
|
||||
rdata.writer.WriteAttributeString("Height", rdata.userAppearance.AvatarHeight.ToString());
|
||||
if (rdata.userAppearance.Owner != UUID.Zero)
|
||||
rdata.writer.WriteAttributeString("Owner", rdata.userAppearance.Owner.ToString());
|
||||
// if (rdata.userAppearance.Owner != UUID.Zero)
|
||||
// rdata.writer.WriteAttributeString("Owner", rdata.userAppearance.Owner.ToString());
|
||||
rdata.writer.WriteAttributeString("Serial", rdata.userAppearance.Serial.ToString());
|
||||
|
||||
/*
|
||||
|
||||
@@ -168,8 +168,8 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory.Tests
|
||||
float x = Convert.ToSingle(rdata.Parameters[PARM_MOVE_X]);
|
||||
float y = Convert.ToSingle(rdata.Parameters[PARM_MOVE_Y]);
|
||||
float z = Convert.ToSingle(rdata.Parameters[PARM_MOVE_Z]);
|
||||
Vector3 vector = new Vector3(x,y,z);
|
||||
presence.DoAutoPilot(0,vector,presence.ControllingClient);
|
||||
Vector3 vector = new Vector3(x, y, z);
|
||||
presence.MoveToTarget(vector, false);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
||||
@@ -57,7 +57,6 @@ namespace OpenSim.Capabilities.Handlers
|
||||
|
||||
public Hashtable ProcessGetMesh(Hashtable request, UUID AgentId, Caps cap)
|
||||
{
|
||||
|
||||
Hashtable responsedata = new Hashtable();
|
||||
responsedata["int_response_code"] = 400; //501; //410; //404;
|
||||
responsedata["content_type"] = "text/plain";
|
||||
@@ -69,7 +68,6 @@ namespace OpenSim.Capabilities.Handlers
|
||||
if (request.ContainsKey("mesh_id"))
|
||||
meshStr = request["mesh_id"].ToString();
|
||||
|
||||
|
||||
UUID meshID = UUID.Zero;
|
||||
if (!String.IsNullOrEmpty(meshStr) && UUID.TryParse(meshStr, out meshID))
|
||||
{
|
||||
@@ -82,12 +80,11 @@ namespace OpenSim.Capabilities.Handlers
|
||||
return responsedata;
|
||||
}
|
||||
|
||||
AssetBase mesh;
|
||||
// Only try to fetch locally cached textures. Misses are redirected
|
||||
mesh = m_assetService.GetCached(meshID.ToString());
|
||||
AssetBase mesh = m_assetService.Get(meshID.ToString());
|
||||
|
||||
if (mesh != null)
|
||||
{
|
||||
if (mesh.Type == (SByte)AssetType.Mesh)
|
||||
if (mesh.Type == (SByte)AssetType.Mesh)
|
||||
{
|
||||
responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data);
|
||||
responsedata["content_type"] = "application/vnd.ll.mesh";
|
||||
@@ -105,39 +102,15 @@ namespace OpenSim.Capabilities.Handlers
|
||||
}
|
||||
else
|
||||
{
|
||||
mesh = m_assetService.Get(meshID.ToString());
|
||||
if (mesh != null)
|
||||
{
|
||||
if (mesh.Type == (SByte)AssetType.Mesh)
|
||||
{
|
||||
responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data);
|
||||
responsedata["content_type"] = "application/vnd.ll.mesh";
|
||||
responsedata["int_response_code"] = 200;
|
||||
}
|
||||
// Optionally add additional mesh types here
|
||||
else
|
||||
{
|
||||
responsedata["int_response_code"] = 404; //501; //410; //404;
|
||||
responsedata["content_type"] = "text/plain";
|
||||
responsedata["keepalive"] = false;
|
||||
responsedata["str_response_string"] = "Unfortunately, this asset isn't a mesh.";
|
||||
return responsedata;
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
responsedata["int_response_code"] = 404; //501; //410; //404;
|
||||
responsedata["content_type"] = "text/plain";
|
||||
responsedata["keepalive"] = false;
|
||||
responsedata["str_response_string"] = "Your Mesh wasn't found. Sorry!";
|
||||
return responsedata;
|
||||
}
|
||||
responsedata["int_response_code"] = 404; //501; //410; //404;
|
||||
responsedata["content_type"] = "text/plain";
|
||||
responsedata["keepalive"] = false;
|
||||
responsedata["str_response_string"] = "Your Mesh wasn't found. Sorry!";
|
||||
return responsedata;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return responsedata;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -47,7 +47,6 @@ using Caps = OpenSim.Framework.Capabilities.Caps;
|
||||
|
||||
namespace OpenSim.Capabilities.Handlers
|
||||
{
|
||||
|
||||
public class GetTextureHandler : BaseStreamHandler
|
||||
{
|
||||
private static readonly ILog m_log =
|
||||
@@ -67,7 +66,6 @@ namespace OpenSim.Capabilities.Handlers
|
||||
|
||||
public override byte[] Handle(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
|
||||
{
|
||||
|
||||
// Try to parse the texture ID from the request URL
|
||||
NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query);
|
||||
string textureStr = query.GetOne("texture_id");
|
||||
@@ -85,6 +83,8 @@ namespace OpenSim.Capabilities.Handlers
|
||||
UUID textureID;
|
||||
if (!String.IsNullOrEmpty(textureStr) && UUID.TryParse(textureStr, out textureID))
|
||||
{
|
||||
// m_log.DebugFormat("[GETTEXTURE]: Received request for texture id {0}", textureID);
|
||||
|
||||
string[] formats;
|
||||
if (format != null && format != string.Empty)
|
||||
{
|
||||
@@ -105,7 +105,6 @@ namespace OpenSim.Capabilities.Handlers
|
||||
if (FetchTexture(httpRequest, httpResponse, textureID, f))
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace OpenSim.Data
|
||||
{
|
||||
public class FriendsData
|
||||
{
|
||||
public UUID PrincipalID;
|
||||
public string PrincipalID;
|
||||
public string Friend;
|
||||
public Dictionary<string, string> Data;
|
||||
}
|
||||
@@ -46,6 +46,8 @@ namespace OpenSim.Data
|
||||
{
|
||||
bool Store(FriendsData data);
|
||||
bool Delete(UUID ownerID, string friend);
|
||||
bool Delete(string ownerID, string friend);
|
||||
FriendsData[] GetFriends(UUID principalID);
|
||||
FriendsData[] GetFriends(string principalID);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace OpenSim.Data.MSSQL
|
||||
{
|
||||
private const string _migrationStore = "EstateStore";
|
||||
|
||||
private static readonly ILog _Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private MSSQLManager _Database;
|
||||
private string m_connectionString;
|
||||
@@ -72,7 +72,12 @@ namespace OpenSim.Data.MSSQL
|
||||
}
|
||||
|
||||
//Migration settings
|
||||
_Database.CheckMigration(_migrationStore);
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
{
|
||||
conn.Open();
|
||||
Migration m = new Migration(conn, GetType().Assembly, "EstateStore");
|
||||
m.Update();
|
||||
}
|
||||
|
||||
//Interesting way to get parameters! Maybe implement that also with other types
|
||||
Type t = typeof(EstateSettings);
|
||||
@@ -112,19 +117,19 @@ namespace OpenSim.Data.MSSQL
|
||||
{
|
||||
FieldInfo f = _FieldMap[name];
|
||||
object v = reader[name];
|
||||
if (f.FieldType == typeof(bool) )
|
||||
if (f.FieldType == typeof(bool))
|
||||
{
|
||||
f.SetValue(es, Convert.ToInt32(v) != 0);
|
||||
}
|
||||
else if (f.FieldType == typeof(UUID) )
|
||||
else if (f.FieldType == typeof(UUID))
|
||||
{
|
||||
f.SetValue(es, new UUID((Guid)v)); // uuid);
|
||||
}
|
||||
else if (f.FieldType == typeof(string))
|
||||
else if (f.FieldType == typeof(string))
|
||||
{
|
||||
f.SetValue(es, v.ToString());
|
||||
}
|
||||
else if (f.FieldType == typeof(UInt32))
|
||||
else if (f.FieldType == typeof(UInt32))
|
||||
{
|
||||
f.SetValue(es, Convert.ToUInt32(v));
|
||||
}
|
||||
@@ -186,7 +191,7 @@ namespace OpenSim.Data.MSSQL
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_Log.DebugFormat("[ESTATE DB]: Error inserting regionID and EstateID in estate_map: {0}", e);
|
||||
m_log.DebugFormat("[ESTATE DB]: Error inserting regionID and EstateID in estate_map: {0}", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -310,12 +315,12 @@ namespace OpenSim.Data.MSSQL
|
||||
conn.Open();
|
||||
using (SqlCommand cmd = conn.CreateCommand())
|
||||
{
|
||||
cmd.CommandText = "delete from estateban where EstateID = @EstateID";
|
||||
cmd.CommandText = "delete from estateban where EstateID = @EstateID";
|
||||
cmd.Parameters.AddWithValue("@EstateID", (int)es.EstateID);
|
||||
cmd.ExecuteNonQuery();
|
||||
|
||||
//Insert after
|
||||
cmd.CommandText = "insert into estateban (EstateID, bannedUUID) values ( @EstateID, @bannedUUID )";
|
||||
cmd.CommandText = "insert into estateban (EstateID, bannedUUID,bannedIp, bannedIpHostMask, bannedNameMask) values ( @EstateID, @bannedUUID, '','','' )";
|
||||
cmd.Parameters.AddWithValue("@bannedUUID", Guid.Empty);
|
||||
foreach (EstateBan b in es.EstateBans)
|
||||
{
|
||||
@@ -350,43 +355,195 @@ namespace OpenSim.Data.MSSQL
|
||||
|
||||
public EstateSettings LoadEstateSettings(int estateID)
|
||||
{
|
||||
// TODO: Implementation!
|
||||
return new EstateSettings();
|
||||
EstateSettings es = new EstateSettings();
|
||||
string sql = "select estate_settings." + String.Join(",estate_settings.", FieldList) + " from estate_settings where EstateID = @EstateID";
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
{
|
||||
conn.Open();
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@EstateID", (int)estateID);
|
||||
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
if (reader.Read())
|
||||
{
|
||||
foreach (string name in FieldList)
|
||||
{
|
||||
FieldInfo f = _FieldMap[name];
|
||||
object v = reader[name];
|
||||
if (f.FieldType == typeof(bool))
|
||||
{
|
||||
f.SetValue(es, Convert.ToInt32(v) != 0);
|
||||
}
|
||||
else if (f.FieldType == typeof(UUID))
|
||||
{
|
||||
f.SetValue(es, new UUID((Guid)v)); // uuid);
|
||||
}
|
||||
else if (f.FieldType == typeof(string))
|
||||
{
|
||||
f.SetValue(es, v.ToString());
|
||||
}
|
||||
else if (f.FieldType == typeof(UInt32))
|
||||
{
|
||||
f.SetValue(es, Convert.ToUInt32(v));
|
||||
}
|
||||
else if (f.FieldType == typeof(Single))
|
||||
{
|
||||
f.SetValue(es, Convert.ToSingle(v));
|
||||
}
|
||||
else
|
||||
f.SetValue(es, v);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
LoadBanList(es);
|
||||
|
||||
es.EstateManagers = LoadUUIDList(es.EstateID, "estate_managers");
|
||||
es.EstateAccess = LoadUUIDList(es.EstateID, "estate_users");
|
||||
es.EstateGroups = LoadUUIDList(es.EstateID, "estate_groups");
|
||||
|
||||
//Set event
|
||||
es.OnSave += StoreEstateSettings;
|
||||
return es;
|
||||
|
||||
}
|
||||
|
||||
|
||||
public List<EstateSettings> LoadEstateSettingsAll()
|
||||
{
|
||||
// TODO: Implementation!
|
||||
return new List<EstateSettings>();
|
||||
List<EstateSettings> allEstateSettings = new List<EstateSettings>();
|
||||
|
||||
List<int> allEstateIds = GetEstatesAll();
|
||||
|
||||
foreach (int estateId in allEstateIds)
|
||||
allEstateSettings.Add(LoadEstateSettings(estateId));
|
||||
|
||||
return allEstateSettings;
|
||||
}
|
||||
|
||||
public List<int> GetEstates(string search)
|
||||
{
|
||||
// TODO: Implementation!
|
||||
return new List<int>();
|
||||
List<int> result = new List<int>();
|
||||
string sql = "select estateID from estate_settings where EstateName = @EstateName";
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
{
|
||||
conn.Open();
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@EstateName", search);
|
||||
|
||||
using (IDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
result.Add(Convert.ToInt32(reader["EstateID"]));
|
||||
}
|
||||
reader.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public List<int> GetEstatesAll()
|
||||
{
|
||||
// TODO: Implementation!
|
||||
return new List<int>();
|
||||
List<int> result = new List<int>();
|
||||
string sql = "select estateID from estate_settings";
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
{
|
||||
conn.Open();
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
using (IDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
result.Add(Convert.ToInt32(reader["EstateID"]));
|
||||
}
|
||||
reader.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public List<int> GetEstatesByOwner(UUID ownerID)
|
||||
{
|
||||
return new List<int>();
|
||||
List<int> result = new List<int>();
|
||||
string sql = "select estateID from estate_settings where EstateOwner = @EstateOwner";
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
{
|
||||
conn.Open();
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@EstateOwner", ownerID);
|
||||
|
||||
using (IDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
result.Add(Convert.ToInt32(reader["EstateID"]));
|
||||
}
|
||||
reader.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public bool LinkRegion(UUID regionID, int estateID)
|
||||
{
|
||||
// TODO: Implementation!
|
||||
string sql = "insert into estate_map values (@RegionID, @EstateID)";
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
{
|
||||
conn.Open();
|
||||
try
|
||||
{
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@RegionID", regionID);
|
||||
cmd.Parameters.AddWithValue("@EstateID", estateID);
|
||||
|
||||
int ret = cmd.ExecuteNonQuery();
|
||||
return (ret != 0);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
m_log.Error("[REGION DB]: LinkRegion failed: " + ex.Message);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public List<UUID> GetRegions(int estateID)
|
||||
{
|
||||
// TODO: Implementation!
|
||||
return new List<UUID>();
|
||||
List<UUID> result = new List<UUID>();
|
||||
string sql = "select RegionID from estate_map where EstateID = @EstateID";
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
{
|
||||
conn.Open();
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@EstateID", estateID);
|
||||
|
||||
using (IDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
result.Add(DBGuid.FromDB(reader["RegionID"]));
|
||||
}
|
||||
reader.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public bool DeleteEstate(int estateID)
|
||||
|
||||
@@ -51,6 +51,11 @@ namespace OpenSim.Data.MSSQL
|
||||
}
|
||||
|
||||
public bool Delete(UUID principalID, string friend)
|
||||
{
|
||||
return Delete(principalID.ToString(), friend);
|
||||
}
|
||||
|
||||
public bool Delete(string principalID, string friend)
|
||||
{
|
||||
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||
using (SqlCommand cmd = new SqlCommand())
|
||||
@@ -67,6 +72,11 @@ namespace OpenSim.Data.MSSQL
|
||||
}
|
||||
|
||||
public FriendsData[] GetFriends(UUID principalID)
|
||||
{
|
||||
return GetFriends(principalID.ToString());
|
||||
}
|
||||
|
||||
public FriendsData[] GetFriends(string principalID)
|
||||
{
|
||||
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||
using (SqlCommand cmd = new SqlCommand())
|
||||
|
||||
@@ -168,14 +168,13 @@ namespace OpenSim.Data.MSSQL
|
||||
|
||||
protected T[] DoQuery(SqlCommand cmd)
|
||||
{
|
||||
List<T> result = new List<T>();
|
||||
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
if (reader == null)
|
||||
return new T[0];
|
||||
|
||||
CheckColumnNames(reader);
|
||||
|
||||
List<T> result = new List<T>();
|
||||
CheckColumnNames(reader);
|
||||
|
||||
while (reader.Read())
|
||||
{
|
||||
@@ -262,6 +261,15 @@ namespace OpenSim.Data.MSSQL
|
||||
{
|
||||
names.Add(fi.Name);
|
||||
values.Add("@" + fi.Name);
|
||||
// Temporarily return more information about what field is unexpectedly null for
|
||||
// http://opensimulator.org/mantis/view.php?id=5403. This might be due to a bug in the
|
||||
// InventoryTransferModule or we may be required to substitute a DBNull here.
|
||||
if (fi.GetValue(row) == null)
|
||||
throw new NullReferenceException(
|
||||
string.Format(
|
||||
"[MSSQL GENERIC TABLE HANDLER]: Trying to store field {0} for {1} which is unexpectedly null",
|
||||
fi.Name, row));
|
||||
|
||||
if (constraintFields.Count > 0 && constraintFields.Contains(fi.Name))
|
||||
{
|
||||
constraints.Add(new KeyValuePair<string, string>(fi.Name, fi.GetValue(row).ToString()));
|
||||
@@ -358,12 +366,18 @@ namespace OpenSim.Data.MSSQL
|
||||
|
||||
string where = String.Join(" AND ", terms.ToArray());
|
||||
|
||||
string query = String.Format("DELETE * FROM {0} WHERE {1}", m_Realm, where);
|
||||
string query = String.Format("DELETE FROM {0} WHERE {1}", m_Realm, where);
|
||||
|
||||
cmd.Connection = conn;
|
||||
cmd.CommandText = query;
|
||||
conn.Open();
|
||||
return cmd.ExecuteNonQuery() > 0;
|
||||
|
||||
if (cmd.ExecuteNonQuery() > 0)
|
||||
{
|
||||
//m_log.Warn("[MSSQLGenericTable]: " + deleteCommand);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,16 +29,19 @@ using System;
|
||||
using System.Data;
|
||||
using System.Data.Common;
|
||||
using System.Reflection;
|
||||
using System.Data.SqlClient;
|
||||
|
||||
namespace OpenSim.Data.MSSQL
|
||||
{
|
||||
public class MSSQLMigration : Migration
|
||||
{
|
||||
public MSSQLMigration(DbConnection conn, Assembly assem, string type) : base(conn, assem, type)
|
||||
public MSSQLMigration(DbConnection conn, Assembly assem, string type)
|
||||
: base(conn, assem, type)
|
||||
{
|
||||
}
|
||||
|
||||
public MSSQLMigration(DbConnection conn, Assembly assem, string subtype, string type) : base(conn, assem, subtype, type)
|
||||
public MSSQLMigration(DbConnection conn, Assembly assem, string subtype, string type)
|
||||
: base(conn, assem, subtype, type)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -67,5 +70,30 @@ namespace OpenSim.Data.MSSQL
|
||||
}
|
||||
return version;
|
||||
}
|
||||
|
||||
protected override void ExecuteScript(DbConnection conn, string[] script)
|
||||
{
|
||||
if (!(conn is SqlConnection))
|
||||
{
|
||||
base.ExecuteScript(conn, script);
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (string sql in script)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (SqlCommand cmd = new SqlCommand(sql, (SqlConnection)conn))
|
||||
{
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw new Exception(sql);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,6 +70,7 @@ namespace OpenSim.Data.MSSQL
|
||||
string sql = "select * from ["+m_Realm+"] where regionName like @regionName";
|
||||
if (scopeID != UUID.Zero)
|
||||
sql += " and ScopeID = @scopeID";
|
||||
sql += " order by regionName";
|
||||
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
|
||||
@@ -55,6 +55,10 @@ namespace OpenSim.Data.MSSQL
|
||||
/// </summary>
|
||||
private MSSQLManager _Database;
|
||||
private string m_connectionString;
|
||||
protected virtual Assembly Assembly
|
||||
{
|
||||
get { return GetType().Assembly; }
|
||||
}
|
||||
|
||||
public MSSQLSimulationData()
|
||||
{
|
||||
@@ -74,9 +78,13 @@ namespace OpenSim.Data.MSSQL
|
||||
m_connectionString = connectionString;
|
||||
_Database = new MSSQLManager(connectionString);
|
||||
|
||||
|
||||
//Migration settings
|
||||
_Database.CheckMigration(_migrationStore);
|
||||
using (SqlConnection conn = new SqlConnection(connectionString))
|
||||
{
|
||||
conn.Open();
|
||||
//New Migration settings
|
||||
Migration m = new Migration(conn, Assembly, "RegionStore");
|
||||
m.Update();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -214,7 +222,7 @@ namespace OpenSim.Data.MSSQL
|
||||
{
|
||||
command.Parameters.Clear();
|
||||
command.Parameters.Add(_Database.CreateParameter("@PrimID", objectPart.UUID));
|
||||
|
||||
|
||||
List<TaskInventoryItem> inventory = new List<TaskInventoryItem>();
|
||||
|
||||
using (SqlDataReader reader = command.ExecuteReader())
|
||||
@@ -241,6 +249,14 @@ namespace OpenSim.Data.MSSQL
|
||||
/// <param name="regionUUID"></param>
|
||||
public void StoreObject(SceneObjectGroup obj, UUID regionUUID)
|
||||
{
|
||||
uint flags = obj.RootPart.GetEffectiveObjectFlags();
|
||||
// Eligibility check
|
||||
//
|
||||
if ((flags & (uint)PrimFlags.Temporary) != 0)
|
||||
return;
|
||||
if ((flags & (uint)PrimFlags.TemporaryOnRez) != 0)
|
||||
return;
|
||||
|
||||
_Log.DebugFormat("[MSSQL]: Adding/Changing SceneObjectGroup: {0} to region: {1}, object has {2} prims.", obj.UUID, regionUUID, obj.Parts.Length);
|
||||
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
@@ -700,16 +716,470 @@ VALUES
|
||||
}
|
||||
public RegionLightShareData LoadRegionWindlightSettings(UUID regionUUID)
|
||||
{
|
||||
//This connector doesn't support the windlight module yet
|
||||
//Return default LL windlight settings
|
||||
return new RegionLightShareData();
|
||||
RegionLightShareData nWP = new RegionLightShareData();
|
||||
nWP.OnSave += StoreRegionWindlightSettings;
|
||||
string sql = "select * from [regionwindlight] where region_id = @regionID";
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.Add(_Database.CreateParameter("@regionID", regionUUID));
|
||||
conn.Open();
|
||||
using (SqlDataReader result = cmd.ExecuteReader())
|
||||
{
|
||||
if (!result.Read())
|
||||
{
|
||||
//No result, so store our default windlight profile and return it
|
||||
nWP.regionID = regionUUID;
|
||||
StoreRegionWindlightSettings(nWP);
|
||||
return nWP;
|
||||
}
|
||||
else
|
||||
{
|
||||
nWP.regionID = DBGuid.FromDB(result["region_id"]);
|
||||
nWP.waterColor.X = Convert.ToSingle(result["water_color_r"]);
|
||||
nWP.waterColor.Y = Convert.ToSingle(result["water_color_g"]);
|
||||
nWP.waterColor.Z = Convert.ToSingle(result["water_color_b"]);
|
||||
nWP.waterFogDensityExponent = Convert.ToSingle(result["water_fog_density_exponent"]);
|
||||
nWP.underwaterFogModifier = Convert.ToSingle(result["underwater_fog_modifier"]);
|
||||
nWP.reflectionWaveletScale.X = Convert.ToSingle(result["reflection_wavelet_scale_1"]);
|
||||
nWP.reflectionWaveletScale.Y = Convert.ToSingle(result["reflection_wavelet_scale_2"]);
|
||||
nWP.reflectionWaveletScale.Z = Convert.ToSingle(result["reflection_wavelet_scale_3"]);
|
||||
nWP.fresnelScale = Convert.ToSingle(result["fresnel_scale"]);
|
||||
nWP.fresnelOffset = Convert.ToSingle(result["fresnel_offset"]);
|
||||
nWP.refractScaleAbove = Convert.ToSingle(result["refract_scale_above"]);
|
||||
nWP.refractScaleBelow = Convert.ToSingle(result["refract_scale_below"]);
|
||||
nWP.blurMultiplier = Convert.ToSingle(result["blur_multiplier"]);
|
||||
nWP.bigWaveDirection.X = Convert.ToSingle(result["big_wave_direction_x"]);
|
||||
nWP.bigWaveDirection.Y = Convert.ToSingle(result["big_wave_direction_y"]);
|
||||
nWP.littleWaveDirection.X = Convert.ToSingle(result["little_wave_direction_x"]);
|
||||
nWP.littleWaveDirection.Y = Convert.ToSingle(result["little_wave_direction_y"]);
|
||||
UUID.TryParse(result["normal_map_texture"].ToString(), out nWP.normalMapTexture);
|
||||
nWP.horizon.X = Convert.ToSingle(result["horizon_r"]);
|
||||
nWP.horizon.Y = Convert.ToSingle(result["horizon_g"]);
|
||||
nWP.horizon.Z = Convert.ToSingle(result["horizon_b"]);
|
||||
nWP.horizon.W = Convert.ToSingle(result["horizon_i"]);
|
||||
nWP.hazeHorizon = Convert.ToSingle(result["haze_horizon"]);
|
||||
nWP.blueDensity.X = Convert.ToSingle(result["blue_density_r"]);
|
||||
nWP.blueDensity.Y = Convert.ToSingle(result["blue_density_g"]);
|
||||
nWP.blueDensity.Z = Convert.ToSingle(result["blue_density_b"]);
|
||||
nWP.blueDensity.W = Convert.ToSingle(result["blue_density_i"]);
|
||||
nWP.hazeDensity = Convert.ToSingle(result["haze_density"]);
|
||||
nWP.densityMultiplier = Convert.ToSingle(result["density_multiplier"]);
|
||||
nWP.distanceMultiplier = Convert.ToSingle(result["distance_multiplier"]);
|
||||
nWP.maxAltitude = Convert.ToUInt16(result["max_altitude"]);
|
||||
nWP.sunMoonColor.X = Convert.ToSingle(result["sun_moon_color_r"]);
|
||||
nWP.sunMoonColor.Y = Convert.ToSingle(result["sun_moon_color_g"]);
|
||||
nWP.sunMoonColor.Z = Convert.ToSingle(result["sun_moon_color_b"]);
|
||||
nWP.sunMoonColor.W = Convert.ToSingle(result["sun_moon_color_i"]);
|
||||
nWP.sunMoonPosition = Convert.ToSingle(result["sun_moon_position"]);
|
||||
nWP.ambient.X = Convert.ToSingle(result["ambient_r"]);
|
||||
nWP.ambient.Y = Convert.ToSingle(result["ambient_g"]);
|
||||
nWP.ambient.Z = Convert.ToSingle(result["ambient_b"]);
|
||||
nWP.ambient.W = Convert.ToSingle(result["ambient_i"]);
|
||||
nWP.eastAngle = Convert.ToSingle(result["east_angle"]);
|
||||
nWP.sunGlowFocus = Convert.ToSingle(result["sun_glow_focus"]);
|
||||
nWP.sunGlowSize = Convert.ToSingle(result["sun_glow_size"]);
|
||||
nWP.sceneGamma = Convert.ToSingle(result["scene_gamma"]);
|
||||
nWP.starBrightness = Convert.ToSingle(result["star_brightness"]);
|
||||
nWP.cloudColor.X = Convert.ToSingle(result["cloud_color_r"]);
|
||||
nWP.cloudColor.Y = Convert.ToSingle(result["cloud_color_g"]);
|
||||
nWP.cloudColor.Z = Convert.ToSingle(result["cloud_color_b"]);
|
||||
nWP.cloudColor.W = Convert.ToSingle(result["cloud_color_i"]);
|
||||
nWP.cloudXYDensity.X = Convert.ToSingle(result["cloud_x"]);
|
||||
nWP.cloudXYDensity.Y = Convert.ToSingle(result["cloud_y"]);
|
||||
nWP.cloudXYDensity.Z = Convert.ToSingle(result["cloud_density"]);
|
||||
nWP.cloudCoverage = Convert.ToSingle(result["cloud_coverage"]);
|
||||
nWP.cloudScale = Convert.ToSingle(result["cloud_scale"]);
|
||||
nWP.cloudDetailXYDensity.X = Convert.ToSingle(result["cloud_detail_x"]);
|
||||
nWP.cloudDetailXYDensity.Y = Convert.ToSingle(result["cloud_detail_y"]);
|
||||
nWP.cloudDetailXYDensity.Z = Convert.ToSingle(result["cloud_detail_density"]);
|
||||
nWP.cloudScrollX = Convert.ToSingle(result["cloud_scroll_x"]);
|
||||
nWP.cloudScrollXLock = Convert.ToBoolean(result["cloud_scroll_x_lock"]);
|
||||
nWP.cloudScrollY = Convert.ToSingle(result["cloud_scroll_y"]);
|
||||
nWP.cloudScrollYLock = Convert.ToBoolean(result["cloud_scroll_y_lock"]);
|
||||
nWP.drawClassicClouds = Convert.ToBoolean(result["draw_classic_clouds"]);
|
||||
nWP.valid = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nWP;
|
||||
}
|
||||
|
||||
public void RemoveRegionWindlightSettings(UUID regionID)
|
||||
{
|
||||
string sql = "delete from [regionwindlight] where region_id = @region_id";
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
conn.Open();
|
||||
cmd.Parameters.Add(_Database.CreateParameter("@region_id", regionID));
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
|
||||
public void StoreRegionWindlightSettings(RegionLightShareData wl)
|
||||
{
|
||||
//This connector doesn't support the windlight module yet
|
||||
string sql = "select count (region_id) from regionwindlight where region_id = @region_id";
|
||||
bool exists = false;
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
{
|
||||
conn.Open();
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.Add(_Database.CreateParameter("@region_id", wl.regionID));
|
||||
exists = (int)cmd.ExecuteScalar() > 0;
|
||||
}
|
||||
}
|
||||
if (exists)
|
||||
{
|
||||
RemoveRegionWindlightSettings(wl.regionID);
|
||||
}
|
||||
|
||||
// sql insert
|
||||
sql = @"INSERT INTO [regionwindlight]
|
||||
([region_id]
|
||||
,[water_color_r]
|
||||
,[water_color_g]
|
||||
,[water_color_b]
|
||||
,[water_fog_density_exponent]
|
||||
,[underwater_fog_modifier]
|
||||
,[reflection_wavelet_scale_1]
|
||||
,[reflection_wavelet_scale_2]
|
||||
,[reflection_wavelet_scale_3]
|
||||
,[fresnel_scale]
|
||||
,[fresnel_offset]
|
||||
,[refract_scale_above]
|
||||
,[refract_scale_below]
|
||||
,[blur_multiplier]
|
||||
,[big_wave_direction_x]
|
||||
,[big_wave_direction_y]
|
||||
,[little_wave_direction_x]
|
||||
,[little_wave_direction_y]
|
||||
,[normal_map_texture]
|
||||
,[horizon_r]
|
||||
,[horizon_g]
|
||||
,[horizon_b]
|
||||
,[horizon_i]
|
||||
,[haze_horizon]
|
||||
,[blue_density_r]
|
||||
,[blue_density_g]
|
||||
,[blue_density_b]
|
||||
,[blue_density_i]
|
||||
,[haze_density]
|
||||
,[density_multiplier]
|
||||
,[distance_multiplier]
|
||||
,[max_altitude]
|
||||
,[sun_moon_color_r]
|
||||
,[sun_moon_color_g]
|
||||
,[sun_moon_color_b]
|
||||
,[sun_moon_color_i]
|
||||
,[sun_moon_position]
|
||||
,[ambient_r]
|
||||
,[ambient_g]
|
||||
,[ambient_b]
|
||||
,[ambient_i]
|
||||
,[east_angle]
|
||||
,[sun_glow_focus]
|
||||
,[sun_glow_size]
|
||||
,[scene_gamma]
|
||||
,[star_brightness]
|
||||
,[cloud_color_r]
|
||||
,[cloud_color_g]
|
||||
,[cloud_color_b]
|
||||
,[cloud_color_i]
|
||||
,[cloud_x]
|
||||
,[cloud_y]
|
||||
,[cloud_density]
|
||||
,[cloud_coverage]
|
||||
,[cloud_scale]
|
||||
,[cloud_detail_x]
|
||||
,[cloud_detail_y]
|
||||
,[cloud_detail_density]
|
||||
,[cloud_scroll_x]
|
||||
,[cloud_scroll_x_lock]
|
||||
,[cloud_scroll_y]
|
||||
,[cloud_scroll_y_lock]
|
||||
,[draw_classic_clouds])
|
||||
VALUES
|
||||
(@region_id
|
||||
,@water_color_r
|
||||
,@water_color_g
|
||||
,@water_color_b
|
||||
,@water_fog_density_exponent
|
||||
,@underwater_fog_modifier
|
||||
,@reflection_wavelet_scale_1
|
||||
,@reflection_wavelet_scale_2
|
||||
,@reflection_wavelet_scale_3
|
||||
,@fresnel_scale
|
||||
,@fresnel_offset
|
||||
,@refract_scale_above
|
||||
,@refract_scale_below
|
||||
,@blur_multiplier
|
||||
,@big_wave_direction_x
|
||||
,@big_wave_direction_y
|
||||
,@little_wave_direction_x
|
||||
,@little_wave_direction_y
|
||||
,@normal_map_texture
|
||||
,@horizon_r
|
||||
,@horizon_g
|
||||
,@horizon_b
|
||||
,@horizon_i
|
||||
,@haze_horizon
|
||||
,@blue_density_r
|
||||
,@blue_density_g
|
||||
,@blue_density_b
|
||||
,@blue_density_i
|
||||
,@haze_density
|
||||
,@density_multiplier
|
||||
,@distance_multiplier
|
||||
,@max_altitude
|
||||
,@sun_moon_color_r
|
||||
,@sun_moon_color_g
|
||||
,@sun_moon_color_b
|
||||
,@sun_moon_color_i
|
||||
,@sun_moon_position
|
||||
,@ambient_r
|
||||
,@ambient_g
|
||||
,@ambient_b
|
||||
,@ambient_i
|
||||
,@east_angle
|
||||
,@sun_glow_focus
|
||||
,@sun_glow_size
|
||||
,@scene_gamma
|
||||
,@star_brightness
|
||||
,@cloud_color_r
|
||||
,@cloud_color_g
|
||||
,@cloud_color_b
|
||||
,@cloud_color_i
|
||||
,@cloud_x
|
||||
,@cloud_y
|
||||
,@cloud_density
|
||||
,@cloud_coverage
|
||||
,@cloud_scale
|
||||
,@cloud_detail_x
|
||||
,@cloud_detail_y
|
||||
,@cloud_detail_density
|
||||
,@cloud_scroll_x
|
||||
,@cloud_scroll_x_lock
|
||||
,@cloud_scroll_y
|
||||
,@cloud_scroll_y_lock
|
||||
,@draw_classic_clouds)";
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
{
|
||||
conn.Open();
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.Add(_Database.CreateParameter("region_id", wl.regionID));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("water_color_r", wl.waterColor.X));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("water_color_g", wl.waterColor.Y));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("water_color_b", wl.waterColor.Z));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("water_fog_density_exponent", wl.waterFogDensityExponent));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("underwater_fog_modifier", wl.underwaterFogModifier));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("reflection_wavelet_scale_1", wl.reflectionWaveletScale.X));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("reflection_wavelet_scale_2", wl.reflectionWaveletScale.Y));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("reflection_wavelet_scale_3", wl.reflectionWaveletScale.Z));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("fresnel_scale", wl.fresnelScale));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("fresnel_offset", wl.fresnelOffset));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("refract_scale_above", wl.refractScaleAbove));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("refract_scale_below", wl.refractScaleBelow));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("blur_multiplier", wl.blurMultiplier));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("big_wave_direction_x", wl.bigWaveDirection.X));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("big_wave_direction_y", wl.bigWaveDirection.Y));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("little_wave_direction_x", wl.littleWaveDirection.X));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("little_wave_direction_y", wl.littleWaveDirection.Y));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("normal_map_texture", wl.normalMapTexture));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("horizon_r", wl.horizon.X));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("horizon_g", wl.horizon.Y));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("horizon_b", wl.horizon.Z));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("horizon_i", wl.horizon.W));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("haze_horizon", wl.hazeHorizon));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("blue_density_r", wl.blueDensity.X));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("blue_density_g", wl.blueDensity.Y));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("blue_density_b", wl.blueDensity.Z));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("blue_density_i", wl.blueDensity.W));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("haze_density", wl.hazeDensity));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("density_multiplier", wl.densityMultiplier));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("distance_multiplier", wl.distanceMultiplier));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("max_altitude", wl.maxAltitude));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("sun_moon_color_r", wl.sunMoonColor.X));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("sun_moon_color_g", wl.sunMoonColor.Y));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("sun_moon_color_b", wl.sunMoonColor.Z));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("sun_moon_color_i", wl.sunMoonColor.W));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("sun_moon_position", wl.sunMoonPosition));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("ambient_r", wl.ambient.X));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("ambient_g", wl.ambient.Y));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("ambient_b", wl.ambient.Z));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("ambient_i", wl.ambient.W));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("east_angle", wl.eastAngle));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("sun_glow_focus", wl.sunGlowFocus));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("sun_glow_size", wl.sunGlowSize));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("scene_gamma", wl.sceneGamma));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("star_brightness", wl.starBrightness));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("cloud_color_r", wl.cloudColor.X));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("cloud_color_g", wl.cloudColor.Y));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("cloud_color_b", wl.cloudColor.Z));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("cloud_color_i", wl.cloudColor.W));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("cloud_x", wl.cloudXYDensity.X));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("cloud_y", wl.cloudXYDensity.Y));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("cloud_density", wl.cloudXYDensity.Z));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("cloud_coverage", wl.cloudCoverage));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("cloud_scale", wl.cloudScale));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("cloud_detail_x", wl.cloudDetailXYDensity.X));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("cloud_detail_y", wl.cloudDetailXYDensity.Y));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("cloud_detail_density", wl.cloudDetailXYDensity.Z));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("cloud_scroll_x", wl.cloudScrollX));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("cloud_scroll_x_lock", wl.cloudScrollXLock));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("cloud_scroll_y", wl.cloudScrollY));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("cloud_scroll_y_lock", wl.cloudScrollYLock));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("draw_classic_clouds", wl.drawClassicClouds));
|
||||
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
#region update
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// // sql update
|
||||
// sql = @"UPDATE [OpenSim].[dbo].[regionwindlight]
|
||||
// SET [region_id] = @region_id
|
||||
// ,[water_color_r] = @water_color_r
|
||||
// ,[water_color_g] = @water_color_g
|
||||
// ,[water_color_b] = @water_color_b
|
||||
// ,[water_fog_density_exponent] = @water_fog_density_exponent
|
||||
// ,[underwater_fog_modifier] = @underwater_fog_modifier
|
||||
// ,[reflection_wavelet_scale_1] = @reflection_wavelet_scale_1
|
||||
// ,[reflection_wavelet_scale_2] = @reflection_wavelet_scale_2
|
||||
// ,[reflection_wavelet_scale_3] = @reflection_wavelet_scale_3
|
||||
// ,[fresnel_scale] = @fresnel_scale
|
||||
// ,[fresnel_offset] = @fresnel_offset
|
||||
// ,[refract_scale_above] = @refract_scale_above
|
||||
// ,[refract_scale_below] = @refract_scale_below
|
||||
// ,[blur_multiplier] = @blur_multiplier
|
||||
// ,[big_wave_direction_x] = @big_wave_direction_x
|
||||
// ,[big_wave_direction_y] = @big_wave_direction_y
|
||||
// ,[little_wave_direction_x] = @little_wave_direction_x
|
||||
// ,[little_wave_direction_y] = @little_wave_direction_y
|
||||
// ,[normal_map_texture] = @normal_map_texture
|
||||
// ,[horizon_r] = @horizon_r
|
||||
// ,[horizon_g] = @horizon_g
|
||||
// ,[horizon_b] = @horizon_b
|
||||
// ,[horizon_i] = @horizon_i
|
||||
// ,[haze_horizon] = @haze_horizon
|
||||
// ,[blue_density_r] = @blue_density_r
|
||||
// ,[blue_density_g] = @blue_density_g
|
||||
// ,[blue_density_b] = @blue_density_b
|
||||
// ,[blue_density_i] = @blue_density_i
|
||||
// ,[haze_density] = @haze_density
|
||||
// ,[density_multiplier] = @density_multiplier
|
||||
// ,[distance_multiplier] = @distance_multiplier
|
||||
// ,[max_altitude] = @max_altitude
|
||||
// ,[sun_moon_color_r] = @sun_moon_color_r
|
||||
// ,[sun_moon_color_g] = @sun_moon_color_g
|
||||
// ,[sun_moon_color_b] = @sun_moon_color_b
|
||||
// ,[sun_moon_color_i] = @sun_moon_color_i
|
||||
// ,[sun_moon_position] = @sun_moon_position
|
||||
// ,[ambient_r] = @ambient_r
|
||||
// ,[ambient_g] = @ambient_g
|
||||
// ,[ambient_b] = @ambient_b
|
||||
// ,[ambient_i] = @ambient_i
|
||||
// ,[east_angle] = @east_angle
|
||||
// ,[sun_glow_focus] = @sun_glow_focus
|
||||
// ,[sun_glow_size] = @sun_glow_size
|
||||
// ,[scene_gamma] = @scene_gamma
|
||||
// ,[star_brightness] = @star_brightness
|
||||
// ,[cloud_color_r] = @cloud_color_r
|
||||
// ,[cloud_color_g] = @cloud_color_g
|
||||
// ,[cloud_color_b] = @cloud_color_b
|
||||
// ,[cloud_color_i] = @cloud_color_i
|
||||
// ,[cloud_x] = @cloud_x
|
||||
// ,[cloud_y] = @cloud_y
|
||||
// ,[cloud_density] = @cloud_density
|
||||
// ,[cloud_coverage] = @cloud_coverage
|
||||
// ,[cloud_scale] = @cloud_scale
|
||||
// ,[cloud_detail_x] = @cloud_detail_x
|
||||
// ,[cloud_detail_y] = @cloud_detail_y
|
||||
// ,[cloud_detail_density] = @cloud_detail_density
|
||||
// ,[cloud_scroll_x] = @cloud_scroll_x
|
||||
// ,[cloud_scroll_x_lock] = @cloud_scroll_x_lock
|
||||
// ,[cloud_scroll_y] = @cloud_scroll_y
|
||||
// ,[cloud_scroll_y_lock] = @cloud_scroll_y_lock
|
||||
// ,[draw_classic_clouds] = @draw_classic_clouds
|
||||
// WHERE region_id = @region_id";
|
||||
// using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
// {
|
||||
// conn.Open();
|
||||
// using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
// {
|
||||
// cmd.Parameters.AddWithValue("region_id", wl.regionID);
|
||||
// cmd.Parameters.AddWithValue("water_color_r", wl.waterColor.X);
|
||||
// cmd.Parameters.AddWithValue("water_color_g", wl.waterColor.Y);
|
||||
// cmd.Parameters.AddWithValue("water_color_b", wl.waterColor.Z);
|
||||
// cmd.Parameters.AddWithValue("water_fog_density_exponent", wl.waterFogDensityExponent);
|
||||
// cmd.Parameters.AddWithValue("underwater_fog_modifier", wl.underwaterFogModifier);
|
||||
// cmd.Parameters.AddWithValue("reflection_wavelet_scale_1", wl.reflectionWaveletScale.X);
|
||||
// cmd.Parameters.AddWithValue("reflection_wavelet_scale_2", wl.reflectionWaveletScale.Y);
|
||||
// cmd.Parameters.AddWithValue("reflection_wavelet_scale_3", wl.reflectionWaveletScale.Z);
|
||||
// cmd.Parameters.AddWithValue("fresnel_scale", wl.fresnelScale);
|
||||
// cmd.Parameters.AddWithValue("fresnel_offset", wl.fresnelOffset);
|
||||
// cmd.Parameters.AddWithValue("refract_scale_above", wl.refractScaleAbove);
|
||||
// cmd.Parameters.AddWithValue("refract_scale_below", wl.refractScaleBelow);
|
||||
// cmd.Parameters.AddWithValue("blur_multiplier", wl.blurMultiplier);
|
||||
// cmd.Parameters.AddWithValue("big_wave_direction_x", wl.bigWaveDirection.X);
|
||||
// cmd.Parameters.AddWithValue("big_wave_direction_y", wl.bigWaveDirection.Y);
|
||||
// cmd.Parameters.AddWithValue("little_wave_direction_x", wl.littleWaveDirection.X);
|
||||
// cmd.Parameters.AddWithValue("little_wave_direction_y", wl.littleWaveDirection.Y);
|
||||
// cmd.Parameters.AddWithValue("normal_map_texture", wl.normalMapTexture);
|
||||
// cmd.Parameters.AddWithValue("horizon_r", wl.horizon.X);
|
||||
// cmd.Parameters.AddWithValue("horizon_g", wl.horizon.Y);
|
||||
// cmd.Parameters.AddWithValue("horizon_b", wl.horizon.Z);
|
||||
// cmd.Parameters.AddWithValue("horizon_i", wl.horizon.W);
|
||||
// cmd.Parameters.AddWithValue("haze_horizon", wl.hazeHorizon);
|
||||
// cmd.Parameters.AddWithValue("blue_density_r", wl.blueDensity.X);
|
||||
// cmd.Parameters.AddWithValue("blue_density_g", wl.blueDensity.Y);
|
||||
// cmd.Parameters.AddWithValue("blue_density_b", wl.blueDensity.Z);
|
||||
// cmd.Parameters.AddWithValue("blue_density_i", wl.blueDensity.W);
|
||||
// cmd.Parameters.AddWithValue("haze_density", wl.hazeDensity);
|
||||
// cmd.Parameters.AddWithValue("density_multiplier", wl.densityMultiplier);
|
||||
// cmd.Parameters.AddWithValue("distance_multiplier", wl.distanceMultiplier);
|
||||
// cmd.Parameters.AddWithValue("max_altitude", wl.maxAltitude);
|
||||
// cmd.Parameters.AddWithValue("sun_moon_color_r", wl.sunMoonColor.X);
|
||||
// cmd.Parameters.AddWithValue("sun_moon_color_g", wl.sunMoonColor.Y);
|
||||
// cmd.Parameters.AddWithValue("sun_moon_color_b", wl.sunMoonColor.Z);
|
||||
// cmd.Parameters.AddWithValue("sun_moon_color_i", wl.sunMoonColor.W);
|
||||
// cmd.Parameters.AddWithValue("sun_moon_position", wl.sunMoonPosition);
|
||||
// cmd.Parameters.AddWithValue("ambient_r", wl.ambient.X);
|
||||
// cmd.Parameters.AddWithValue("ambient_g", wl.ambient.Y);
|
||||
// cmd.Parameters.AddWithValue("ambient_b", wl.ambient.Z);
|
||||
// cmd.Parameters.AddWithValue("ambient_i", wl.ambient.W);
|
||||
// cmd.Parameters.AddWithValue("east_angle", wl.eastAngle);
|
||||
// cmd.Parameters.AddWithValue("sun_glow_focus", wl.sunGlowFocus);
|
||||
// cmd.Parameters.AddWithValue("sun_glow_size", wl.sunGlowSize);
|
||||
// cmd.Parameters.AddWithValue("scene_gamma", wl.sceneGamma);
|
||||
// cmd.Parameters.AddWithValue("star_brightness", wl.starBrightness);
|
||||
// cmd.Parameters.AddWithValue("cloud_color_r", wl.cloudColor.X);
|
||||
// cmd.Parameters.AddWithValue("cloud_color_g", wl.cloudColor.Y);
|
||||
// cmd.Parameters.AddWithValue("cloud_color_b", wl.cloudColor.Z);
|
||||
// cmd.Parameters.AddWithValue("cloud_color_i", wl.cloudColor.W);
|
||||
// cmd.Parameters.AddWithValue("cloud_x", wl.cloudXYDensity.X);
|
||||
// cmd.Parameters.AddWithValue("cloud_y", wl.cloudXYDensity.Y);
|
||||
// cmd.Parameters.AddWithValue("cloud_density", wl.cloudXYDensity.Z);
|
||||
// cmd.Parameters.AddWithValue("cloud_coverage", wl.cloudCoverage);
|
||||
// cmd.Parameters.AddWithValue("cloud_scale", wl.cloudScale);
|
||||
// cmd.Parameters.AddWithValue("cloud_detail_x", wl.cloudDetailXYDensity.X);
|
||||
// cmd.Parameters.AddWithValue("cloud_detail_y", wl.cloudDetailXYDensity.Y);
|
||||
// cmd.Parameters.AddWithValue("cloud_detail_density", wl.cloudDetailXYDensity.Z);
|
||||
// cmd.Parameters.AddWithValue("cloud_scroll_x", wl.cloudScrollX);
|
||||
// cmd.Parameters.AddWithValue("cloud_scroll_x_lock", wl.cloudScrollXLock);
|
||||
// cmd.Parameters.AddWithValue("cloud_scroll_y", wl.cloudScrollY);
|
||||
// cmd.Parameters.AddWithValue("cloud_scroll_y_lock", wl.cloudScrollYLock);
|
||||
// cmd.Parameters.AddWithValue("draw_classic_clouds", wl.drawClassicClouds);
|
||||
|
||||
// cmd.ExecuteNonQuery();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
#endregion
|
||||
}
|
||||
/// <summary>
|
||||
/// Loads the settings of a region.
|
||||
@@ -1136,7 +1606,7 @@ VALUES
|
||||
if (Convert.ToInt16(primRow["PassTouches"]) != 0)
|
||||
prim.PassTouches = true;
|
||||
prim.LinkNum = Convert.ToInt32(primRow["LinkNumber"]);
|
||||
|
||||
|
||||
if (!(primRow["MediaURL"] is System.DBNull))
|
||||
prim.MediaUrl = (string)primRow["MediaURL"];
|
||||
|
||||
@@ -1192,11 +1662,11 @@ VALUES
|
||||
{
|
||||
}
|
||||
|
||||
if (!(shapeRow["Media"] is System.DBNull) )
|
||||
if (!(shapeRow["Media"] is System.DBNull))
|
||||
{
|
||||
baseShape.Media = PrimitiveBaseShape.MediaList.FromXml((string)shapeRow["Media"]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
return baseShape;
|
||||
}
|
||||
@@ -1576,15 +2046,15 @@ VALUES
|
||||
parameters.Add(_Database.CreateParameter("ExtraParams", s.ExtraParams));
|
||||
parameters.Add(_Database.CreateParameter("State", s.State));
|
||||
|
||||
if(null == s.Media )
|
||||
if (null == s.Media)
|
||||
{
|
||||
parameters.Add(_Database.CreateParameter("Media", DBNull.Value));
|
||||
parameters.Add(_Database.CreateParameter("Media", DBNull.Value));
|
||||
}
|
||||
else
|
||||
{
|
||||
parameters.Add(_Database.CreateParameter("Media", s.Media.ToXml()));
|
||||
parameters.Add(_Database.CreateParameter("Media", s.Media.ToXml()));
|
||||
}
|
||||
|
||||
|
||||
|
||||
return parameters.ToArray();
|
||||
}
|
||||
|
||||
@@ -66,11 +66,18 @@ namespace OpenSim.Data.MSSQL
|
||||
|
||||
public bool StoreFolder(XInventoryFolder folder)
|
||||
{
|
||||
if (folder.folderName.Length > 64)
|
||||
folder.folderName = folder.folderName.Substring(0, 64);
|
||||
return m_Folders.Store(folder);
|
||||
}
|
||||
|
||||
public bool StoreItem(XInventoryItem item)
|
||||
{
|
||||
if (item.inventoryName.Length > 64)
|
||||
item.inventoryName = item.inventoryName.Substring(0, 64);
|
||||
if (item.inventoryDescription.Length > 128)
|
||||
item.inventoryDescription = item.inventoryDescription.Substring(0, 128);
|
||||
|
||||
return m_Items.Store(item);
|
||||
}
|
||||
|
||||
@@ -78,7 +85,6 @@ namespace OpenSim.Data.MSSQL
|
||||
{
|
||||
return m_Folders.Delete(field, val);
|
||||
}
|
||||
|
||||
public bool DeleteFolders(string[] fields, string[] vals)
|
||||
{
|
||||
return m_Folders.Delete(fields, vals);
|
||||
@@ -88,12 +94,10 @@ namespace OpenSim.Data.MSSQL
|
||||
{
|
||||
return m_Items.Delete(field, val);
|
||||
}
|
||||
|
||||
public bool DeleteItems(string[] fields, string[] vals)
|
||||
{
|
||||
return m_Items.Delete(fields, vals);
|
||||
}
|
||||
|
||||
public bool MoveItem(string id, string newParent)
|
||||
{
|
||||
return m_Items.MoveItem(id, newParent);
|
||||
@@ -172,5 +176,27 @@ namespace OpenSim.Data.MSSQL
|
||||
|
||||
}
|
||||
}
|
||||
public override bool Store(XInventoryItem item)
|
||||
{
|
||||
if (!base.Store(item))
|
||||
return false;
|
||||
string sql = "update inventoryfolders set version=version+1 where folderID = @folderID";
|
||||
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
conn.Open();
|
||||
|
||||
cmd.Parameters.AddWithValue("@folderID", item.parentFolderID.ToString());
|
||||
try
|
||||
{
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,4 +37,28 @@ EXECUTE sp_rename N'dbo.Tmp_Avatars', N'Avatars', 'OBJECT'
|
||||
|
||||
COMMIT
|
||||
|
||||
:VERSION 3
|
||||
|
||||
BEGIN TRANSACTION
|
||||
|
||||
CREATE TABLE dbo.Tmp_Avatars
|
||||
(
|
||||
PrincipalID uniqueidentifier NOT NULL,
|
||||
[Name] varchar(32) NOT NULL,
|
||||
Value text NOT NULL DEFAULT '',
|
||||
PRIMARY KEY CLUSTERED
|
||||
(
|
||||
[PrincipalID] ASC, [Name] ASC
|
||||
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
|
||||
) ON [PRIMARY]
|
||||
TEXTIMAGE_ON [PRIMARY]
|
||||
|
||||
IF EXISTS(SELECT * FROM dbo.Avatars)
|
||||
EXEC('INSERT INTO dbo.Tmp_Avatars (PrincipalID, Name, Value)
|
||||
SELECT PrincipalID, CONVERT(text, Name), Value FROM dbo.Avatars WITH (HOLDLOCK TABLOCKX)')
|
||||
|
||||
DROP TABLE dbo.Avatars
|
||||
|
||||
EXECUTE sp_rename N'dbo.Tmp_Avatars', N'Avatars', 'OBJECT'
|
||||
COMMIT
|
||||
|
||||
|
||||
@@ -17,3 +17,49 @@ CREATE TABLE "GridUser" (
|
||||
)
|
||||
|
||||
COMMIT
|
||||
|
||||
:VERSION 2 # --------------------------
|
||||
|
||||
BEGIN TRANSACTION
|
||||
|
||||
CREATE TABLE [GridUser_tmp] (
|
||||
[UserID] VARCHAR(255) NOT NULL,
|
||||
[HomeRegionID] uniqueidentifier NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
|
||||
[HomePosition] CHAR(64) NOT NULL DEFAULT '<0,0,0>',
|
||||
[HomeLookAt] CHAR(64) NOT NULL DEFAULT '<0,0,0>',
|
||||
[LastRegionID] uniqueidentifier NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',
|
||||
[LastPosition] CHAR(64) NOT NULL DEFAULT '<0,0,0>',
|
||||
[LastLookAt] CHAR(64) NOT NULL DEFAULT '<0,0,0>',
|
||||
[Online] CHAR(5) NOT NULL DEFAULT 'false',
|
||||
[Login] CHAR(16) NOT NULL DEFAULT '0',
|
||||
[Logout] CHAR(16) NOT NULL DEFAULT '0',
|
||||
|
||||
PRIMARY KEY CLUSTERED
|
||||
(
|
||||
[UserID] ASC
|
||||
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
|
||||
) ON [PRIMARY]
|
||||
|
||||
COMMIT
|
||||
|
||||
IF EXISTS(SELECT * FROM dbo.GridUser)
|
||||
EXEC('INSERT INTO dbo.GridUser_tmp ([UserID]
|
||||
,[HomeRegionID]
|
||||
,[HomePosition]
|
||||
,[HomeLookAt]
|
||||
,[LastRegionID]
|
||||
,[LastPosition]
|
||||
,[LastLookAt]
|
||||
,[Online]
|
||||
,[Login]
|
||||
,[Logout])
|
||||
SELECT CONVERT(varchar(36), [HomeRegionID]), [HomePosition] ,[HomeLookAt] , CONVERT(varchar(36),[LastRegionID])
|
||||
,[LastPosition]
|
||||
,[LastLookAt]
|
||||
,[Online]
|
||||
,[Login]
|
||||
,[Logout] FROM dbo.GridUser WITH (HOLDLOCK TABLOCKX)')
|
||||
|
||||
DROP TABLE dbo.GridUser
|
||||
|
||||
EXECUTE sp_rename N'dbo.GridUser_tmp', N'GridUser', 'OBJECT'
|
||||
@@ -1003,7 +1003,7 @@ CREATE TABLE "regionwindlight" (
|
||||
PRIMARY KEY ("region_id")
|
||||
)
|
||||
|
||||
COMMIT TRANSACTION
|
||||
COMMIT
|
||||
|
||||
:VERSION 26
|
||||
|
||||
|
||||
@@ -253,12 +253,14 @@ namespace OpenSim.Data.MySQL
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// check if the asset UUID exist in database
|
||||
/// Check if the asset exists in the database
|
||||
/// </summary>
|
||||
/// <param name="uuid">The asset UUID</param>
|
||||
/// <returns>true if exist.</returns>
|
||||
/// <returns>true if it exists, false otherwise.</returns>
|
||||
override public bool ExistsAsset(UUID uuid)
|
||||
{
|
||||
// m_log.DebugFormat("[ASSETS DB]: Checking for asset {0}", uuid);
|
||||
|
||||
bool assetExists = false;
|
||||
|
||||
lock (m_dbLock)
|
||||
@@ -275,7 +277,10 @@ namespace OpenSim.Data.MySQL
|
||||
using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow))
|
||||
{
|
||||
if (dbReader.Read())
|
||||
{
|
||||
// m_log.DebugFormat("[ASSETS DB]: Found asset {0}", uuid);
|
||||
assetExists = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
|
||||
@@ -43,6 +43,11 @@ namespace OpenSim.Data.MySQL
|
||||
}
|
||||
|
||||
public bool Delete(UUID principalID, string friend)
|
||||
{
|
||||
return Delete(principalID.ToString(), friend);
|
||||
}
|
||||
|
||||
public bool Delete(string principalID, string friend)
|
||||
{
|
||||
MySqlCommand cmd = new MySqlCommand();
|
||||
|
||||
@@ -64,5 +69,14 @@ namespace OpenSim.Data.MySQL
|
||||
|
||||
return DoQuery(cmd);
|
||||
}
|
||||
|
||||
public FriendsData[] GetFriends(string principalID)
|
||||
{
|
||||
MySqlCommand cmd = new MySqlCommand();
|
||||
|
||||
cmd.CommandText = String.Format("select a.*,case when b.Flags is null then -1 else b.Flags end as TheirFlags from {0} as a left join {0} as b on a.PrincipalID = b.Friend and a.Friend = b.PrincipalID where a.PrincipalID LIKE ?PrincipalID", m_Realm);
|
||||
cmd.Parameters.AddWithValue("?PrincipalID", principalID.ToString() + '%');
|
||||
return DoQuery(cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,23 +78,6 @@ namespace OpenSim.Data.MySQL
|
||||
//
|
||||
Migration m = new Migration(dbcon, Assembly, "RegionStore");
|
||||
m.Update();
|
||||
|
||||
// Clean dropped attachments
|
||||
//
|
||||
try
|
||||
{
|
||||
using (MySqlCommand cmd = dbcon.CreateCommand())
|
||||
{
|
||||
cmd.CommandText = "delete from prims, primshapes using prims " +
|
||||
"left join primshapes on prims.uuid = primshapes.uuid " +
|
||||
"where PCode = 9 and State <> 0";
|
||||
ExecuteNonQuery(cmd);
|
||||
}
|
||||
}
|
||||
catch (MySqlException ex)
|
||||
{
|
||||
m_log.Error("[REGION DB]: Error cleaning up dropped attachments: " + ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -753,7 +736,7 @@ namespace OpenSim.Data.MySQL
|
||||
{
|
||||
//No result, so store our default windlight profile and return it
|
||||
nWP.regionID = regionUUID;
|
||||
StoreRegionWindlightSettings(nWP);
|
||||
// StoreRegionWindlightSettings(nWP);
|
||||
return nWP;
|
||||
}
|
||||
else
|
||||
@@ -1011,7 +994,7 @@ namespace OpenSim.Data.MySQL
|
||||
"use_estate_sun, fixed_sun, sun_position, " +
|
||||
"covenant, Sandbox, sunvectorx, sunvectory, " +
|
||||
"sunvectorz, loaded_creation_datetime, " +
|
||||
"loaded_creation_id, map_tile_ID) values (?RegionUUID, ?BlockTerraform, " +
|
||||
"loaded_creation_id, map_tile_ID, block_search, casino) values (?RegionUUID, ?BlockTerraform, " +
|
||||
"?BlockFly, ?AllowDamage, ?RestrictPushing, " +
|
||||
"?AllowLandResell, ?AllowLandJoinDivide, " +
|
||||
"?BlockShowInSearch, ?AgentLimit, ?ObjectBonus, " +
|
||||
@@ -1026,7 +1009,7 @@ namespace OpenSim.Data.MySQL
|
||||
"?SunPosition, ?Covenant, ?Sandbox, " +
|
||||
"?SunVectorX, ?SunVectorY, ?SunVectorZ, " +
|
||||
"?LoadedCreationDateTime, ?LoadedCreationID, " +
|
||||
"?TerrainImageID)";
|
||||
"?TerrainImageID, ?block_search, ?casino)";
|
||||
|
||||
FillRegionSettingsCommand(cmd, rs);
|
||||
|
||||
@@ -1226,7 +1209,6 @@ namespace OpenSim.Data.MySQL
|
||||
return prim;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Build a prim inventory item from the persisted data.
|
||||
/// </summary>
|
||||
@@ -1315,6 +1297,9 @@ namespace OpenSim.Data.MySQL
|
||||
|
||||
newSettings.TerrainImageID = DBGuid.FromDB(row["map_tile_ID"]);
|
||||
|
||||
newSettings.GodBlockSearch = Convert.ToBoolean(row["block_search"]);
|
||||
newSettings.Casino = Convert.ToBoolean(row["casino"]);
|
||||
|
||||
return newSettings;
|
||||
}
|
||||
|
||||
@@ -1644,6 +1629,8 @@ namespace OpenSim.Data.MySQL
|
||||
cmd.Parameters.AddWithValue("LoadedCreationDateTime", settings.LoadedCreationDateTime);
|
||||
cmd.Parameters.AddWithValue("LoadedCreationID", settings.LoadedCreationID);
|
||||
cmd.Parameters.AddWithValue("TerrainImageID", settings.TerrainImageID);
|
||||
cmd.Parameters.AddWithValue("block_search", settings.GodBlockSearch);
|
||||
cmd.Parameters.AddWithValue("casino", settings.Casino);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -70,13 +70,13 @@ namespace OpenSim.Data.MySQL
|
||||
|
||||
if (words.Length == 1)
|
||||
{
|
||||
cmd.CommandText = String.Format("select * from {0} where (ScopeID=?ScopeID or ScopeID='00000000-0000-0000-0000-000000000000') and (FirstName like ?search or LastName like ?search)", m_Realm);
|
||||
cmd.CommandText = String.Format("select * from {0} where (ScopeID=?ScopeID or ScopeID='00000000-0000-0000-0000-000000000000') and (FirstName like ?search or LastName like ?search) and active=1", m_Realm);
|
||||
cmd.Parameters.AddWithValue("?search", words[0] + "%");
|
||||
cmd.Parameters.AddWithValue("?ScopeID", scopeID.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
cmd.CommandText = String.Format("select * from {0} where (ScopeID=?ScopeID or ScopeID='00000000-0000-0000-0000-000000000000') and (FirstName like ?searchFirst and LastName like ?searchLast)", m_Realm);
|
||||
cmd.CommandText = String.Format("select * from {0} where (ScopeID=?ScopeID or ScopeID='00000000-0000-0000-0000-000000000000') and (FirstName like ?searchFirst and LastName like ?searchLast) and active=1", m_Realm);
|
||||
cmd.Parameters.AddWithValue("?searchFirst", words[0] + "%");
|
||||
cmd.Parameters.AddWithValue("?searchLast", words[1] + "%");
|
||||
cmd.Parameters.AddWithValue("?ScopeID", scopeID.ToString());
|
||||
|
||||
@@ -21,5 +21,12 @@ INSERT INTO `Friends` SELECT `ownerID`, `friendID`, `friendPerms`, 0 FROM `userf
|
||||
|
||||
COMMIT;
|
||||
|
||||
:VERSION 3 # -------------------------
|
||||
|
||||
BEGIN;
|
||||
|
||||
ALTER TABLE `Friends` MODIFY COLUMN PrincipalID varchar(255) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000';
|
||||
ALTER TABLE `Friends` DROP PRIMARY KEY;
|
||||
ALTER TABLE `Friends` ADD PRIMARY KEY(PrincipalID(36), Friend(36));
|
||||
|
||||
COMMIT;
|
||||
|
||||
@@ -826,3 +826,19 @@ ALTER TABLE `prims` MODIFY COLUMN `CreatorID` VARCHAR(255) NOT NULL DEFAULT '';
|
||||
ALTER TABLE `primitems` MODIFY COLUMN `CreatorID` VARCHAR(255) NOT NULL DEFAULT '';
|
||||
|
||||
COMMIT;
|
||||
|
||||
:VERSION 38 #---------------------
|
||||
|
||||
BEGIN;
|
||||
|
||||
alter table land ENGINE = MyISAM;
|
||||
alter table landaccesslist ENGINE = MyISAM;
|
||||
alter table migrations ENGINE = MyISAM;
|
||||
alter table primitems ENGINE = MyISAM;
|
||||
alter table prims ENGINE = MyISAM;
|
||||
alter table primshapes ENGINE = MyISAM;
|
||||
alter table regionban ENGINE = MyISAM;
|
||||
alter table regionsettings ENGINE = MyISAM;
|
||||
alter table terrain ENGINE = MyISAM;
|
||||
|
||||
COMMIT;
|
||||
@@ -42,6 +42,11 @@ namespace OpenSim.Data.Null
|
||||
{
|
||||
}
|
||||
|
||||
public FriendsData[] GetFriends(UUID principalID)
|
||||
{
|
||||
return GetFriends(principalID.ToString());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to implement the Get [] semantics, but it cuts corners.
|
||||
/// Specifically, it gets all friendships even if they weren't accepted yet.
|
||||
@@ -49,11 +54,11 @@ namespace OpenSim.Data.Null
|
||||
/// <param name="fields"></param>
|
||||
/// <param name="values"></param>
|
||||
/// <returns></returns>
|
||||
public FriendsData[] GetFriends(UUID userID)
|
||||
public FriendsData[] GetFriends(string userID)
|
||||
{
|
||||
List<FriendsData> lst = m_Data.FindAll(delegate (FriendsData fdata)
|
||||
{
|
||||
return fdata.PrincipalID == userID;
|
||||
return fdata.PrincipalID == userID.ToString();
|
||||
});
|
||||
|
||||
if (lst != null)
|
||||
@@ -72,9 +77,14 @@ namespace OpenSim.Data.Null
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool Delete(UUID userID, string friendID)
|
||||
public bool Delete(UUID principalID, string friend)
|
||||
{
|
||||
List<FriendsData> lst = m_Data.FindAll(delegate(FriendsData fdata) { return fdata.PrincipalID == userID; });
|
||||
return Delete(principalID.ToString(), friend);
|
||||
}
|
||||
|
||||
public bool Delete(string userID, string friendID)
|
||||
{
|
||||
List<FriendsData> lst = m_Data.FindAll(delegate(FriendsData fdata) { return fdata.PrincipalID == userID.ToString(); });
|
||||
if (lst != null)
|
||||
{
|
||||
FriendsData friend = lst.Find(delegate(FriendsData fdata) { return fdata.Friend == friendID; });
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace OpenSim.Data.Null
|
||||
{
|
||||
private static NullRegionData Instance = null;
|
||||
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
Dictionary<UUID, RegionData> m_regionData = new Dictionary<UUID, RegionData>();
|
||||
|
||||
@@ -97,7 +97,7 @@ namespace OpenSim.Data.Null
|
||||
|
||||
foreach (RegionData r in m_regionData.Values)
|
||||
{
|
||||
m_log.DebugFormat("[NULL REGION DATA]: comparing {0} to {1}", cleanName, r.RegionName.ToLower());
|
||||
// m_log.DebugFormat("[NULL REGION DATA]: comparing {0} to {1}", cleanName, r.RegionName.ToLower());
|
||||
if (queryMatch(r.RegionName.ToLower()))
|
||||
ret.Add(r);
|
||||
}
|
||||
|
||||
@@ -59,19 +59,23 @@ namespace OpenSim.Data.Null
|
||||
public void StoreRegionSettings(RegionSettings rs)
|
||||
{
|
||||
}
|
||||
|
||||
public RegionLightShareData LoadRegionWindlightSettings(UUID regionUUID)
|
||||
{
|
||||
//This connector doesn't support the windlight module yet
|
||||
//Return default LL windlight settings
|
||||
return new RegionLightShareData();
|
||||
}
|
||||
|
||||
public void RemoveRegionWindlightSettings(UUID regionID)
|
||||
{
|
||||
}
|
||||
|
||||
public void StoreRegionWindlightSettings(RegionLightShareData wl)
|
||||
{
|
||||
//This connector doesn't support the windlight module yet
|
||||
}
|
||||
|
||||
public RegionSettings LoadRegionSettings(UUID regionUUID)
|
||||
{
|
||||
return null;
|
||||
|
||||
@@ -41,11 +41,9 @@ COMMIT;
|
||||
|
||||
:VERSION 2
|
||||
|
||||
ATTACH 'inventoryStore.db' AS old;
|
||||
|
||||
BEGIN TRANSACTION;
|
||||
|
||||
INSERT INTO inventoryfolders (folderName, type, version, folderID, agentID, parentFolderID) SELECT `name` AS folderName, `type` AS type, `version` AS version, `UUID` AS folderID, `agentID` AS agentID, `parentID` AS parentFolderID from old.inventoryfolders;
|
||||
INSERT INTO inventoryitems (assetID, assetType, inventoryName, inventoryDescription, inventoryNextPermissions, inventoryCurrentPermissions, invType, creatorID, inventoryBasePermissions, inventoryEveryOnePermissions, salePrice, saleType, creationDate, groupID, groupOwned, flags, inventoryID, parentFolderID, avatarID, inventoryGroupPermissions) SELECT `assetID`, `assetType` AS assetType, `inventoryName` AS inventoryName, `inventoryDescription` AS inventoryDescription, `inventoryNextPermissions` AS inventoryNextPermissions, `inventoryCurrentPermissions` AS inventoryCurrentPermissions, `invType` AS invType, `creatorsID` AS creatorID, `inventoryBasePermissions` AS inventoryBasePermissions, `inventoryEveryOnePermissions` AS inventoryEveryOnePermissions, `salePrice` AS salePrice, `saleType` AS saleType, `creationDate` AS creationDate, `groupID` AS groupID, `groupOwned` AS groupOwned, `flags` AS flags, `UUID` AS inventoryID, `parentFolderID` AS parentFolderID, `avatarID` AS avatarID, `inventoryGroupPermissions` AS inventoryGroupPermissions FROM old.inventoryitems;
|
||||
|
||||
COMMIT;
|
||||
COMMIT;
|
||||
|
||||
@@ -57,6 +57,11 @@ namespace OpenSim.Data.SQLite
|
||||
|
||||
private SqliteConnection m_conn;
|
||||
|
||||
protected virtual Assembly Assembly
|
||||
{
|
||||
get { return GetType().Assembly; }
|
||||
}
|
||||
|
||||
override public void Dispose()
|
||||
{
|
||||
if (m_conn != null)
|
||||
@@ -83,8 +88,7 @@ namespace OpenSim.Data.SQLite
|
||||
m_conn = new SqliteConnection(dbconnect);
|
||||
m_conn.Open();
|
||||
|
||||
Assembly assem = GetType().Assembly;
|
||||
Migration m = new Migration(m_conn, assem, "AssetStore");
|
||||
Migration m = new Migration(m_conn, Assembly, "AssetStore");
|
||||
m.Update();
|
||||
|
||||
return;
|
||||
|
||||
@@ -53,6 +53,11 @@ namespace OpenSim.Data.SQLite
|
||||
protected static SqliteConnection m_Connection;
|
||||
private static bool m_initialized = false;
|
||||
|
||||
protected virtual Assembly Assembly
|
||||
{
|
||||
get { return GetType().Assembly; }
|
||||
}
|
||||
|
||||
public SQLiteAuthenticationData(string connectionString, string realm)
|
||||
: base(connectionString)
|
||||
{
|
||||
@@ -63,7 +68,7 @@ namespace OpenSim.Data.SQLite
|
||||
m_Connection = new SqliteConnection(connectionString);
|
||||
m_Connection.Open();
|
||||
|
||||
Migration m = new Migration(m_Connection, GetType().Assembly, "AuthStore");
|
||||
Migration m = new Migration(m_Connection, Assembly, "AuthStore");
|
||||
m.Update();
|
||||
|
||||
m_initialized = true;
|
||||
|
||||
@@ -53,6 +53,11 @@ namespace OpenSim.Data.SQLite
|
||||
private Dictionary<string, FieldInfo> m_FieldMap =
|
||||
new Dictionary<string, FieldInfo>();
|
||||
|
||||
protected virtual Assembly Assembly
|
||||
{
|
||||
get { return GetType().Assembly; }
|
||||
}
|
||||
|
||||
public SQLiteEstateStore()
|
||||
{
|
||||
}
|
||||
@@ -71,8 +76,7 @@ namespace OpenSim.Data.SQLite
|
||||
m_connection = new SqliteConnection(m_connectionString);
|
||||
m_connection.Open();
|
||||
|
||||
Assembly assem = GetType().Assembly;
|
||||
Migration m = new Migration(m_connection, assem, "EstateStore");
|
||||
Migration m = new Migration(m_connection, Assembly, "EstateStore");
|
||||
m.Update();
|
||||
|
||||
//m_connection.Close();
|
||||
|
||||
@@ -46,7 +46,12 @@ namespace OpenSim.Data.SQLite
|
||||
{
|
||||
}
|
||||
|
||||
public FriendsData[] GetFriends(UUID userID)
|
||||
public FriendsData[] GetFriends(UUID principalID)
|
||||
{
|
||||
return GetFriends(principalID.ToString());
|
||||
}
|
||||
|
||||
public FriendsData[] GetFriends(string userID)
|
||||
{
|
||||
SqliteCommand cmd = new SqliteCommand();
|
||||
|
||||
@@ -58,6 +63,11 @@ namespace OpenSim.Data.SQLite
|
||||
}
|
||||
|
||||
public bool Delete(UUID principalID, string friend)
|
||||
{
|
||||
return Delete(principalID.ToString(), friend);
|
||||
}
|
||||
|
||||
public bool Delete(string principalID, string friend)
|
||||
{
|
||||
SqliteCommand cmd = new SqliteCommand();
|
||||
|
||||
|
||||
@@ -55,6 +55,11 @@ namespace OpenSim.Data.SQLite
|
||||
protected static SqliteConnection m_Connection;
|
||||
private static bool m_initialized;
|
||||
|
||||
protected virtual Assembly Assembly
|
||||
{
|
||||
get { return GetType().Assembly; }
|
||||
}
|
||||
|
||||
public SQLiteGenericTableHandler(string connectionString,
|
||||
string realm, string storeName) : base(connectionString)
|
||||
{
|
||||
@@ -68,13 +73,12 @@ namespace OpenSim.Data.SQLite
|
||||
|
||||
if (storeName != String.Empty)
|
||||
{
|
||||
Assembly assem = GetType().Assembly;
|
||||
//SqliteConnection newConnection =
|
||||
// (SqliteConnection)((ICloneable)m_Connection).Clone();
|
||||
//newConnection.Open();
|
||||
|
||||
//Migration m = new Migration(newConnection, assem, storeName);
|
||||
Migration m = new Migration(m_Connection, assem, storeName);
|
||||
//Migration m = new Migration(newConnection, Assembly, storeName);
|
||||
Migration m = new Migration(m_Connection, Assembly, storeName);
|
||||
m.Update();
|
||||
//newConnection.Close();
|
||||
//newConnection.Dispose();
|
||||
@@ -280,7 +284,7 @@ namespace OpenSim.Data.SQLite
|
||||
|
||||
string where = String.Join(" and ", terms.ToArray());
|
||||
|
||||
string query = String.Format("delete * from {0} where {1}", m_Realm, where);
|
||||
string query = String.Format("delete from {0} where {1}", m_Realm, where);
|
||||
|
||||
cmd.CommandText = query;
|
||||
|
||||
|
||||
@@ -74,6 +74,11 @@ namespace OpenSim.Data.SQLite
|
||||
|
||||
private String m_connectionString;
|
||||
|
||||
protected virtual Assembly Assembly
|
||||
{
|
||||
get { return GetType().Assembly; }
|
||||
}
|
||||
|
||||
public SQLiteSimulationData()
|
||||
{
|
||||
}
|
||||
@@ -132,8 +137,7 @@ namespace OpenSim.Data.SQLite
|
||||
SqliteCommand regionSettingsSelectCmd = new SqliteCommand(regionSettingsSelect, m_conn);
|
||||
regionSettingsDa = new SqliteDataAdapter(regionSettingsSelectCmd);
|
||||
// This actually does the roll forward assembly stuff
|
||||
Assembly assem = GetType().Assembly;
|
||||
Migration m = new Migration(m_conn, assem, "RegionStore");
|
||||
Migration m = new Migration(m_conn, Assembly, "RegionStore");
|
||||
m.Update();
|
||||
|
||||
lock (ds)
|
||||
|
||||
@@ -41,7 +41,7 @@ using OpenSim.Framework;
|
||||
namespace OpenSim.Data.SQLite
|
||||
{
|
||||
/// <summary>
|
||||
/// A MySQL Interface for the Asset Server
|
||||
/// A SQLite Interface for the Asset Server
|
||||
/// </summary>
|
||||
public class SQLiteXInventoryData : IXInventoryData
|
||||
{
|
||||
|
||||
@@ -106,7 +106,7 @@ namespace OpenSim.Data.Tests
|
||||
[Test]
|
||||
public void T001_LoadEmpty()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
|
||||
Assert.That(m_db.ExistsAsset(uuid1), Is.False);
|
||||
Assert.That(m_db.ExistsAsset(uuid2), Is.False);
|
||||
@@ -116,7 +116,7 @@ namespace OpenSim.Data.Tests
|
||||
[Test]
|
||||
public void T010_StoreReadVerifyAssets()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
|
||||
AssetBase a1 = new AssetBase(uuid1, "asset one", (sbyte)AssetType.Texture, critter1.ToString());
|
||||
AssetBase a2 = new AssetBase(uuid2, "asset two", (sbyte)AssetType.Texture, critter2.ToString());
|
||||
@@ -183,7 +183,7 @@ namespace OpenSim.Data.Tests
|
||||
[Test]
|
||||
public void T020_CheckForWeirdCreatorID()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
|
||||
// It is expected that eventually the CreatorID might be an arbitrary string (an URI)
|
||||
// rather than a valid UUID (?). This test is to make sure that the database layer does not
|
||||
|
||||
@@ -107,7 +107,7 @@ namespace OpenSim.Data.Tests
|
||||
[Test]
|
||||
public void T010_EstateSettingsSimpleStorage_MinimumParameterSet()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
|
||||
EstateSettingsSimpleStorage(
|
||||
REGION_ID,
|
||||
@@ -140,7 +140,7 @@ namespace OpenSim.Data.Tests
|
||||
[Test]
|
||||
public void T011_EstateSettingsSimpleStorage_MaximumParameterSet()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
|
||||
EstateSettingsSimpleStorage(
|
||||
REGION_ID,
|
||||
@@ -173,7 +173,7 @@ namespace OpenSim.Data.Tests
|
||||
[Test]
|
||||
public void T012_EstateSettingsSimpleStorage_AccurateParameterSet()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
|
||||
EstateSettingsSimpleStorage(
|
||||
REGION_ID,
|
||||
@@ -206,7 +206,7 @@ namespace OpenSim.Data.Tests
|
||||
[Test]
|
||||
public void T012_EstateSettingsRandomStorage()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
|
||||
// Letting estate store generate rows to database for us
|
||||
EstateSettings originalSettings = db.LoadEstateSettings(REGION_ID, true);
|
||||
@@ -227,7 +227,7 @@ namespace OpenSim.Data.Tests
|
||||
[Test]
|
||||
public void T020_EstateSettingsManagerList()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
|
||||
// Letting estate store generate rows to database for us
|
||||
EstateSettings originalSettings = db.LoadEstateSettings(REGION_ID, true);
|
||||
@@ -248,7 +248,7 @@ namespace OpenSim.Data.Tests
|
||||
[Test]
|
||||
public void T021_EstateSettingsUserList()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
|
||||
// Letting estate store generate rows to database for us
|
||||
EstateSettings originalSettings = db.LoadEstateSettings(REGION_ID, true);
|
||||
@@ -269,7 +269,7 @@ namespace OpenSim.Data.Tests
|
||||
[Test]
|
||||
public void T022_EstateSettingsGroupList()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
|
||||
// Letting estate store generate rows to database for us
|
||||
EstateSettings originalSettings = db.LoadEstateSettings(REGION_ID, true);
|
||||
@@ -290,7 +290,7 @@ namespace OpenSim.Data.Tests
|
||||
[Test]
|
||||
public void T022_EstateSettingsBanList()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
|
||||
// Letting estate store generate rows to database for us
|
||||
EstateSettings originalSettings = db.LoadEstateSettings(REGION_ID, true);
|
||||
|
||||
@@ -114,7 +114,7 @@ namespace OpenSim.Data.Tests
|
||||
[Test]
|
||||
public void T001_LoadEmpty()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
|
||||
Assert.That(db.getInventoryFolder(zero), Is.Null);
|
||||
Assert.That(db.getInventoryFolder(folder1), Is.Null);
|
||||
@@ -134,7 +134,7 @@ namespace OpenSim.Data.Tests
|
||||
[Test]
|
||||
public void T010_FolderNonParent()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
|
||||
InventoryFolderBase f1 = NewFolder(folder2, folder1, owner1, name2);
|
||||
// the folder will go in
|
||||
@@ -146,7 +146,7 @@ namespace OpenSim.Data.Tests
|
||||
[Test]
|
||||
public void T011_FolderCreate()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
|
||||
InventoryFolderBase f1 = NewFolder(folder1, zero, owner1, name1);
|
||||
// TODO: this is probably wrong behavior, but is what we have
|
||||
@@ -171,7 +171,7 @@ namespace OpenSim.Data.Tests
|
||||
[Test]
|
||||
public void T012_FolderList()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
|
||||
InventoryFolderBase f2 = NewFolder(folder3, folder1, owner1, name3);
|
||||
db.addInventoryFolder(f2);
|
||||
@@ -187,7 +187,7 @@ namespace OpenSim.Data.Tests
|
||||
[Test]
|
||||
public void T013_FolderHierarchy()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
|
||||
int n = db.getFolderHierarchy(zero).Count; // (for dbg - easier to see what's returned)
|
||||
Assert.That(n, Is.EqualTo(0), "Assert.That(db.getFolderHierarchy(zero).Count, Is.EqualTo(0))");
|
||||
@@ -202,7 +202,7 @@ namespace OpenSim.Data.Tests
|
||||
[Test]
|
||||
public void T014_MoveFolder()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
|
||||
InventoryFolderBase f2 = db.getInventoryFolder(folder2);
|
||||
f2.ParentID = folder3;
|
||||
@@ -218,7 +218,7 @@ namespace OpenSim.Data.Tests
|
||||
[Test]
|
||||
public void T015_FolderHierarchy()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
|
||||
Assert.That(db.getFolderHierarchy(zero).Count, Is.EqualTo(0), "Assert.That(db.getFolderHierarchy(zero).Count, Is.EqualTo(0))");
|
||||
Assert.That(db.getFolderHierarchy(folder1).Count, Is.EqualTo(2), "Assert.That(db.getFolderHierarchy(folder1).Count, Is.EqualTo(2))");
|
||||
@@ -231,7 +231,7 @@ namespace OpenSim.Data.Tests
|
||||
[Test]
|
||||
public void T100_NoItems()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
|
||||
Assert.That(db.getInventoryInFolder(zero).Count, Is.EqualTo(0), "Assert.That(db.getInventoryInFolder(zero).Count, Is.EqualTo(0))");
|
||||
Assert.That(db.getInventoryInFolder(folder1).Count, Is.EqualTo(0), "Assert.That(db.getInventoryInFolder(folder1).Count, Is.EqualTo(0))");
|
||||
@@ -245,7 +245,7 @@ namespace OpenSim.Data.Tests
|
||||
[Test]
|
||||
public void T101_CreatItems()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
|
||||
db.addInventoryItem(NewItem(item1, folder3, owner1, iname1, asset1));
|
||||
db.addInventoryItem(NewItem(item2, folder3, owner1, iname2, asset2));
|
||||
@@ -256,7 +256,7 @@ namespace OpenSim.Data.Tests
|
||||
[Test]
|
||||
public void T102_CompareItems()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
|
||||
InventoryItemBase i1 = db.getInventoryItem(item1);
|
||||
InventoryItemBase i2 = db.getInventoryItem(item2);
|
||||
@@ -275,7 +275,7 @@ namespace OpenSim.Data.Tests
|
||||
[Test]
|
||||
public void T103_UpdateItem()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
|
||||
// TODO: probably shouldn't have the ability to have an
|
||||
// owner of an item in a folder not owned by the user
|
||||
@@ -295,7 +295,7 @@ namespace OpenSim.Data.Tests
|
||||
[Test]
|
||||
public void T104_RandomUpdateItem()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
|
||||
PropertyScrambler<InventoryFolderBase> folderScrambler =
|
||||
new PropertyScrambler<InventoryFolderBase>()
|
||||
@@ -354,7 +354,7 @@ namespace OpenSim.Data.Tests
|
||||
[Test]
|
||||
public void T999_StillNull()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
|
||||
// After all tests are run, these should still return no results
|
||||
Assert.That(db.getInventoryFolder(zero), Is.Null);
|
||||
|
||||
@@ -151,7 +151,7 @@ namespace OpenSim.Data.Tests
|
||||
[Test]
|
||||
public void T001_LoadEmpty()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
|
||||
List<SceneObjectGroup> objs = db.LoadObjects(region1);
|
||||
List<SceneObjectGroup> objs3 = db.LoadObjects(region3);
|
||||
@@ -169,7 +169,7 @@ namespace OpenSim.Data.Tests
|
||||
[Test]
|
||||
public void T010_StoreSimpleObject()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
|
||||
SceneObjectGroup sog = NewSOG("object1", prim1, region1);
|
||||
SceneObjectGroup sog2 = NewSOG("object2", prim2, region1);
|
||||
@@ -204,7 +204,7 @@ namespace OpenSim.Data.Tests
|
||||
[Test]
|
||||
public void T011_ObjectNames()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
|
||||
List<SceneObjectGroup> objs = db.LoadObjects(region1);
|
||||
foreach (SceneObjectGroup sog in objs)
|
||||
@@ -218,7 +218,7 @@ namespace OpenSim.Data.Tests
|
||||
[Test]
|
||||
public void T012_SceneParts()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
|
||||
UUID tmp0 = UUID.Random();
|
||||
UUID tmp1 = UUID.Random();
|
||||
@@ -253,7 +253,7 @@ namespace OpenSim.Data.Tests
|
||||
[Test]
|
||||
public void T013_DatabasePersistency()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
|
||||
// Sets all ScenePart parameters, stores and retrieves them, then check for consistency with initial data
|
||||
// The commented Asserts are the ones that are unchangeable (when storing on the database, their "Set" values are ignored
|
||||
@@ -304,9 +304,9 @@ namespace OpenSim.Data.Tests
|
||||
regionInfo.RegionLocX = 0;
|
||||
regionInfo.RegionLocY = 0;
|
||||
|
||||
// Scene scene = new Scene(regionInfo);
|
||||
|
||||
SceneObjectPart sop = new SceneObjectPart();
|
||||
SceneObjectGroup sog = new SceneObjectGroup(sop);
|
||||
|
||||
sop.RegionHandle = regionh;
|
||||
sop.UUID = uuid;
|
||||
sop.LocalId = localid;
|
||||
@@ -373,8 +373,6 @@ namespace OpenSim.Data.Tests
|
||||
|
||||
// This is necessary or object will not be inserted in DB
|
||||
sop.Flags = PrimFlags.None;
|
||||
|
||||
SceneObjectGroup sog = new SceneObjectGroup(sop);
|
||||
|
||||
// Inserts group in DB
|
||||
db.StoreObject(sog,region3);
|
||||
@@ -430,7 +428,7 @@ namespace OpenSim.Data.Tests
|
||||
[Test]
|
||||
public void T014_UpdateObject()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
|
||||
string text1 = "object1 text";
|
||||
SceneObjectGroup sog = FindSOG("object1", region1);
|
||||
@@ -540,7 +538,7 @@ namespace OpenSim.Data.Tests
|
||||
[Test]
|
||||
public void T015_LargeSceneObjects()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
|
||||
UUID id = UUID.Random();
|
||||
Dictionary<UUID, SceneObjectPart> mydic = new Dictionary<UUID, SceneObjectPart>();
|
||||
@@ -587,7 +585,7 @@ namespace OpenSim.Data.Tests
|
||||
//[Test]
|
||||
public void T016_RandomSogWithSceneParts()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
|
||||
PropertyScrambler<SceneObjectPart> scrambler =
|
||||
new PropertyScrambler<SceneObjectPart>()
|
||||
@@ -663,7 +661,7 @@ namespace OpenSim.Data.Tests
|
||||
[Test]
|
||||
public void T020_PrimInventoryEmpty()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
|
||||
SceneObjectGroup sog = GetMySOG("object1");
|
||||
TaskInventoryItem t = sog.GetInventoryItem(sog.RootPart.LocalId, item1);
|
||||
@@ -687,7 +685,7 @@ namespace OpenSim.Data.Tests
|
||||
[Test]
|
||||
public void T021_PrimInventoryBasic()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
|
||||
SceneObjectGroup sog = GetMySOG("object1");
|
||||
InventoryItemBase i = NewItem(item1, zero, zero, itemname1, zero);
|
||||
@@ -727,7 +725,7 @@ namespace OpenSim.Data.Tests
|
||||
[Test]
|
||||
public void T025_PrimInventoryPersistency()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
|
||||
InventoryItemBase i = new InventoryItemBase();
|
||||
UUID id = UUID.Random();
|
||||
@@ -800,7 +798,7 @@ namespace OpenSim.Data.Tests
|
||||
[ExpectedException(typeof(ArgumentException))]
|
||||
public void T026_PrimInventoryMany()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
|
||||
UUID i1,i2,i3,i4;
|
||||
i1 = UUID.Random();
|
||||
@@ -832,7 +830,7 @@ namespace OpenSim.Data.Tests
|
||||
[Test]
|
||||
public void T052_RemoveObject()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
|
||||
db.RemoveObject(prim1, region1);
|
||||
SceneObjectGroup sog = FindSOG("object1", region1);
|
||||
@@ -842,7 +840,7 @@ namespace OpenSim.Data.Tests
|
||||
[Test]
|
||||
public void T100_DefaultRegionInfo()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
|
||||
RegionSettings r1 = db.LoadRegionSettings(region1);
|
||||
Assert.That(r1.RegionUUID, Is.EqualTo(region1), "Assert.That(r1.RegionUUID, Is.EqualTo(region1))");
|
||||
@@ -854,7 +852,7 @@ namespace OpenSim.Data.Tests
|
||||
[Test]
|
||||
public void T101_UpdateRegionInfo()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
|
||||
int agentlimit = random.Next();
|
||||
double objectbonus = random.Next();
|
||||
@@ -960,7 +958,7 @@ namespace OpenSim.Data.Tests
|
||||
[Test]
|
||||
public void T300_NoTerrain()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
|
||||
Assert.That(db.LoadTerrain(zero), Is.Null);
|
||||
Assert.That(db.LoadTerrain(region1), Is.Null);
|
||||
@@ -971,7 +969,7 @@ namespace OpenSim.Data.Tests
|
||||
[Test]
|
||||
public void T301_CreateTerrain()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
|
||||
double[,] t1 = GenTerrain(height1);
|
||||
db.StoreTerrain(t1, region1);
|
||||
@@ -985,7 +983,7 @@ namespace OpenSim.Data.Tests
|
||||
[Test]
|
||||
public void T302_FetchTerrain()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
|
||||
double[,] baseterrain1 = GenTerrain(height1);
|
||||
double[,] baseterrain2 = GenTerrain(height2);
|
||||
@@ -997,7 +995,7 @@ namespace OpenSim.Data.Tests
|
||||
[Test]
|
||||
public void T303_UpdateTerrain()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
|
||||
double[,] baseterrain1 = GenTerrain(height1);
|
||||
double[,] baseterrain2 = GenTerrain(height2);
|
||||
@@ -1011,7 +1009,7 @@ namespace OpenSim.Data.Tests
|
||||
[Test]
|
||||
public void T400_EmptyLand()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
|
||||
Assert.That(db.LoadLandObjects(zero).Count, Is.EqualTo(0), "Assert.That(db.LoadLandObjects(zero).Count, Is.EqualTo(0))");
|
||||
Assert.That(db.LoadLandObjects(region1).Count, Is.EqualTo(0), "Assert.That(db.LoadLandObjects(region1).Count, Is.EqualTo(0))");
|
||||
|
||||
@@ -296,11 +296,12 @@ namespace OpenSim.Framework
|
||||
if (args["start_pos"] != null)
|
||||
Vector3.TryParse(args["start_pos"].AsString(), out startpos);
|
||||
|
||||
m_log.InfoFormat("[AGENTCIRCUITDATA] agentid={0}, child={1}, startpos={2}",AgentID,child,startpos.ToString());
|
||||
m_log.InfoFormat("[AGENTCIRCUITDATA]: agentid={0}, child={1}, startpos={2}", AgentID, child, startpos);
|
||||
|
||||
try {
|
||||
try
|
||||
{
|
||||
// Unpack various appearance elements
|
||||
Appearance = new AvatarAppearance(AgentID);
|
||||
Appearance = new AvatarAppearance();
|
||||
|
||||
// Eventually this code should be deprecated, use full appearance
|
||||
// packing in packed_appearance
|
||||
@@ -313,7 +314,9 @@ namespace OpenSim.Framework
|
||||
m_log.InfoFormat("[AGENTCIRCUITDATA] unpacked appearance");
|
||||
}
|
||||
else
|
||||
m_log.Warn("[AGENTCIRCUITDATA] failed to find a valid packed_appearance");
|
||||
{
|
||||
m_log.Warn("[AGENTCIRCUITDATA]: failed to find a valid packed_appearance");
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -345,6 +348,7 @@ namespace OpenSim.Framework
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -223,6 +223,12 @@ namespace OpenSim.Framework
|
||||
set { m_metadata.Temporary = value; }
|
||||
}
|
||||
|
||||
public string CreatorID
|
||||
{
|
||||
get { return m_metadata.CreatorID; }
|
||||
set { m_metadata.CreatorID = value; }
|
||||
}
|
||||
|
||||
public AssetFlags Flags
|
||||
{
|
||||
get { return m_metadata.Flags; }
|
||||
@@ -275,6 +281,7 @@ namespace OpenSim.Framework
|
||||
|
||||
return m_id;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
UUID uuid = UUID.Zero;
|
||||
|
||||
@@ -35,6 +35,7 @@ namespace OpenSim.Framework
|
||||
public Vector3 Position;
|
||||
public ulong RegionHandle;
|
||||
public UUID RegionID;
|
||||
public string Gatekeeper = string.Empty;
|
||||
public int Version;
|
||||
|
||||
public AssetLandmark(AssetBase a)
|
||||
@@ -51,6 +52,8 @@ namespace OpenSim.Framework
|
||||
string[] parts = temp.Split('\n');
|
||||
int.TryParse(parts[0].Substring(17, 1), out Version);
|
||||
UUID.TryParse(parts[1].Substring(10, 36), out RegionID);
|
||||
if (parts.Length >= 5)
|
||||
Gatekeeper = parts[4].Replace("gatekeeper ", "");
|
||||
// The position is a vector with spaces as separators ("10.3 32.5 43").
|
||||
// Parse each scalar separately to take into account the system's culture setting.
|
||||
string[] scalars = parts[2].Substring(10, parts[2].Length - 10).Split(' ');
|
||||
|
||||
@@ -47,7 +47,6 @@ namespace OpenSim.Framework
|
||||
public readonly static int TEXTURE_COUNT = 21;
|
||||
public readonly static byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 };
|
||||
|
||||
protected UUID m_owner;
|
||||
protected int m_serial = 0;
|
||||
protected byte[] m_visualparams;
|
||||
protected Primitive.TextureEntry m_texture;
|
||||
@@ -56,12 +55,6 @@ namespace OpenSim.Framework
|
||||
protected float m_avatarHeight = 0;
|
||||
protected float m_hipOffset = 0;
|
||||
|
||||
public virtual UUID Owner
|
||||
{
|
||||
get { return m_owner; }
|
||||
set { m_owner = value; }
|
||||
}
|
||||
|
||||
public virtual int Serial
|
||||
{
|
||||
get { return m_serial; }
|
||||
@@ -77,7 +70,11 @@ namespace OpenSim.Framework
|
||||
public virtual Primitive.TextureEntry Texture
|
||||
{
|
||||
get { return m_texture; }
|
||||
set { m_texture = value; }
|
||||
set
|
||||
{
|
||||
// m_log.DebugFormat("[AVATAR APPEARANCE]: Set TextureEntry to {0}", value);
|
||||
m_texture = value;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual AvatarWearable[] Wearables
|
||||
@@ -97,38 +94,31 @@ namespace OpenSim.Framework
|
||||
get { return m_hipOffset; }
|
||||
}
|
||||
|
||||
public AvatarAppearance() : this(UUID.Zero) {}
|
||||
|
||||
public AvatarAppearance(UUID owner)
|
||||
public AvatarAppearance()
|
||||
{
|
||||
// m_log.WarnFormat("[AVATAR APPEARANCE]: create empty appearance for {0}",owner);
|
||||
// m_log.WarnFormat("[AVATAR APPEARANCE]: create empty appearance");
|
||||
|
||||
m_serial = 0;
|
||||
m_owner = owner;
|
||||
|
||||
SetDefaultWearables();
|
||||
SetDefaultTexture();
|
||||
SetDefaultParams();
|
||||
SetHeight();
|
||||
|
||||
m_attachments = new Dictionary<int, List<AvatarAttachment>>();
|
||||
}
|
||||
|
||||
public AvatarAppearance(UUID avatarID, OSDMap map)
|
||||
public AvatarAppearance(OSDMap map)
|
||||
{
|
||||
// m_log.WarnFormat("[AVATAR APPEARANCE]: create appearance for {0} from OSDMap",avatarID);
|
||||
// m_log.WarnFormat("[AVATAR APPEARANCE]: create appearance from OSDMap");
|
||||
|
||||
m_owner = avatarID;
|
||||
Unpack(map);
|
||||
SetHeight();
|
||||
}
|
||||
|
||||
public AvatarAppearance(UUID avatarID, AvatarWearable[] wearables, Primitive.TextureEntry textureEntry, byte[] visualParams)
|
||||
public AvatarAppearance(AvatarWearable[] wearables, Primitive.TextureEntry textureEntry, byte[] visualParams)
|
||||
{
|
||||
// m_log.WarnFormat("[AVATAR APPEARANCE] create initialized appearance for {0}",avatarID);
|
||||
// m_log.WarnFormat("[AVATAR APPEARANCE] create initialized appearance");
|
||||
|
||||
m_serial = 0;
|
||||
m_owner = avatarID;
|
||||
|
||||
if (wearables != null)
|
||||
m_wearables = wearables;
|
||||
@@ -161,24 +151,21 @@ namespace OpenSim.Framework
|
||||
if (appearance == null)
|
||||
{
|
||||
m_serial = 0;
|
||||
m_owner = UUID.Zero;
|
||||
|
||||
SetDefaultWearables();
|
||||
SetDefaultTexture();
|
||||
SetDefaultParams();
|
||||
SetHeight();
|
||||
|
||||
m_attachments = new Dictionary<int, List<AvatarAttachment>>();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
m_serial = appearance.Serial;
|
||||
m_owner = appearance.Owner;
|
||||
|
||||
m_wearables = new AvatarWearable[AvatarWearable.MAX_WEARABLES];
|
||||
for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++)
|
||||
m_wearables[i] = new AvatarWearable();
|
||||
|
||||
if (copyWearables && (appearance.Wearables != null))
|
||||
{
|
||||
for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++)
|
||||
@@ -196,6 +183,9 @@ namespace OpenSim.Framework
|
||||
if (appearance.VisualParams != null)
|
||||
m_visualparams = (byte[])appearance.VisualParams.Clone();
|
||||
|
||||
m_avatarHeight = appearance.m_avatarHeight;
|
||||
m_hipOffset = appearance.m_hipOffset;
|
||||
|
||||
// Copy the attachment, force append mode since that ensures consistency
|
||||
m_attachments = new Dictionary<int, List<AvatarAttachment>>();
|
||||
foreach (AvatarAttachment attachment in appearance.GetAttachments())
|
||||
@@ -237,7 +227,6 @@ namespace OpenSim.Framework
|
||||
{
|
||||
m_serial = 0;
|
||||
|
||||
SetDefaultParams();
|
||||
SetDefaultTexture();
|
||||
|
||||
//for (int i = 0; i < BAKE_INDICES.Length; i++)
|
||||
@@ -409,36 +398,47 @@ namespace OpenSim.Framework
|
||||
// DEBUG OFF
|
||||
|
||||
/// <summary>
|
||||
/// Get a list of the attachments, note that there may be
|
||||
/// duplicate attachpoints
|
||||
/// Get a list of the attachments.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// There may be duplicate attachpoints
|
||||
/// </remarks>
|
||||
public List<AvatarAttachment> GetAttachments()
|
||||
{
|
||||
|
||||
|
||||
lock (m_attachments)
|
||||
{
|
||||
List<AvatarAttachment> alist = new List<AvatarAttachment>();
|
||||
List<AvatarAttachment> alist = new List<AvatarAttachment>();
|
||||
foreach (KeyValuePair<int, List<AvatarAttachment>> kvp in m_attachments)
|
||||
{
|
||||
foreach (AvatarAttachment attach in kvp.Value)
|
||||
alist.Add(new AvatarAttachment(attach));
|
||||
}
|
||||
|
||||
return alist;
|
||||
}
|
||||
}
|
||||
return alist;
|
||||
} }
|
||||
|
||||
internal void AppendAttachment(AvatarAttachment attach)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[AVATAR APPEARNCE]: Appending itemID={0}, assetID={1} at {2}",
|
||||
// attach.ItemID, attach.AssetID, attach.AttachPoint);
|
||||
|
||||
lock (m_attachments)
|
||||
{
|
||||
if (!m_attachments.ContainsKey(attach.AttachPoint))
|
||||
m_attachments[attach.AttachPoint] = new List<AvatarAttachment>();
|
||||
|
||||
m_attachments[attach.AttachPoint].Add(attach);
|
||||
}
|
||||
}
|
||||
|
||||
internal void ReplaceAttachment(AvatarAttachment attach)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[AVATAR APPEARANCE]: Replacing itemID={0}, assetID={1} at {2}",
|
||||
// attach.ItemID, attach.AssetID, attach.AttachPoint);
|
||||
|
||||
lock (m_attachments)
|
||||
{
|
||||
m_attachments[attach.AttachPoint] = new List<AvatarAttachment>();
|
||||
@@ -447,14 +447,26 @@ namespace OpenSim.Framework
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add an attachment, if the attachpoint has the
|
||||
/// Set an attachment
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If the attachpoint has the
|
||||
/// 0x80 bit set then we assume this is an append
|
||||
/// operation otherwise we replace whatever is
|
||||
/// currently attached at the attachpoint
|
||||
/// </remarks>
|
||||
/// <param name="attachpoint"></param>
|
||||
/// <param name="item">If UUID.Zero, then an any attachment at the attachpoint is removed.</param>
|
||||
/// <param name="asset"></param>
|
||||
/// <returns>
|
||||
/// return true if something actually changed
|
||||
/// </summary>
|
||||
/// </returns>
|
||||
public bool SetAttachment(int attachpoint, UUID item, UUID asset)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[AVATAR APPEARANCE]: Setting attachment at {0} with item ID {1}, asset ID {2}",
|
||||
// attachpoint, item, asset);
|
||||
|
||||
if (attachpoint == 0)
|
||||
return false;
|
||||
|
||||
@@ -467,12 +479,21 @@ namespace OpenSim.Framework
|
||||
m_attachments.Remove(attachpoint);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// check if the item is already attached at this point
|
||||
if (GetAttachpoint(item) == (attachpoint & 0x7F))
|
||||
// When a user logs in, the attachment item ids are pulled from persistence in the Avatars table. However,
|
||||
// the asset ids are not saved. When the avatar enters a simulator the attachments are set again. If
|
||||
// we simply perform an item check here then the asset ids (which are now present) are never set, and NPC attachments
|
||||
// later fail unless the attachment is detached and reattached.
|
||||
//
|
||||
// Therefore, we will carry on with the set if the existing attachment has no asset id.
|
||||
AvatarAttachment existingAttachment = GetAttachmentForItem(item);
|
||||
if (existingAttachment != null
|
||||
&& existingAttachment.AssetID != UUID.Zero
|
||||
&& existingAttachment.AttachPoint == (attachpoint & 0x7F))
|
||||
{
|
||||
// m_log.DebugFormat("[AVATAR APPEARANCE] attempt to attach an already attached item {0}",item);
|
||||
return false;
|
||||
@@ -487,11 +508,32 @@ namespace OpenSim.Framework
|
||||
}
|
||||
else
|
||||
{
|
||||
ReplaceAttachment(new AvatarAttachment(attachpoint,item,asset));
|
||||
ReplaceAttachment(new AvatarAttachment(attachpoint,item, asset));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If the item is already attached, return it.
|
||||
/// </summary>
|
||||
/// <param name="itemID"></param>
|
||||
/// <returns>Returns null if this item is not attached.</returns>
|
||||
public AvatarAttachment GetAttachmentForItem(UUID itemID)
|
||||
{
|
||||
lock (m_attachments)
|
||||
{
|
||||
foreach (KeyValuePair<int, List<AvatarAttachment>> kvp in m_attachments)
|
||||
{
|
||||
int index = kvp.Value.FindIndex(delegate(AvatarAttachment a) { return a.ItemID == itemID; });
|
||||
if (index >= 0)
|
||||
return kvp.Value[index];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public int GetAttachpoint(UUID itemID)
|
||||
{
|
||||
lock (m_attachments)
|
||||
@@ -502,9 +544,8 @@ namespace OpenSim.Framework
|
||||
if (index >= 0)
|
||||
return kvp.Key;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public bool DetachAttachment(UUID itemID)
|
||||
@@ -518,23 +559,23 @@ namespace OpenSim.Framework
|
||||
{
|
||||
// Remove it from the list of attachments at that attach point
|
||||
m_attachments[kvp.Key].RemoveAt(index);
|
||||
|
||||
|
||||
// And remove the list if there are no more attachments here
|
||||
if (m_attachments[kvp.Key].Count == 0)
|
||||
m_attachments.Remove(kvp.Key);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void ClearAttachments()
|
||||
{
|
||||
lock (m_attachments)
|
||||
{
|
||||
m_attachments.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
#region Packing Functions
|
||||
@@ -589,7 +630,7 @@ namespace OpenSim.Framework
|
||||
/// </summary>
|
||||
public void Unpack(OSDMap data)
|
||||
{
|
||||
if ((data != null) && (data["serial"] != null))
|
||||
if ((data != null) && (data["serial"] != null))
|
||||
m_serial = data["serial"].AsInteger();
|
||||
if ((data != null) && (data["height"] != null))
|
||||
m_avatarHeight = (float)data["height"].AsReal();
|
||||
@@ -647,7 +688,14 @@ namespace OpenSim.Framework
|
||||
{
|
||||
OSDArray attachs = (OSDArray)(data["attachments"]);
|
||||
for (int i = 0; i < attachs.Count; i++)
|
||||
AppendAttachment(new AvatarAttachment((OSDMap)attachs[i]));
|
||||
{
|
||||
AvatarAttachment att = new AvatarAttachment((OSDMap)attachs[i]);
|
||||
AppendAttachment(att);
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[AVATAR APPEARANCE]: Unpacked attachment itemID {0}, assetID {1}, point {2}",
|
||||
// att.ItemID, att.AssetID, att.AttachPoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
|
||||
@@ -66,11 +66,11 @@ namespace OpenSim.Framework
|
||||
return attachdata;
|
||||
}
|
||||
|
||||
|
||||
public void Unpack(OSDMap args)
|
||||
{
|
||||
if (args["point"] != null)
|
||||
AttachPoint = args["point"].AsInteger();
|
||||
|
||||
ItemID = (args["item"] != null) ? args["item"].AsUUID() : UUID.Zero;
|
||||
AssetID = (args["asset"] != null) ? args["asset"].AsUUID() : UUID.Zero;
|
||||
}
|
||||
|
||||
@@ -441,7 +441,6 @@ namespace OpenSim.Framework
|
||||
args["controllers"] = controls;
|
||||
}
|
||||
|
||||
|
||||
if ((CallbackURI != null) && (!CallbackURI.Equals("")))
|
||||
args["callback_uri"] = OSD.FromString(CallbackURI);
|
||||
|
||||
@@ -593,7 +592,7 @@ namespace OpenSim.Framework
|
||||
// AgentTextures[i++] = o.AsUUID();
|
||||
//}
|
||||
|
||||
Appearance = new AvatarAppearance(AgentID);
|
||||
Appearance = new AvatarAppearance();
|
||||
|
||||
// The code to unpack textures, visuals, wearables and attachments
|
||||
// should be removed; packed appearance contains the full appearance
|
||||
@@ -628,6 +627,7 @@ namespace OpenSim.Framework
|
||||
// We know all of these must end up as attachments so we
|
||||
// append rather than replace to ensure multiple attachments
|
||||
// per point continues to work
|
||||
// m_log.DebugFormat("[CHILDAGENTDATAUPDATE]: Appending attachments for {0}", AgentID);
|
||||
Appearance.AppendAttachment(new AvatarAttachment((OSDMap)o));
|
||||
}
|
||||
}
|
||||
@@ -635,7 +635,7 @@ namespace OpenSim.Framework
|
||||
// end of code to remove
|
||||
|
||||
if (args.ContainsKey("packed_appearance") && (args["packed_appearance"]).Type == OSDType.Map)
|
||||
Appearance = new AvatarAppearance(AgentID,(OSDMap)args["packed_appearance"]);
|
||||
Appearance = new AvatarAppearance((OSDMap)args["packed_appearance"]);
|
||||
else
|
||||
m_log.WarnFormat("[CHILDAGENTDATAUPDATE] No packed appearance");
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ namespace OpenSim.Framework
|
||||
UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection,
|
||||
bool RezSelected, bool RemoveItem, UUID fromTaskID);
|
||||
|
||||
public delegate UUID RezSingleAttachmentFromInv(IClientAPI remoteClient, UUID itemID, uint AttachmentPt);
|
||||
public delegate ISceneEntity RezSingleAttachmentFromInv(IClientAPI remoteClient, UUID itemID, uint AttachmentPt);
|
||||
|
||||
public delegate void RezMultipleAttachmentsFromInv(IClientAPI remoteClient, RezMultipleAttachmentsFromInvPacket.HeaderDataBlock header,
|
||||
RezMultipleAttachmentsFromInvPacket.ObjectDataBlock[] objects);
|
||||
@@ -83,7 +83,7 @@ namespace OpenSim.Framework
|
||||
IClientAPI remoteClient, ulong regionHandle, Vector3 position, Vector3 lookAt, uint flags);
|
||||
|
||||
public delegate void TeleportLandmarkRequest(
|
||||
IClientAPI remoteClient, UUID regionID, Vector3 position);
|
||||
IClientAPI remoteClient, AssetLandmark lm);
|
||||
|
||||
public delegate void DisconnectUser();
|
||||
|
||||
@@ -741,7 +741,7 @@ namespace OpenSim.Framework
|
||||
bool IsActive { get; set; }
|
||||
|
||||
/// <value>
|
||||
/// Determines whether the client is logging out or not.
|
||||
/// Determines whether the client is or has been removed from a given scene
|
||||
/// </value>
|
||||
bool IsLoggingOut { get; set; }
|
||||
|
||||
@@ -790,7 +790,7 @@ namespace OpenSim.Framework
|
||||
event DeRezObject OnDeRezObject;
|
||||
event Action<IClientAPI> OnRegionHandShakeReply;
|
||||
event GenericCall1 OnRequestWearables;
|
||||
event GenericCall1 OnCompleteMovementToRegion;
|
||||
event Action<IClientAPI, bool> OnCompleteMovementToRegion;
|
||||
event UpdateAgent OnPreAgentUpdate;
|
||||
event UpdateAgent OnAgentUpdate;
|
||||
event AgentRequestSit OnAgentRequestSit;
|
||||
@@ -940,7 +940,7 @@ namespace OpenSim.Framework
|
||||
event ScriptReset OnScriptReset;
|
||||
event GetScriptRunning OnGetScriptRunning;
|
||||
event SetScriptRunning OnSetScriptRunning;
|
||||
event UpdateVector OnAutoPilotGo;
|
||||
event Action<Vector3, bool> OnAutoPilotGo;
|
||||
|
||||
event TerrainUnacked OnUnackedTerrain;
|
||||
event ActivateGesture OnActivateGesture;
|
||||
@@ -1165,7 +1165,19 @@ namespace OpenSim.Framework
|
||||
void SendAgentAlertMessage(string message, bool modal);
|
||||
void SendLoadURL(string objectname, UUID objectID, UUID ownerID, bool groupOwned, string message, string url);
|
||||
|
||||
void SendDialog(string objectname, UUID objectID, string ownerFirstName, string ownerLastName, string msg, UUID textureID, int ch,
|
||||
/// <summary>
|
||||
/// Open a dialog box on the client.
|
||||
/// </summary>
|
||||
/// <param name="objectname"></param>
|
||||
/// <param name="objectID"></param>
|
||||
/// <param name="ownerID">/param>
|
||||
/// <param name="ownerFirstName"></param>
|
||||
/// <param name="ownerLastName"></param>
|
||||
/// <param name="msg"></param>
|
||||
/// <param name="textureID"></param>
|
||||
/// <param name="ch"></param>
|
||||
/// <param name="buttonlabels"></param>
|
||||
void SendDialog(string objectname, UUID objectID, UUID ownerID, string ownerFirstName, string ownerLastName, string msg, UUID textureID, int ch,
|
||||
string[] buttonlabels);
|
||||
|
||||
bool AddMoney(int debit);
|
||||
@@ -1389,7 +1401,7 @@ namespace OpenSim.Framework
|
||||
void SendGroupTransactionsSummaryDetails(IClientAPI sender,UUID groupID, UUID transactionID, UUID sessionID,int amt);
|
||||
|
||||
void SendChangeUserRights(UUID agentID, UUID friendID, int rights);
|
||||
void SendTextBoxRequest(string message, int chatChannel, string objectname, string ownerFirstName, string ownerLastName, UUID objectId);
|
||||
void SendTextBoxRequest(string message, int chatChannel, string objectname, UUID ownerID, string ownerFirstName, string ownerLastName, UUID objectId);
|
||||
|
||||
void StopFlying(ISceneEntity presence);
|
||||
|
||||
|
||||
@@ -70,8 +70,20 @@ namespace OpenSim.Framework
|
||||
|
||||
event restart OnRestart;
|
||||
|
||||
void AddNewClient(IClientAPI client);
|
||||
void RemoveClient(UUID agentID);
|
||||
/// <summary>
|
||||
/// Register the new client with the scene. The client starts off as a child agent - the later agent crossing
|
||||
/// will promote it to a root agent.
|
||||
/// </summary>
|
||||
/// <param name="client"></param>
|
||||
/// <param name="type">The type of agent to add.</param>
|
||||
void AddNewClient(IClientAPI client, PresenceType type);
|
||||
|
||||
/// <summary>
|
||||
/// Remove the given client from the scene.
|
||||
/// </summary>
|
||||
/// <param name="agentID"></param>
|
||||
/// <param name="closeChildAgents">Close the neighbour child agents associated with this client.</param>
|
||||
void RemoveClient(UUID agentID, bool closeChildAgents);
|
||||
|
||||
void Restart();
|
||||
//RegionInfo OtherRegionUp(RegionInfo thisRegion);
|
||||
|
||||
@@ -31,6 +31,7 @@ namespace OpenSim.Framework
|
||||
{
|
||||
public interface ISceneEntity
|
||||
{
|
||||
string Name { get; set; }
|
||||
UUID UUID { get; }
|
||||
uint LocalId { get; }
|
||||
Vector3 AbsolutePosition { get; }
|
||||
|
||||
@@ -27,13 +27,15 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using log4net;
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace OpenSim.Framework
|
||||
{
|
||||
public class InventoryFolderImpl : InventoryFolderBase
|
||||
{
|
||||
//private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
public static readonly string PATH_DELIMITER = "/";
|
||||
|
||||
@@ -402,6 +404,10 @@ namespace OpenSim.Framework
|
||||
{
|
||||
foreach (InventoryItemBase item in Items.Values)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[INVENTORY FOLDER IMPL]: Returning item {0} {1}, OwnerPermissions {2:X}",
|
||||
// item.Name, item.ID, item.CurrentPermissions);
|
||||
|
||||
itemList.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,6 +144,7 @@ namespace OpenSim.Framework
|
||||
m_log.WarnFormat("[PACKETPOOL]: Failed to get packet of type {0}", type);
|
||||
else
|
||||
packet.FromBytes(bytes, ref i, ref packetEnd, zeroBuffer);
|
||||
|
||||
return packet;
|
||||
}
|
||||
|
||||
@@ -160,19 +161,18 @@ namespace OpenSim.Framework
|
||||
case PacketType.ObjectUpdate:
|
||||
ObjectUpdatePacket oup = (ObjectUpdatePacket)packet;
|
||||
|
||||
foreach (ObjectUpdatePacket.ObjectDataBlock oupod in
|
||||
oup.ObjectData)
|
||||
foreach (ObjectUpdatePacket.ObjectDataBlock oupod in oup.ObjectData)
|
||||
ReturnDataBlock<ObjectUpdatePacket.ObjectDataBlock>(oupod);
|
||||
|
||||
oup.ObjectData = null;
|
||||
break;
|
||||
|
||||
case PacketType.ImprovedTerseObjectUpdate:
|
||||
ImprovedTerseObjectUpdatePacket itoup =
|
||||
(ImprovedTerseObjectUpdatePacket)packet;
|
||||
ImprovedTerseObjectUpdatePacket itoup = (ImprovedTerseObjectUpdatePacket)packet;
|
||||
|
||||
foreach (ImprovedTerseObjectUpdatePacket.ObjectDataBlock
|
||||
itoupod in itoup.ObjectData)
|
||||
foreach (ImprovedTerseObjectUpdatePacket.ObjectDataBlock itoupod in itoup.ObjectData)
|
||||
ReturnDataBlock<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>(itoupod);
|
||||
|
||||
itoup.ObjectData = null;
|
||||
break;
|
||||
}
|
||||
@@ -194,6 +194,7 @@ namespace OpenSim.Framework
|
||||
{
|
||||
pool[type] = new Stack<Packet>();
|
||||
}
|
||||
|
||||
if ((pool[type]).Count < 50)
|
||||
{
|
||||
(pool[type]).Push(packet);
|
||||
@@ -223,6 +224,7 @@ namespace OpenSim.Framework
|
||||
{
|
||||
DataBlocks[typeof(T)] = new Stack<Object>();
|
||||
}
|
||||
|
||||
return new T();
|
||||
}
|
||||
}
|
||||
@@ -234,6 +236,9 @@ namespace OpenSim.Framework
|
||||
|
||||
lock (DataBlocks)
|
||||
{
|
||||
if (!DataBlocks.ContainsKey(typeof(T)))
|
||||
DataBlocks[typeof(T)] = new Stack<Object>();
|
||||
|
||||
if (DataBlocks[typeof(T)].Count < 50)
|
||||
DataBlocks[typeof(T)].Push(block);
|
||||
}
|
||||
|
||||
@@ -24,17 +24,16 @@
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
using System;
|
||||
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
|
||||
namespace OpenSim.Region.CoreModules.Avatar.NPC
|
||||
namespace OpenSim.Framework
|
||||
{
|
||||
public interface INPCModule
|
||||
/// <summary>
|
||||
/// Indicate the type of ScenePresence.
|
||||
/// </summary>
|
||||
public enum PresenceType
|
||||
{
|
||||
UUID CreateNPC(string firstname, string lastname, Vector3 position, Scene scene, UUID cloneAppearanceFrom);
|
||||
void Autopilot(UUID agentID, Scene scene, Vector3 pos);
|
||||
void Say(UUID agentID, Scene scene, string text);
|
||||
void DeleteNPC(UUID agentID, Scene scene);
|
||||
User,
|
||||
Npc
|
||||
}
|
||||
}
|
||||
@@ -213,6 +213,8 @@ namespace OpenSim.Framework
|
||||
/// <param name="prim"></param>
|
||||
public PrimitiveBaseShape(Primitive prim)
|
||||
{
|
||||
// m_log.DebugFormat("[PRIMITIVE BASE SHAPE]: Creating from {0}", prim.ID);
|
||||
|
||||
PCode = (byte)prim.PrimData.PCode;
|
||||
ExtraParams = new byte[1];
|
||||
|
||||
@@ -376,7 +378,7 @@ namespace OpenSim.Framework
|
||||
_pathEnd = Primitive.PackEndCut(end);
|
||||
}
|
||||
|
||||
public void SetSculptData(byte sculptType, UUID SculptTextureUUID)
|
||||
public void SetSculptProperties(byte sculptType, UUID SculptTextureUUID)
|
||||
{
|
||||
_sculptType = sculptType;
|
||||
_sculptTexture = SculptTextureUUID;
|
||||
@@ -613,29 +615,39 @@ namespace OpenSim.Framework
|
||||
}
|
||||
}
|
||||
|
||||
public byte SculptType {
|
||||
get {
|
||||
public byte SculptType
|
||||
{
|
||||
get
|
||||
{
|
||||
return _sculptType;
|
||||
}
|
||||
set {
|
||||
set
|
||||
{
|
||||
_sculptType = value;
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] SculptData {
|
||||
get {
|
||||
public byte[] SculptData
|
||||
{
|
||||
get
|
||||
{
|
||||
return _sculptData;
|
||||
}
|
||||
set {
|
||||
set
|
||||
{
|
||||
// m_log.DebugFormat("[PRIMITIVE BASE SHAPE]: Setting SculptData to data with length {0}", value.Length);
|
||||
_sculptData = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int FlexiSoftness {
|
||||
get {
|
||||
public int FlexiSoftness
|
||||
{
|
||||
get
|
||||
{
|
||||
return _flexiSoftness;
|
||||
}
|
||||
set {
|
||||
set
|
||||
{
|
||||
_flexiSoftness = value;
|
||||
}
|
||||
}
|
||||
@@ -867,8 +879,71 @@ namespace OpenSim.Framework
|
||||
}
|
||||
}
|
||||
|
||||
public ulong GetMeshKey(Vector3 size, float lod)
|
||||
{
|
||||
ulong hash = 5381;
|
||||
|
||||
hash = djb2(hash, this.PathCurve);
|
||||
hash = djb2(hash, (byte)((byte)this.HollowShape | (byte)this.ProfileShape));
|
||||
hash = djb2(hash, this.PathBegin);
|
||||
hash = djb2(hash, this.PathEnd);
|
||||
hash = djb2(hash, this.PathScaleX);
|
||||
hash = djb2(hash, this.PathScaleY);
|
||||
hash = djb2(hash, this.PathShearX);
|
||||
hash = djb2(hash, this.PathShearY);
|
||||
hash = djb2(hash, (byte)this.PathTwist);
|
||||
hash = djb2(hash, (byte)this.PathTwistBegin);
|
||||
hash = djb2(hash, (byte)this.PathRadiusOffset);
|
||||
hash = djb2(hash, (byte)this.PathTaperX);
|
||||
hash = djb2(hash, (byte)this.PathTaperY);
|
||||
hash = djb2(hash, this.PathRevolutions);
|
||||
hash = djb2(hash, (byte)this.PathSkew);
|
||||
hash = djb2(hash, this.ProfileBegin);
|
||||
hash = djb2(hash, this.ProfileEnd);
|
||||
hash = djb2(hash, this.ProfileHollow);
|
||||
|
||||
// TODO: Separate scale out from the primitive shape data (after
|
||||
// scaling is supported at the physics engine level)
|
||||
byte[] scaleBytes = size.GetBytes();
|
||||
for (int i = 0; i < scaleBytes.Length; i++)
|
||||
hash = djb2(hash, scaleBytes[i]);
|
||||
|
||||
// Include LOD in hash, accounting for endianness
|
||||
byte[] lodBytes = new byte[4];
|
||||
Buffer.BlockCopy(BitConverter.GetBytes(lod), 0, lodBytes, 0, 4);
|
||||
if (!BitConverter.IsLittleEndian)
|
||||
{
|
||||
Array.Reverse(lodBytes, 0, 4);
|
||||
}
|
||||
for (int i = 0; i < lodBytes.Length; i++)
|
||||
hash = djb2(hash, lodBytes[i]);
|
||||
|
||||
// include sculpt UUID
|
||||
if (this.SculptEntry)
|
||||
{
|
||||
scaleBytes = this.SculptTexture.GetBytes();
|
||||
for (int i = 0; i < scaleBytes.Length; i++)
|
||||
hash = djb2(hash, scaleBytes[i]);
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
private ulong djb2(ulong hash, byte c)
|
||||
{
|
||||
return ((hash << 5) + hash) + (ulong)c;
|
||||
}
|
||||
|
||||
private ulong djb2(ulong hash, ushort c)
|
||||
{
|
||||
hash = ((hash << 5) + hash) + (ulong)((byte)c);
|
||||
return ((hash << 5) + hash) + (ulong)(c >> 8);
|
||||
}
|
||||
|
||||
public byte[] ExtraParamsToBytes()
|
||||
{
|
||||
// m_log.DebugFormat("[EXTRAPARAMS]: Called ExtraParamsToBytes()");
|
||||
|
||||
ushort FlexiEP = 0x10;
|
||||
ushort LightEP = 0x20;
|
||||
ushort SculptEP = 0x30;
|
||||
@@ -884,18 +959,21 @@ namespace OpenSim.Framework
|
||||
TotalBytesLength += 16;// data
|
||||
TotalBytesLength += 2 + 4; // type
|
||||
}
|
||||
|
||||
if (_lightEntry)
|
||||
{
|
||||
ExtraParamsNum++;
|
||||
TotalBytesLength += 16;// data
|
||||
TotalBytesLength += 2 + 4; // type
|
||||
}
|
||||
|
||||
if (_sculptEntry)
|
||||
{
|
||||
ExtraParamsNum++;
|
||||
TotalBytesLength += 17;// data
|
||||
TotalBytesLength += 2 + 4; // type
|
||||
}
|
||||
|
||||
if (_projectionEntry)
|
||||
{
|
||||
ExtraParamsNum++;
|
||||
@@ -905,7 +983,6 @@ namespace OpenSim.Framework
|
||||
|
||||
byte[] returnbytes = new byte[TotalBytesLength];
|
||||
|
||||
|
||||
// uint paramlength = ExtraParamsNum;
|
||||
|
||||
// Stick in the number of parameters
|
||||
@@ -925,6 +1002,7 @@ namespace OpenSim.Framework
|
||||
Array.Copy(FlexiData, 0, returnbytes, i, FlexiData.Length);
|
||||
i += FlexiData.Length;
|
||||
}
|
||||
|
||||
if (_lightEntry)
|
||||
{
|
||||
byte[] LightData = GetLightBytes();
|
||||
@@ -939,6 +1017,7 @@ namespace OpenSim.Framework
|
||||
Array.Copy(LightData, 0, returnbytes, i, LightData.Length);
|
||||
i += LightData.Length;
|
||||
}
|
||||
|
||||
if (_sculptEntry)
|
||||
{
|
||||
byte[] SculptData = GetSculptBytes();
|
||||
@@ -953,6 +1032,7 @@ namespace OpenSim.Framework
|
||||
Array.Copy(SculptData, 0, returnbytes, i, SculptData.Length);
|
||||
i += SculptData.Length;
|
||||
}
|
||||
|
||||
if (_projectionEntry)
|
||||
{
|
||||
byte[] ProjectionData = GetProjectionBytes();
|
||||
@@ -966,6 +1046,7 @@ namespace OpenSim.Framework
|
||||
Array.Copy(ProjectionData, 0, returnbytes, i, ProjectionData.Length);
|
||||
i += ProjectionData.Length;
|
||||
}
|
||||
|
||||
if (!_flexiEntry && !_lightEntry && !_sculptEntry && !_projectionEntry)
|
||||
{
|
||||
byte[] returnbyte = new byte[1];
|
||||
@@ -973,10 +1054,7 @@ namespace OpenSim.Framework
|
||||
return returnbyte;
|
||||
}
|
||||
|
||||
|
||||
return returnbytes;
|
||||
//m_log.Info("[EXTRAPARAMS]: Length = " + m_shape.ExtraParams.Length.ToString());
|
||||
|
||||
}
|
||||
|
||||
public void ReadInUpdateExtraParam(ushort type, bool inUse, byte[] data)
|
||||
@@ -1047,7 +1125,6 @@ namespace OpenSim.Framework
|
||||
extraParamCount = data[i++];
|
||||
}
|
||||
|
||||
|
||||
for (int k = 0; k < extraParamCount; k++)
|
||||
{
|
||||
ushort epType = Utils.BytesToUInt16(data, i);
|
||||
@@ -1091,7 +1168,6 @@ namespace OpenSim.Framework
|
||||
_sculptEntry = false;
|
||||
if (!lGotFilter)
|
||||
_projectionEntry = false;
|
||||
|
||||
}
|
||||
|
||||
public void ReadSculptData(byte[] data, int pos)
|
||||
@@ -1120,6 +1196,7 @@ namespace OpenSim.Framework
|
||||
if (_sculptType != (byte)1 && _sculptType != (byte)2 && _sculptType != (byte)3 && _sculptType != (byte)4)
|
||||
_sculptType = 4;
|
||||
}
|
||||
|
||||
_sculptTexture = SculptUUID;
|
||||
_sculptType = SculptTypel;
|
||||
//m_log.Info("[SCULPT]:" + SculptUUID.ToString());
|
||||
|
||||
@@ -769,10 +769,10 @@ namespace OpenSim.Framework
|
||||
"Clamp prims to max size", "false", true);
|
||||
|
||||
configMember.addConfigurationOption("object_capacity", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
|
||||
"Max objects this sim will hold", "0", true);
|
||||
|
||||
"Max objects this sim will hold", "15000", true);
|
||||
|
||||
configMember.addConfigurationOption("agent_capacity", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
|
||||
"Max agents this sim will hold", "0", true);
|
||||
"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);
|
||||
|
||||
@@ -397,5 +397,18 @@ namespace OpenSim.Framework
|
||||
set { m_LoadedCreationID = value; }
|
||||
}
|
||||
|
||||
private bool m_GodBlockSearch = false;
|
||||
public bool GodBlockSearch
|
||||
{
|
||||
get { return m_GodBlockSearch; }
|
||||
set { m_GodBlockSearch = value; }
|
||||
}
|
||||
|
||||
private bool m_Casino = false;
|
||||
public bool Casino
|
||||
{
|
||||
get { return m_Casino; }
|
||||
set { m_Casino = value; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,6 +182,9 @@ namespace OpenSim.Framework.Serialization.External
|
||||
case "FixedSun":
|
||||
settings.FixedSun = bool.Parse(xtr.ReadElementContentAsString());
|
||||
break;
|
||||
case "SunPosition":
|
||||
settings.SunPosition = double.Parse(xtr.ReadElementContentAsString());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -237,8 +240,9 @@ namespace OpenSim.Framework.Serialization.External
|
||||
xtw.WriteElementString("TerrainLowerLimit", settings.TerrainLowerLimit.ToString());
|
||||
xtw.WriteElementString("UseEstateSun", settings.UseEstateSun.ToString());
|
||||
xtw.WriteElementString("FixedSun", settings.FixedSun.ToString());
|
||||
// XXX: Need to expose interface to get sun phase information from sun module
|
||||
// xtw.WriteStartElement("SunPhase",
|
||||
xtw.WriteElementString("SunPosition", settings.SunPosition.ToString());
|
||||
// Note: 'SunVector' isn't saved because this value is owned by the Sun Module, which
|
||||
// calculates it automatically according to the date and other factors.
|
||||
xtw.WriteEndElement();
|
||||
|
||||
xtw.WriteEndElement();
|
||||
|
||||
@@ -31,6 +31,7 @@ using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using System.Timers;
|
||||
using log4net;
|
||||
@@ -124,7 +125,6 @@ namespace OpenSim.Framework.Servers
|
||||
m_logFileAppender = appender;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -443,45 +443,68 @@ namespace OpenSim.Framework.Servers
|
||||
{
|
||||
string buildVersion = string.Empty;
|
||||
|
||||
// Add commit hash and date information if available
|
||||
// The commit hash and date are stored in a file bin/.version
|
||||
// This file can automatically created by a post
|
||||
// commit script in the opensim git master repository or
|
||||
// by issuing the follwoing command from the top level
|
||||
// directory of the opensim repository
|
||||
// git log -n 1 --pretty="format:%h: %ci" >bin/.version
|
||||
// For the full git commit hash use %H instead of %h
|
||||
//
|
||||
// The subversion information is deprecated and will be removed at a later date
|
||||
// Add subversion revision information if available
|
||||
// Try file "svn_revision" in the current directory first, then the .svn info.
|
||||
// This allows to make the revision available in simulators not running from the source tree.
|
||||
// FIXME: Making an assumption about the directory we're currently in - we do this all over the place
|
||||
// elsewhere as well
|
||||
string gitDir = "../.git/";
|
||||
string gitRefPointerPath = gitDir + "HEAD";
|
||||
|
||||
string svnRevisionFileName = "svn_revision";
|
||||
string svnFileName = ".svn/entries";
|
||||
string gitCommitFileName = ".version";
|
||||
string manualVersionFileName = ".version";
|
||||
string inputLine;
|
||||
int strcmp;
|
||||
|
||||
if (File.Exists(gitCommitFileName))
|
||||
if (File.Exists(manualVersionFileName))
|
||||
{
|
||||
StreamReader CommitFile = File.OpenText(gitCommitFileName);
|
||||
buildVersion = CommitFile.ReadLine();
|
||||
CommitFile.Close();
|
||||
using (StreamReader CommitFile = File.OpenText(manualVersionFileName))
|
||||
buildVersion = CommitFile.ReadLine();
|
||||
|
||||
m_version += buildVersion ?? "";
|
||||
}
|
||||
else if (File.Exists(gitRefPointerPath))
|
||||
{
|
||||
// m_log.DebugFormat("[OPENSIM]: Found {0}", gitRefPointerPath);
|
||||
|
||||
// Remove the else logic when subversion mirror is no longer used
|
||||
string rawPointer = "";
|
||||
|
||||
using (StreamReader pointerFile = File.OpenText(gitRefPointerPath))
|
||||
rawPointer = pointerFile.ReadLine();
|
||||
|
||||
// m_log.DebugFormat("[OPENSIM]: rawPointer [{0}]", rawPointer);
|
||||
|
||||
Match m = Regex.Match(rawPointer, "^ref: (.+)$");
|
||||
|
||||
if (m.Success)
|
||||
{
|
||||
// m_log.DebugFormat("[OPENSIM]: Matched [{0}]", m.Groups[1].Value);
|
||||
|
||||
string gitRef = m.Groups[1].Value;
|
||||
string gitRefPath = gitDir + gitRef;
|
||||
if (File.Exists(gitRefPath))
|
||||
{
|
||||
// m_log.DebugFormat("[OPENSIM]: Found gitRefPath [{0}]", gitRefPath);
|
||||
|
||||
using (StreamReader refFile = File.OpenText(gitRefPath))
|
||||
{
|
||||
string gitHash = refFile.ReadLine();
|
||||
m_version += gitHash.Substring(0, 7);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Remove the else logic when subversion mirror is no longer used
|
||||
if (File.Exists(svnRevisionFileName))
|
||||
{
|
||||
StreamReader RevisionFile = File.OpenText(svnRevisionFileName);
|
||||
buildVersion = RevisionFile.ReadLine();
|
||||
buildVersion.Trim();
|
||||
RevisionFile.Close();
|
||||
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(buildVersion) && File.Exists(svnFileName))
|
||||
|
||||
@@ -56,7 +56,6 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
private volatile int NotSocketErrors = 0;
|
||||
public volatile bool HTTPDRunning = false;
|
||||
|
||||
protected Thread m_workerThread;
|
||||
// protected HttpListener m_httpListener;
|
||||
protected CoolHTTPListener m_httpListener2;
|
||||
protected Dictionary<string, XmlRpcMethod> m_rpcHandlers = new Dictionary<string, XmlRpcMethod>();
|
||||
@@ -66,7 +65,6 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
protected Dictionary<string, IRequestHandler> m_streamHandlers = new Dictionary<string, IRequestHandler>();
|
||||
protected Dictionary<string, GenericHTTPMethod> m_HTTPHandlers = new Dictionary<string, GenericHTTPMethod>();
|
||||
protected Dictionary<string, IHttpAgentHandler> m_agentHandlers = new Dictionary<string, IHttpAgentHandler>();
|
||||
|
||||
protected Dictionary<string, PollServiceEventArgs> m_pollHandlers =
|
||||
new Dictionary<string, PollServiceEventArgs>();
|
||||
|
||||
@@ -155,7 +153,8 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
|
||||
public List<string> GetStreamHandlerKeys()
|
||||
{
|
||||
return new List<string>(m_streamHandlers.Keys);
|
||||
lock (m_streamHandlers)
|
||||
return new List<string>(m_streamHandlers.Keys);
|
||||
}
|
||||
|
||||
private static string GetHandlerKey(string httpMethod, string path)
|
||||
@@ -196,7 +195,8 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
|
||||
public List<string> GetXmlRpcHandlerKeys()
|
||||
{
|
||||
return new List<string>(m_rpcHandlers.Keys);
|
||||
lock (m_rpcHandlers)
|
||||
return new List<string>(m_rpcHandlers.Keys);
|
||||
}
|
||||
|
||||
public bool AddHTTPHandler(string methodName, GenericHTTPMethod handler)
|
||||
@@ -218,10 +218,10 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
|
||||
public List<string> GetHTTPHandlerKeys()
|
||||
{
|
||||
return new List<string>(m_HTTPHandlers.Keys);
|
||||
lock (m_HTTPHandlers)
|
||||
return new List<string>(m_HTTPHandlers.Keys);
|
||||
}
|
||||
|
||||
|
||||
public bool AddPollServiceHTTPHandler(string methodName, GenericHTTPMethod handler, PollServiceEventArgs args)
|
||||
{
|
||||
bool pollHandlerResult = false;
|
||||
@@ -242,10 +242,10 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
|
||||
public List<string> GetPollServiceHandlerKeys()
|
||||
{
|
||||
return new List<string>(m_pollHandlers.Keys);
|
||||
lock (m_pollHandlers)
|
||||
return new List<string>(m_pollHandlers.Keys);
|
||||
}
|
||||
|
||||
|
||||
// Note that the agent string is provided simply to differentiate
|
||||
// the handlers - it is NOT required to be an actual agent header
|
||||
// value.
|
||||
@@ -266,7 +266,8 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
|
||||
public List<string> GetAgentHandlerKeys()
|
||||
{
|
||||
return new List<string>(m_agentHandlers.Keys);
|
||||
lock (m_agentHandlers)
|
||||
return new List<string>(m_agentHandlers.Keys);
|
||||
}
|
||||
|
||||
public bool AddLLSDHandler(string path, LLSDMethod handler)
|
||||
@@ -284,7 +285,8 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
|
||||
public List<string> GetLLSDHandlerKeys()
|
||||
{
|
||||
return new List<string>(m_llsdHandlers.Keys);
|
||||
lock (m_llsdHandlers)
|
||||
return new List<string>(m_llsdHandlers.Keys);
|
||||
}
|
||||
|
||||
public bool SetDefaultLLSDHandler(DefaultLLSDMethod handler)
|
||||
@@ -404,15 +406,15 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
string requestMethod = request.HttpMethod;
|
||||
string uriString = request.RawUrl;
|
||||
|
||||
string reqnum = "unknown";
|
||||
// string reqnum = "unknown";
|
||||
int tickstart = Environment.TickCount;
|
||||
|
||||
try
|
||||
{
|
||||
// OpenSim.Framework.WebUtil.OSHeaderRequestID
|
||||
if (request.Headers["opensim-request-id"] != null)
|
||||
reqnum = String.Format("{0}:{1}",request.RemoteIPEndPoint,request.Headers["opensim-request-id"]);
|
||||
// m_log.DebugFormat("[BASE HTTP SERVER]: <{0}> handle request for {1}",reqnum,request.RawUrl);
|
||||
// if (request.Headers["opensim-request-id"] != null)
|
||||
// reqnum = String.Format("{0}:{1}",request.RemoteIPEndPoint,request.Headers["opensim-request-id"]);
|
||||
//m_log.DebugFormat("[BASE HTTP SERVER]: <{0}> handle request for {1}",reqnum,request.RawUrl);
|
||||
|
||||
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US", true);
|
||||
|
||||
@@ -440,7 +442,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
string path = request.RawUrl;
|
||||
string handlerKey = GetHandlerKey(request.HttpMethod, path);
|
||||
|
||||
// m_log.DebugFormat("[BASE HTTP SERVER]: Handling {0} request for {1}", request.HttpMethod, path);
|
||||
//m_log.DebugFormat("[BASE HTTP SERVER]: Handling {0} request for {1}", request.HttpMethod, path);
|
||||
|
||||
if (TryGetStreamHandler(handlerKey, out requestHandler))
|
||||
{
|
||||
@@ -746,7 +748,8 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
private bool TryGetAgentHandler(OSHttpRequest request, OSHttpResponse response, out IHttpAgentHandler agentHandler)
|
||||
{
|
||||
agentHandler = null;
|
||||
try
|
||||
|
||||
lock (m_agentHandlers)
|
||||
{
|
||||
foreach (IHttpAgentHandler handler in m_agentHandlers.Values)
|
||||
{
|
||||
@@ -757,9 +760,6 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(KeyNotFoundException)
|
||||
{
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -803,9 +803,12 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
|
||||
XmlRpcMethod method;
|
||||
bool methodWasFound;
|
||||
bool keepAlive = false;
|
||||
lock (m_rpcHandlers)
|
||||
{
|
||||
methodWasFound = m_rpcHandlers.TryGetValue(methodName, out method);
|
||||
if (methodWasFound)
|
||||
keepAlive = m_rpcHandlersKeepAlive[methodName];
|
||||
}
|
||||
|
||||
if (methodWasFound)
|
||||
@@ -824,7 +827,6 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
}
|
||||
xmlRprcRequest.Params.Add(request.Headers.Get(xff)); // Param[3]
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
xmlRpcResponse = method(xmlRprcRequest, request.RemoteIPEndPoint);
|
||||
@@ -846,7 +848,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
}
|
||||
|
||||
// if the method wasn't found, we can't determine KeepAlive state anyway, so lets do it only here
|
||||
response.KeepAlive = m_rpcHandlersKeepAlive[methodName];
|
||||
response.KeepAlive = keepAlive;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1106,7 +1108,6 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
/// <returns>true if we have one, false if not</returns>
|
||||
private bool DoWeHaveALLSDHandler(string path)
|
||||
{
|
||||
|
||||
string[] pathbase = path.Split('/');
|
||||
string searchquery = "/";
|
||||
|
||||
@@ -1122,14 +1123,12 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
|
||||
string bestMatch = null;
|
||||
|
||||
foreach (string pattern in m_llsdHandlers.Keys)
|
||||
lock (m_llsdHandlers)
|
||||
{
|
||||
|
||||
if (searchquery.StartsWith(pattern) && searchquery.Length >= pattern.Length)
|
||||
foreach (string pattern in m_llsdHandlers.Keys)
|
||||
{
|
||||
|
||||
if (searchquery.StartsWith(pattern) && searchquery.Length >= pattern.Length)
|
||||
bestMatch = pattern;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1142,12 +1141,10 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
|
||||
if (String.IsNullOrEmpty(bestMatch))
|
||||
{
|
||||
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1232,29 +1229,32 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
|
||||
string bestMatch = null;
|
||||
|
||||
foreach (string pattern in m_llsdHandlers.Keys)
|
||||
lock (m_llsdHandlers)
|
||||
{
|
||||
if (searchquery.ToLower().StartsWith(pattern.ToLower()))
|
||||
foreach (string pattern in m_llsdHandlers.Keys)
|
||||
{
|
||||
if (String.IsNullOrEmpty(bestMatch) || searchquery.Length > bestMatch.Length)
|
||||
if (searchquery.ToLower().StartsWith(pattern.ToLower()))
|
||||
{
|
||||
// You have to specifically register for '/' and to get it, you must specificaly request it
|
||||
//
|
||||
if (pattern == "/" && searchquery == "/" || pattern != "/")
|
||||
bestMatch = pattern;
|
||||
if (String.IsNullOrEmpty(bestMatch) || searchquery.Length > bestMatch.Length)
|
||||
{
|
||||
// You have to specifically register for '/' and to get it, you must specificaly request it
|
||||
//
|
||||
if (pattern == "/" && searchquery == "/" || pattern != "/")
|
||||
bestMatch = pattern;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (String.IsNullOrEmpty(bestMatch))
|
||||
{
|
||||
llsdHandler = null;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
llsdHandler = m_llsdHandlers[bestMatch];
|
||||
return true;
|
||||
|
||||
if (String.IsNullOrEmpty(bestMatch))
|
||||
{
|
||||
llsdHandler = null;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
llsdHandler = m_llsdHandlers[bestMatch];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1523,11 +1523,20 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
//m_log.Info("[BASE HTTP SERVER]: Doing HTTP Grunt work with response");
|
||||
responsecode = (int)responsedata["int_response_code"];
|
||||
responseString = (string)responsedata["str_response_string"];
|
||||
contentType = (string)responsedata["content_type"];
|
||||
try
|
||||
{
|
||||
//m_log.Info("[BASE HTTP SERVER]: Doing HTTP Grunt work with response");
|
||||
responsecode = (int)responsedata["int_response_code"];
|
||||
responseString = (string)responsedata["str_response_string"];
|
||||
contentType = (string)responsedata["content_type"];
|
||||
}
|
||||
catch
|
||||
{
|
||||
responsecode = 500;
|
||||
responseString = "No response could be obtained";
|
||||
contentType = "text/plain";
|
||||
responsedata = new Hashtable();
|
||||
}
|
||||
}
|
||||
|
||||
if (responsedata.ContainsKey("error_status_text"))
|
||||
@@ -1807,7 +1816,8 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
|
||||
//m_log.DebugFormat("[BASE HTTP SERVER]: Removing handler key {0}", handlerKey);
|
||||
|
||||
lock (m_streamHandlers) m_streamHandlers.Remove(handlerKey);
|
||||
lock (m_streamHandlers)
|
||||
m_streamHandlers.Remove(handlerKey);
|
||||
}
|
||||
|
||||
public void RemoveHTTPHandler(string httpMethod, string path)
|
||||
@@ -1839,17 +1849,16 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
|
||||
public bool RemoveAgentHandler(string agent, IHttpAgentHandler handler)
|
||||
{
|
||||
try
|
||||
lock (m_agentHandlers)
|
||||
{
|
||||
if (handler == m_agentHandlers[agent])
|
||||
IHttpAgentHandler foundHandler;
|
||||
|
||||
if (m_agentHandlers.TryGetValue(agent, out foundHandler) && foundHandler == handler)
|
||||
{
|
||||
m_agentHandlers.Remove(agent);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch(KeyNotFoundException)
|
||||
{
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -1867,18 +1876,16 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
|
||||
public bool RemoveLLSDHandler(string path, LLSDMethod handler)
|
||||
{
|
||||
try
|
||||
lock (m_llsdHandlers)
|
||||
{
|
||||
if (handler == m_llsdHandlers[path])
|
||||
LLSDMethod foundHandler;
|
||||
|
||||
if (m_llsdHandlers.TryGetValue(path, out foundHandler) && foundHandler == handler)
|
||||
{
|
||||
m_llsdHandlers.Remove(path);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (KeyNotFoundException)
|
||||
{
|
||||
// This is an exception to prevent crashing because of invalid code
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ namespace OpenSim.Framework.Tests
|
||||
SecureSessionId = UUID.Random();
|
||||
SessionId = UUID.Random();
|
||||
|
||||
AvAppearance = new AvatarAppearance(AgentId);
|
||||
AvAppearance = new AvatarAppearance();
|
||||
VisualParams = new byte[218];
|
||||
|
||||
//body
|
||||
|
||||
@@ -68,7 +68,7 @@ namespace OpenSim.Framework.Tests
|
||||
|
||||
m_agentCircuitData1 = new AgentCircuitData();
|
||||
m_agentCircuitData1.AgentID = AgentId1;
|
||||
m_agentCircuitData1.Appearance = new AvatarAppearance(AgentId1);
|
||||
m_agentCircuitData1.Appearance = new AvatarAppearance();
|
||||
m_agentCircuitData1.BaseFolder = BaseFolder;
|
||||
m_agentCircuitData1.CapsPath = CapsPath;
|
||||
m_agentCircuitData1.child = false;
|
||||
@@ -83,7 +83,7 @@ namespace OpenSim.Framework.Tests
|
||||
|
||||
m_agentCircuitData2 = new AgentCircuitData();
|
||||
m_agentCircuitData2.AgentID = AgentId2;
|
||||
m_agentCircuitData2.Appearance = new AvatarAppearance(AgentId2);
|
||||
m_agentCircuitData2.Appearance = new AvatarAppearance();
|
||||
m_agentCircuitData2.BaseFolder = BaseFolder;
|
||||
m_agentCircuitData2.CapsPath = CapsPath;
|
||||
m_agentCircuitData2.child = false;
|
||||
|
||||
@@ -61,7 +61,7 @@ namespace OpenSim.Framework.Tests
|
||||
"Magnitude of vector was incorrect.");
|
||||
|
||||
TestDelegate d = delegate() { Util.GetNormalizedVector(v1); };
|
||||
bool causesArgumentException = TestHelper.AssertThisDelegateCausesArgumentException(d);
|
||||
bool causesArgumentException = TestHelpers.AssertThisDelegateCausesArgumentException(d);
|
||||
Assert.That(causesArgumentException, Is.True,
|
||||
"Getting magnitude of null vector did not cause argument exception.");
|
||||
|
||||
@@ -94,12 +94,12 @@ namespace OpenSim.Framework.Tests
|
||||
"Magnitude of vector was incorrect.");
|
||||
|
||||
TestDelegate d = delegate() { Util.GetNormalizedVector(v1); };
|
||||
bool causesArgumentException = TestHelper.AssertThisDelegateCausesArgumentException(d);
|
||||
bool causesArgumentException = TestHelpers.AssertThisDelegateCausesArgumentException(d);
|
||||
Assert.That(causesArgumentException, Is.True,
|
||||
"Getting magnitude of null vector did not cause argument exception.");
|
||||
|
||||
d = delegate() { Util.GetNormalizedVector(v2); };
|
||||
causesArgumentException = TestHelper.AssertThisDelegateCausesArgumentException(d);
|
||||
causesArgumentException = TestHelpers.AssertThisDelegateCausesArgumentException(d);
|
||||
Assert.That(causesArgumentException, Is.True,
|
||||
"Getting magnitude of null vector did not cause argument exception.");
|
||||
}
|
||||
@@ -122,7 +122,7 @@ namespace OpenSim.Framework.Tests
|
||||
"Magnitude of vector was incorrect.");
|
||||
|
||||
TestDelegate d = delegate() { Util.GetNormalizedVector(v1); };
|
||||
bool causesArgumentException = TestHelper.AssertThisDelegateCausesArgumentException(d);
|
||||
bool causesArgumentException = TestHelpers.AssertThisDelegateCausesArgumentException(d);
|
||||
Assert.That(causesArgumentException, Is.True,
|
||||
"Getting magnitude of null vector did not cause argument exception.");
|
||||
|
||||
|
||||
@@ -56,8 +56,13 @@ namespace OpenSim.Framework
|
||||
/// <summary>
|
||||
/// The method used by Util.FireAndForget for asynchronously firing events
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// None is used to execute the method in the same thread that made the call. It should only be used by regression
|
||||
/// test code that relies on predictable event ordering.
|
||||
/// </remarks>
|
||||
public enum FireAndForgetMethod
|
||||
{
|
||||
None,
|
||||
UnsafeQueueUserWorkItem,
|
||||
QueueUserWorkItem,
|
||||
BeginInvoke,
|
||||
@@ -89,7 +94,8 @@ namespace OpenSim.Framework
|
||||
public static readonly Regex UUIDPattern
|
||||
= new Regex("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$");
|
||||
|
||||
public static FireAndForgetMethod FireAndForgetMethod = FireAndForgetMethod.SmartThreadPool;
|
||||
public static FireAndForgetMethod DefaultFireAndForgetMethod = FireAndForgetMethod.SmartThreadPool;
|
||||
public static FireAndForgetMethod FireAndForgetMethod = DefaultFireAndForgetMethod;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the directory where the current running executable
|
||||
@@ -324,10 +330,25 @@ namespace OpenSim.Framework
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Debug utility function to convert unbroken strings of XML into something human readable for occasional debugging purposes.
|
||||
///
|
||||
/// Please don't delete me even if I appear currently unused!
|
||||
/// Debug utility function to convert OSD into formatted XML for debugging purposes.
|
||||
/// </summary>
|
||||
/// <param name="osd">
|
||||
/// A <see cref="OSD"/>
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// A <see cref="System.String"/>
|
||||
/// </returns>
|
||||
public static string GetFormattedXml(OSD osd)
|
||||
{
|
||||
return GetFormattedXml(OSDParser.SerializeLLSDXmlString(osd));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Debug utility function to convert unbroken strings of XML into something human readable for occasional debugging purposes.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Please don't delete me even if I appear currently unused!
|
||||
/// </remarks>
|
||||
/// <param name="rawXml"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetFormattedXml(string rawXml)
|
||||
@@ -431,26 +452,36 @@ namespace OpenSim.Framework
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return an SHA1 hash of the given string
|
||||
/// Return an SHA1 hash
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <returns></returns>
|
||||
|
||||
public static string SHA1Hash(string data)
|
||||
public static string SHA1Hash(string data, Encoding enc)
|
||||
{
|
||||
return SHA1Hash(data, Encoding.Default);
|
||||
return SHA1Hash(enc.GetBytes(data));
|
||||
}
|
||||
|
||||
public static string SHA1Hash(string data, Encoding encoding)
|
||||
public static string SHA1Hash(string data)
|
||||
{
|
||||
byte[] hash = ComputeSHA1Hash(data, encoding);
|
||||
return SHA1Hash(Encoding.Default.GetBytes(data));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return an SHA1 hash
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <returns></returns>
|
||||
public static string SHA1Hash(byte[] data)
|
||||
{
|
||||
byte[] hash = ComputeSHA1Hash(data);
|
||||
return BitConverter.ToString(hash).Replace("-", String.Empty);
|
||||
}
|
||||
|
||||
private static byte[] ComputeSHA1Hash(string src, Encoding encoding)
|
||||
private static byte[] ComputeSHA1Hash(byte[] src)
|
||||
{
|
||||
SHA1CryptoServiceProvider SHA1 = new SHA1CryptoServiceProvider();
|
||||
return SHA1.ComputeHash(encoding.GetBytes(src));
|
||||
return SHA1.ComputeHash(src);
|
||||
}
|
||||
|
||||
public static int fast_distance2d(int x, int y)
|
||||
@@ -1353,11 +1384,30 @@ namespace OpenSim.Framework
|
||||
return (ipaddr1 != null) ? "http://" + ipaddr1.ToString() + ":" + port1 : uri;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert a string to a byte format suitable for transport in an LLUDP packet. The output is truncated to 256 bytes if necessary.
|
||||
/// </summary>
|
||||
/// <param name="str">
|
||||
/// If null or empty, then an bytes[0] is returned.
|
||||
/// Using "\0" will return a conversion of the null character to a byte. This is not the same as bytes[0]
|
||||
/// </param>
|
||||
/// <param name="args">
|
||||
/// Arguments to substitute into the string via the {} mechanism.
|
||||
/// </param>
|
||||
/// <returns></returns>
|
||||
public static byte[] StringToBytes256(string str, params object[] args)
|
||||
{
|
||||
return StringToBytes256(string.Format(str, args));
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Convert a string to a byte format suitable for transport in an LLUDP packet. The output is truncated to 256 bytes if necessary.
|
||||
/// </summary>
|
||||
/// <param name="str">
|
||||
/// If null or empty, then an bytes[0] is returned.
|
||||
/// Using "\0" will return a conversion of the null character to a byte. This is not the same as bytes[0]
|
||||
/// </param>
|
||||
/// <returns></returns>
|
||||
public static byte[] StringToBytes256(string str)
|
||||
{
|
||||
if (String.IsNullOrEmpty(str)) { return Utils.EmptyBytes; }
|
||||
@@ -1376,11 +1426,30 @@ namespace OpenSim.Framework
|
||||
return data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert a string to a byte format suitable for transport in an LLUDP packet. The output is truncated to 1024 bytes if necessary.
|
||||
/// </summary>
|
||||
/// <param name="str">
|
||||
/// If null or empty, then an bytes[0] is returned.
|
||||
/// Using "\0" will return a conversion of the null character to a byte. This is not the same as bytes[0]
|
||||
/// </param>
|
||||
/// <param name="args">
|
||||
/// Arguments to substitute into the string via the {} mechanism.
|
||||
/// </param>
|
||||
/// <returns></returns>
|
||||
public static byte[] StringToBytes1024(string str, params object[] args)
|
||||
{
|
||||
return StringToBytes1024(string.Format(str, args));
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Convert a string to a byte format suitable for transport in an LLUDP packet. The output is truncated to 1024 bytes if necessary.
|
||||
/// </summary>
|
||||
/// <param name="str">
|
||||
/// If null or empty, then an bytes[0] is returned.
|
||||
/// Using "\0" will return a conversion of the null character to a byte. This is not the same as bytes[0]
|
||||
/// </param>
|
||||
/// <returns></returns>
|
||||
public static byte[] StringToBytes1024(string str)
|
||||
{
|
||||
if (String.IsNullOrEmpty(str)) { return Utils.EmptyBytes; }
|
||||
@@ -1486,25 +1555,47 @@ namespace OpenSim.Framework
|
||||
|
||||
public static void FireAndForget(System.Threading.WaitCallback callback, object obj)
|
||||
{
|
||||
// When OpenSim interacts with a database or sends data over the wire, it must send this in en_US culture
|
||||
// so that we don't encounter problems where, for instance, data is saved with a culture that uses commas
|
||||
// for decimals places but is read by a culture that treats commas as number seperators.
|
||||
WaitCallback realCallback = delegate(object o)
|
||||
{
|
||||
Culture.SetCurrentCulture();
|
||||
|
||||
try
|
||||
{
|
||||
callback(o);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat(
|
||||
"[UTIL]: Continuing after async_call_method thread terminated with exception {0}{1}",
|
||||
e.Message, e.StackTrace);
|
||||
}
|
||||
};
|
||||
|
||||
switch (FireAndForgetMethod)
|
||||
{
|
||||
case FireAndForgetMethod.None:
|
||||
realCallback.Invoke(obj);
|
||||
break;
|
||||
case FireAndForgetMethod.UnsafeQueueUserWorkItem:
|
||||
ThreadPool.UnsafeQueueUserWorkItem(callback, obj);
|
||||
ThreadPool.UnsafeQueueUserWorkItem(realCallback, obj);
|
||||
break;
|
||||
case FireAndForgetMethod.QueueUserWorkItem:
|
||||
ThreadPool.QueueUserWorkItem(callback, obj);
|
||||
ThreadPool.QueueUserWorkItem(realCallback, obj);
|
||||
break;
|
||||
case FireAndForgetMethod.BeginInvoke:
|
||||
FireAndForgetWrapper wrapper = FireAndForgetWrapper.Instance;
|
||||
wrapper.FireAndForget(callback, obj);
|
||||
wrapper.FireAndForget(realCallback, obj);
|
||||
break;
|
||||
case FireAndForgetMethod.SmartThreadPool:
|
||||
if (m_ThreadPool == null)
|
||||
m_ThreadPool = new SmartThreadPool(2000, 15, 2);
|
||||
m_ThreadPool.QueueWorkItem(SmartThreadPoolCallback, new object[] { callback, obj });
|
||||
m_ThreadPool.QueueWorkItem(SmartThreadPoolCallback, new object[] { realCallback, obj });
|
||||
break;
|
||||
case FireAndForgetMethod.Thread:
|
||||
Thread thread = new Thread(delegate(object o) { callback(o); });
|
||||
Thread thread = new Thread(delegate(object o) { realCallback(o); });
|
||||
thread.Start(obj);
|
||||
break;
|
||||
default:
|
||||
@@ -1706,5 +1797,68 @@ namespace OpenSim.Framework
|
||||
return (T)Enum.Parse(typeof(T), value); ;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Universal User Identifiers
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
/// <param name="value">uuid[;endpoint[;name]]</param>
|
||||
/// <param name="uuid"></param>
|
||||
/// <param name="url"></param>
|
||||
/// <param name="firstname"></param>
|
||||
/// <param name="lastname"></param>
|
||||
public static bool ParseUniversalUserIdentifier(string value, out UUID uuid, out string url, out string firstname, out string lastname, out string secret)
|
||||
{
|
||||
uuid = UUID.Zero; url = string.Empty; firstname = "Unknown"; lastname = "User"; secret = string.Empty;
|
||||
|
||||
string[] parts = value.Split(';');
|
||||
if (parts.Length >= 1)
|
||||
if (!UUID.TryParse(parts[0], out uuid))
|
||||
return false;
|
||||
|
||||
if (parts.Length >= 2)
|
||||
url = parts[1];
|
||||
|
||||
if (parts.Length >= 3)
|
||||
{
|
||||
string[] name = parts[2].Split();
|
||||
if (name.Length == 2)
|
||||
{
|
||||
firstname = name[0];
|
||||
lastname = name[1];
|
||||
}
|
||||
}
|
||||
if (parts.Length >= 4)
|
||||
secret = parts[3];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="acircuit"></param>
|
||||
/// <returns>uuid[;endpoint[;name]]</returns>
|
||||
public static string ProduceUserUniversalIdentifier(AgentCircuitData acircuit)
|
||||
{
|
||||
if (acircuit.ServiceURLs.ContainsKey("HomeURI"))
|
||||
{
|
||||
string agentsURI = acircuit.ServiceURLs["HomeURI"].ToString();
|
||||
if (!agentsURI.EndsWith("/"))
|
||||
agentsURI += "/";
|
||||
|
||||
// This is ugly, but there's no other way, given that the name is changed
|
||||
// in the agent circuit data for foreigners
|
||||
if (acircuit.lastname.Contains("@"))
|
||||
{
|
||||
string[] parts = acircuit.firstname.Split(new char[] { '.' });
|
||||
if (parts.Length == 2)
|
||||
return acircuit.AgentID.ToString() + ";" + agentsURI + ";" + parts[0] + " " + parts[1];
|
||||
}
|
||||
return acircuit.AgentID.ToString() + ";" + agentsURI + ";" + acircuit.firstname + " " + acircuit.lastname;
|
||||
}
|
||||
else
|
||||
return acircuit.AgentID.ToString();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -245,6 +245,7 @@ namespace OpenSim.Framework
|
||||
catch (Exception ex)
|
||||
{
|
||||
errorMessage = ex.Message;
|
||||
m_log.Debug("[WEB UTIL]: Exception making request: " + ex.ToString());
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -907,15 +908,6 @@ namespace OpenSim.Framework
|
||||
}
|
||||
}
|
||||
|
||||
public class SynchronousRestObjectPoster
|
||||
{
|
||||
[Obsolete]
|
||||
public static TResponse BeginPostObject<TRequest, TResponse>(string verb, string requestUrl, TRequest obj)
|
||||
{
|
||||
return SynchronousRestObjectRequester.MakeRequest<TRequest, TResponse>(verb, requestUrl, obj);
|
||||
}
|
||||
}
|
||||
|
||||
public class SynchronousRestObjectRequester
|
||||
{
|
||||
private static readonly ILog m_log =
|
||||
@@ -988,9 +980,6 @@ namespace OpenSim.Framework
|
||||
{
|
||||
using (HttpWebResponse resp = (HttpWebResponse)request.GetResponse())
|
||||
{
|
||||
if (resp.StatusCode == HttpStatusCode.NotFound)
|
||||
return deserial;
|
||||
|
||||
if (resp.ContentLength != 0)
|
||||
{
|
||||
Stream respStream = resp.GetResponseStream();
|
||||
@@ -1000,9 +989,19 @@ namespace OpenSim.Framework
|
||||
}
|
||||
else
|
||||
m_log.DebugFormat("[SynchronousRestObjectRequester]: Oops! no content found in response stream from {0} {1}", requestUrl, verb);
|
||||
|
||||
}
|
||||
}
|
||||
catch (WebException e)
|
||||
{
|
||||
HttpWebResponse hwr = (HttpWebResponse)e.Response;
|
||||
|
||||
if (hwr != null && hwr.StatusCode == HttpStatusCode.NotFound)
|
||||
return deserial;
|
||||
else
|
||||
m_log.ErrorFormat(
|
||||
"[SynchronousRestObjectRequester]: WebException {0} {1} {2} {3}",
|
||||
requestUrl, typeof(TResponse).ToString(), e.Message, e.StackTrace);
|
||||
}
|
||||
catch (System.InvalidOperationException)
|
||||
{
|
||||
// This is what happens when there is invalid XML
|
||||
|
||||
@@ -73,6 +73,7 @@ namespace OpenSim
|
||||
AppDomain.CurrentDomain.UnhandledException +=
|
||||
new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
|
||||
|
||||
|
||||
// Add the arguments supplied when running the application to the configuration
|
||||
ArgvConfigSource configSource = new ArgvConfigSource(args);
|
||||
|
||||
@@ -91,6 +92,9 @@ namespace OpenSim
|
||||
m_log.Info("[OPENSIM MAIN]: configured log4net using default OpenSim.exe.config");
|
||||
}
|
||||
|
||||
m_log.DebugFormat(
|
||||
"[OPENSIM MAIN]: System Locale is {0}", System.Threading.Thread.CurrentThread.CurrentCulture);
|
||||
|
||||
// Increase the number of IOCP threads available. Mono defaults to a tragically low number
|
||||
int workerThreads, iocpThreads;
|
||||
System.Threading.ThreadPool.GetMaxThreads(out workerThreads, out iocpThreads);
|
||||
@@ -231,6 +235,8 @@ namespace OpenSim
|
||||
configSource.Alias.AddAlias("Off", false);
|
||||
configSource.Alias.AddAlias("True", true);
|
||||
configSource.Alias.AddAlias("False", false);
|
||||
configSource.Alias.AddAlias("Yes", true);
|
||||
configSource.Alias.AddAlias("No", false);
|
||||
|
||||
configSource.AddSwitch("Startup", "background");
|
||||
configSource.AddSwitch("Startup", "inifile");
|
||||
@@ -239,6 +245,8 @@ namespace OpenSim
|
||||
configSource.AddSwitch("Startup", "physics");
|
||||
configSource.AddSwitch("Startup", "gui");
|
||||
configSource.AddSwitch("Startup", "console");
|
||||
configSource.AddSwitch("Startup", "save_crashes");
|
||||
configSource.AddSwitch("Startup", "crash_dir");
|
||||
|
||||
configSource.AddConfig("StandAlone");
|
||||
configSource.AddConfig("Network");
|
||||
|
||||
@@ -328,7 +328,7 @@ namespace OpenSim
|
||||
config.Set("meshing", "Meshmerizer");
|
||||
config.Set("physical_prim", true);
|
||||
config.Set("see_into_this_sim_from_neighbor", true);
|
||||
config.Set("serverside_object_permissions", false);
|
||||
config.Set("serverside_object_permissions", true);
|
||||
config.Set("storage_plugin", "OpenSim.Data.SQLite.dll");
|
||||
config.Set("storage_connection_string", "URI=file:OpenSim.db,version=3");
|
||||
config.Set("storage_prim_inventories", true);
|
||||
|
||||
@@ -130,7 +130,9 @@ namespace OpenSim
|
||||
//m_log.InfoFormat("[OPENSIM MAIN]: GC Latency Mode: {0}", GCSettings.LatencyMode.ToString());
|
||||
|
||||
if (m_gui) // Driven by external GUI
|
||||
{
|
||||
m_console = new CommandConsole("Region");
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (m_consoleType)
|
||||
@@ -267,12 +269,15 @@ namespace OpenSim
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "save oar",
|
||||
//"save oar [-v|--version=<N>] [-p|--profile=<url>] [<OAR path>]",
|
||||
"save oar [-p|--profile=<url>] [<OAR path>]",
|
||||
"save oar [-p|--profile=<url>] [--noassets] [--perm=<permissions>] [<OAR path>]",
|
||||
"Save a region's data to an OAR archive.",
|
||||
// "-v|--version=<N> generates scene objects as per older versions of the serialization (e.g. -v=0)" + Environment.NewLine
|
||||
"-p|--profile=<url> adds the url of the profile service to the saved user information" + Environment.NewLine
|
||||
"-p|--profile=<url> adds the url of the profile service to the saved user information." + Environment.NewLine
|
||||
+ "--noassets stops assets being saved to the OAR." + Environment.NewLine
|
||||
+ "--perm stops objects with insufficient permissions from being saved to the OAR." + Environment.NewLine
|
||||
+ " <permissions> can contain one or more of these characters: \"C\" = Copy, \"T\" = Transfer" + Environment.NewLine
|
||||
+ "The OAR path must be a filesystem path."
|
||||
+ " If this is not given then the oar is saved to region.oar in the current directory.",
|
||||
+ " If this is not given then the oar is saved to region.oar in the current directory.",
|
||||
SaveOar);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "edit scale",
|
||||
@@ -546,6 +551,7 @@ namespace OpenSim
|
||||
{
|
||||
string regionName = string.Empty;
|
||||
string regionFile = string.Empty;
|
||||
|
||||
if (cmd.Length == 3)
|
||||
{
|
||||
regionFile = cmd[2];
|
||||
@@ -555,14 +561,17 @@ namespace OpenSim
|
||||
regionName = cmd[2];
|
||||
regionFile = cmd[3];
|
||||
}
|
||||
|
||||
string extension = Path.GetExtension(regionFile).ToLower();
|
||||
bool isXml = extension.Equals(".xml");
|
||||
bool isIni = extension.Equals(".ini");
|
||||
|
||||
if (!isXml && !isIni)
|
||||
{
|
||||
MainConsole.Instance.Output("Usage: create region [\"region name\"] <region_file.ini>");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Path.IsPathRooted(regionFile))
|
||||
{
|
||||
string regionsDir = ConfigSource.Source.Configs["Startup"].GetString("regionload_regionsdir", "Regions").Trim();
|
||||
@@ -579,8 +588,18 @@ namespace OpenSim
|
||||
regInfo = new RegionInfo(regionName, regionFile, false, ConfigSource.Source, regionName);
|
||||
}
|
||||
|
||||
IScene scene;
|
||||
Scene existingScene;
|
||||
if (SceneManager.TryGetScene(regInfo.RegionID, out existingScene))
|
||||
{
|
||||
MainConsole.Instance.OutputFormat(
|
||||
"ERROR: Cannot create region {0} with ID {1}, this ID is already assigned to region {2}",
|
||||
regInfo.RegionName, regInfo.RegionID, existingScene.RegionInfo.RegionName);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
PopulateRegionEstateInfo(regInfo);
|
||||
IScene scene;
|
||||
CreateRegion(regInfo, true, out scene);
|
||||
regInfo.EstateSettings.Save();
|
||||
}
|
||||
|
||||
@@ -41,11 +41,14 @@ using OpenSim.Framework.Servers;
|
||||
using OpenSim.Framework.Servers.HttpServer;
|
||||
using OpenSim.Framework.Statistics;
|
||||
using OpenSim.Region.ClientStack;
|
||||
using OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts;
|
||||
using OpenSim.Region.Framework;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Region.Physics.Manager;
|
||||
using OpenSim.Server.Base;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using OpenSim.Services.UserAccountService;
|
||||
|
||||
namespace OpenSim
|
||||
{
|
||||
@@ -411,6 +414,9 @@ namespace OpenSim
|
||||
scene.SnmpService.BootInfo("Loading prins", scene);
|
||||
}
|
||||
|
||||
while (regionInfo.EstateSettings.EstateOwner == UUID.Zero && MainConsole.Instance != null)
|
||||
SetUpEstateOwner(scene);
|
||||
|
||||
// Prims have to be loaded after module configuration since some modules may be invoked during the load
|
||||
scene.LoadPrimsFromStorage(regionInfo.originRegionID);
|
||||
|
||||
@@ -487,10 +493,62 @@ namespace OpenSim
|
||||
}
|
||||
|
||||
scene.StartTimer();
|
||||
scene.StartTimerWatchdog();
|
||||
|
||||
scene.StartScripts();
|
||||
|
||||
return clientServer;
|
||||
}
|
||||
|
||||
private void SetUpEstateOwner(Scene scene)
|
||||
{
|
||||
RegionInfo regionInfo = scene.RegionInfo;
|
||||
|
||||
MainConsole.Instance.OutputFormat("Estate {0} has no owner set.", regionInfo.EstateSettings.EstateName);
|
||||
List<char> excluded = new List<char>(new char[1]{' '});
|
||||
string first = MainConsole.Instance.CmdPrompt("Estate owner first name", "Test", excluded);
|
||||
string last = MainConsole.Instance.CmdPrompt("Estate owner last name", "User", excluded);
|
||||
|
||||
UserAccount account = scene.UserAccountService.GetUserAccount(regionInfo.ScopeID, first, last);
|
||||
|
||||
if (account == null)
|
||||
{
|
||||
|
||||
// XXX: The LocalUserAccountServicesConnector is currently registering its inner service rather than
|
||||
// itself!
|
||||
// if (scene.UserAccountService is LocalUserAccountServicesConnector)
|
||||
// {
|
||||
// IUserAccountService innerUas
|
||||
// = ((LocalUserAccountServicesConnector)scene.UserAccountService).UserAccountService;
|
||||
//
|
||||
// m_log.DebugFormat("B {0}", innerUas.GetType());
|
||||
//
|
||||
// if (innerUas is UserAccountService)
|
||||
// {
|
||||
|
||||
if (scene.UserAccountService is UserAccountService)
|
||||
{
|
||||
string password = MainConsole.Instance.PasswdPrompt("Password");
|
||||
string email = MainConsole.Instance.CmdPrompt("Email", "");
|
||||
|
||||
// TODO: Where do we put m_regInfo.ScopeID?
|
||||
account = ((UserAccountService)scene.UserAccountService).CreateUser(first, last, password, email);
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
if (account == null)
|
||||
{
|
||||
m_log.ErrorFormat(
|
||||
"[OPENSIM]: Unable to store account. If this simulator is connected to a grid, you must create the estate owner account first.");
|
||||
}
|
||||
else
|
||||
{
|
||||
regionInfo.EstateSettings.EstateOwner = account.PrincipalID;
|
||||
regionInfo.EstateSettings.Save();
|
||||
}
|
||||
}
|
||||
|
||||
private void ShutdownRegion(Scene scene)
|
||||
{
|
||||
m_log.DebugFormat("[SHUTDOWN]: Shutting down region {0}", scene.RegionInfo.RegionName);
|
||||
@@ -918,7 +976,7 @@ namespace OpenSim
|
||||
|
||||
if (regInfo.EstateSettings.EstateID == 0) // No record at all
|
||||
{
|
||||
MainConsole.Instance.OutputFormat("Region {0} is not part of an estate.", regInfo.RegionName);
|
||||
m_log.WarnFormat("[ESTATE] Region {0} is not part of an estate.", regInfo.RegionName);
|
||||
|
||||
List<EstateSettings> estates = EstateDataService.LoadEstateSettingsAll();
|
||||
List<string> estateNames = new List<string>();
|
||||
@@ -929,7 +987,7 @@ namespace OpenSim
|
||||
{
|
||||
if (estates.Count == 0)
|
||||
{
|
||||
MainConsole.Instance.Output("No existing estates found. You must create a new one.");
|
||||
m_log.Info("[ESTATE] No existing estates found. You must create a new one.");
|
||||
|
||||
if (CreateEstate(regInfo, estateNames))
|
||||
break;
|
||||
|
||||
@@ -1,10 +1,39 @@
|
||||
using System;
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
|
||||
using OpenMetaverse;
|
||||
using OpenMetaverse.StructuredData;
|
||||
using Nini.Config;
|
||||
using log4net;
|
||||
|
||||
@@ -12,11 +41,14 @@ using OpenSim.Framework;
|
||||
using OpenSim.Framework.Capabilities;
|
||||
using OpenSim.Region.Framework;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Region.Framework.Scenes.Serialization;
|
||||
using OpenSim.Framework.Servers;
|
||||
using OpenSim.Framework.Servers.HttpServer;
|
||||
using OpenSim.Services.Interfaces;
|
||||
|
||||
using Caps = OpenSim.Framework.Capabilities.Caps;
|
||||
using OSDArray = OpenMetaverse.StructuredData.OSDArray;
|
||||
using OSDMap = OpenMetaverse.StructuredData.OSDMap;
|
||||
|
||||
namespace OpenSim.Region.ClientStack.Linden
|
||||
{
|
||||
@@ -79,7 +111,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
|
||||
private bool m_persistBakedTextures = false;
|
||||
private IAssetService m_assetService;
|
||||
private bool m_dumpAssetsToFile;
|
||||
private bool m_dumpAssetsToFile = false;
|
||||
private string m_regionName;
|
||||
|
||||
public BunchOfCaps(Scene scene, Caps caps)
|
||||
@@ -104,7 +136,6 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
TaskScriptUpdatedCall = m_Scene.CapsUpdateTaskInventoryScriptAsset;
|
||||
CAPSFetchInventoryDescendents = m_Scene.HandleFetchInventoryDescendentsCAPS;
|
||||
GetClient = m_Scene.SceneContents.GetControllingClient;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -200,7 +231,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
public string SeedCapRequest(string request, string path, string param,
|
||||
OSHttpRequest httpRequest, OSHttpResponse httpResponse)
|
||||
{
|
||||
m_log.Debug("[CAPS]: Seed Caps Request in region: " + m_regionName);
|
||||
// m_log.Debug("[CAPS]: Seed Caps Request in region: " + m_regionName);
|
||||
|
||||
if (!m_Scene.CheckClient(m_HostCapsObj.AgentID, httpRequest.RemoteIPEndPoint))
|
||||
{
|
||||
@@ -299,14 +330,22 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle a request from the client for a Uri to upload a baked texture.
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <param name="path"></param>
|
||||
/// <param name="param"></param>
|
||||
/// <param name="httpRequest"></param>
|
||||
/// <param name="httpResponse"></param>
|
||||
/// <returns>The upload response if the request is successful, null otherwise.</returns>
|
||||
public string UploadBakedTexture(string request, string path,
|
||||
string param, OSHttpRequest httpRequest,
|
||||
OSHttpResponse httpResponse)
|
||||
{
|
||||
try
|
||||
{
|
||||
// m_log.Debug("[CAPS]: UploadBakedTexture Request in region: " +
|
||||
// m_regionName);
|
||||
// m_log.Debug("[CAPS]: UploadBakedTexture Request in region: " + m_regionName);
|
||||
|
||||
string capsBase = "/CAPS/" + m_HostCapsObj.CapsObjectPath;
|
||||
string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000");
|
||||
@@ -342,6 +381,11 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when a baked texture has been successfully uploaded by a client.
|
||||
/// </summary>
|
||||
/// <param name="assetID"></param>
|
||||
/// <param name="data"></param>
|
||||
public void BakedTextureUploaded(UUID assetID, byte[] data)
|
||||
{
|
||||
// m_log.WarnFormat("[CAPS]: Received baked texture {0}", assetID.ToString());
|
||||
@@ -439,7 +483,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// Convert raw uploaded data into the appropriate asset and item.
|
||||
/// </summary>
|
||||
/// <param name="assetID"></param>
|
||||
/// <param name="inventoryItem"></param>
|
||||
@@ -448,6 +492,10 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
UUID inventoryItem, UUID parentFolder, byte[] data, string inventoryType,
|
||||
string assetType)
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"Uploaded asset {0} for inventory item {1}, inv type {2}, asset type {3}",
|
||||
assetID, inventoryItem, inventoryType, assetType);
|
||||
|
||||
sbyte assType = 0;
|
||||
sbyte inType = 0;
|
||||
|
||||
@@ -474,6 +522,160 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (inventoryType == "object")
|
||||
{
|
||||
inType = (sbyte)InventoryType.Object;
|
||||
assType = (sbyte)AssetType.Object;
|
||||
|
||||
List<Vector3> positions = new List<Vector3>();
|
||||
List<Quaternion> rotations = new List<Quaternion>();
|
||||
OSDMap request = (OSDMap)OSDParser.DeserializeLLSDXml(data);
|
||||
OSDArray instance_list = (OSDArray)request["instance_list"];
|
||||
OSDArray mesh_list = (OSDArray)request["mesh_list"];
|
||||
OSDArray texture_list = (OSDArray)request["texture_list"];
|
||||
SceneObjectGroup grp = null;
|
||||
|
||||
List<UUID> textures = new List<UUID>();
|
||||
for (int i = 0; i < texture_list.Count; i++)
|
||||
{
|
||||
AssetBase textureAsset = new AssetBase(UUID.Random(), assetName, (sbyte)AssetType.Texture, "");
|
||||
textureAsset.Data = texture_list[i].AsBinary();
|
||||
m_assetService.Store(textureAsset);
|
||||
textures.Add(textureAsset.FullID);
|
||||
}
|
||||
|
||||
for (int i = 0; i < mesh_list.Count; i++)
|
||||
{
|
||||
PrimitiveBaseShape pbs = PrimitiveBaseShape.CreateBox();
|
||||
|
||||
Primitive.TextureEntry textureEntry
|
||||
= new Primitive.TextureEntry(Primitive.TextureEntry.WHITE_TEXTURE);
|
||||
OSDMap inner_instance_list = (OSDMap)instance_list[i];
|
||||
|
||||
OSDArray face_list = (OSDArray)inner_instance_list["face_list"];
|
||||
for (uint face = 0; face < face_list.Count; face++)
|
||||
{
|
||||
OSDMap faceMap = (OSDMap)face_list[(int)face];
|
||||
Primitive.TextureEntryFace f = pbs.Textures.CreateFace(face);
|
||||
if(faceMap.ContainsKey("fullbright"))
|
||||
f.Fullbright = faceMap["fullbright"].AsBoolean();
|
||||
if (faceMap.ContainsKey ("diffuse_color"))
|
||||
f.RGBA = faceMap["diffuse_color"].AsColor4();
|
||||
|
||||
int textureNum = faceMap["image"].AsInteger();
|
||||
float imagerot = faceMap["imagerot"].AsInteger();
|
||||
float offsets = (float)faceMap["offsets"].AsReal();
|
||||
float offsett = (float)faceMap["offsett"].AsReal();
|
||||
float scales = (float)faceMap["scales"].AsReal();
|
||||
float scalet = (float)faceMap["scalet"].AsReal();
|
||||
|
||||
if(imagerot != 0)
|
||||
f.Rotation = imagerot;
|
||||
|
||||
if(offsets != 0)
|
||||
f.OffsetU = offsets;
|
||||
|
||||
if (offsett != 0)
|
||||
f.OffsetV = offsett;
|
||||
|
||||
if (scales != 0)
|
||||
f.RepeatU = scales;
|
||||
|
||||
if (scalet != 0)
|
||||
f.RepeatV = scalet;
|
||||
|
||||
if (textures.Count > textureNum)
|
||||
f.TextureID = textures[textureNum];
|
||||
else
|
||||
f.TextureID = Primitive.TextureEntry.WHITE_TEXTURE;
|
||||
|
||||
textureEntry.FaceTextures[face] = f;
|
||||
}
|
||||
|
||||
pbs.TextureEntry = textureEntry.GetBytes();
|
||||
|
||||
AssetBase meshAsset = new AssetBase(UUID.Random(), assetName, (sbyte)AssetType.Mesh, "");
|
||||
meshAsset.Data = mesh_list[i].AsBinary();
|
||||
m_assetService.Store(meshAsset);
|
||||
|
||||
pbs.SculptEntry = true;
|
||||
pbs.SculptTexture = meshAsset.FullID;
|
||||
pbs.SculptType = (byte)SculptType.Mesh;
|
||||
pbs.SculptData = meshAsset.Data;
|
||||
|
||||
Vector3 position = inner_instance_list["position"].AsVector3();
|
||||
Vector3 scale = inner_instance_list["scale"].AsVector3();
|
||||
Quaternion rotation = inner_instance_list["rotation"].AsQuaternion();
|
||||
|
||||
// no longer used - begin ------------------------
|
||||
// int physicsShapeType = inner_instance_list["physics_shape_type"].AsInteger();
|
||||
// int material = inner_instance_list["material"].AsInteger();
|
||||
// int mesh = inner_instance_list["mesh"].AsInteger();
|
||||
|
||||
// OSDMap permissions = (OSDMap)inner_instance_list["permissions"];
|
||||
// int base_mask = permissions["base_mask"].AsInteger();
|
||||
// int everyone_mask = permissions["everyone_mask"].AsInteger();
|
||||
// UUID creator_id = permissions["creator_id"].AsUUID();
|
||||
// UUID group_id = permissions["group_id"].AsUUID();
|
||||
// int group_mask = permissions["group_mask"].AsInteger();
|
||||
// bool is_owner_group = permissions["is_owner_group"].AsBoolean();
|
||||
// UUID last_owner_id = permissions["last_owner_id"].AsUUID();
|
||||
// int next_owner_mask = permissions["next_owner_mask"].AsInteger();
|
||||
// UUID owner_id = permissions["owner_id"].AsUUID();
|
||||
// int owner_mask = permissions["owner_mask"].AsInteger();
|
||||
// no longer used - end ------------------------
|
||||
|
||||
UUID owner_id = m_HostCapsObj.AgentID;
|
||||
|
||||
SceneObjectPart prim
|
||||
= new SceneObjectPart(owner_id, pbs, position, Quaternion.Identity, Vector3.Zero);
|
||||
|
||||
prim.Scale = scale;
|
||||
prim.OffsetPosition = position;
|
||||
rotations.Add(rotation);
|
||||
positions.Add(position);
|
||||
prim.UUID = UUID.Random();
|
||||
prim.CreatorID = owner_id;
|
||||
prim.OwnerID = owner_id;
|
||||
prim.GroupID = UUID.Zero;
|
||||
prim.LastOwnerID = prim.OwnerID;
|
||||
prim.CreationDate = Util.UnixTimeSinceEpoch();
|
||||
prim.Name = assetName;
|
||||
prim.Description = "";
|
||||
|
||||
// prim.BaseMask = (uint)base_mask;
|
||||
// prim.EveryoneMask = (uint)everyone_mask;
|
||||
// prim.GroupMask = (uint)group_mask;
|
||||
// prim.NextOwnerMask = (uint)next_owner_mask;
|
||||
// prim.OwnerMask = (uint)owner_mask;
|
||||
|
||||
if (grp == null)
|
||||
grp = new SceneObjectGroup(prim);
|
||||
else
|
||||
grp.AddPart(prim);
|
||||
}
|
||||
|
||||
// Fix first link number
|
||||
if (grp.Parts.Length > 1)
|
||||
grp.RootPart.LinkNum++;
|
||||
|
||||
Vector3 rootPos = positions[0];
|
||||
grp.AbsolutePosition = rootPos;
|
||||
for (int i = 0; i < positions.Count; i++)
|
||||
{
|
||||
Vector3 offset = positions[i] - rootPos;
|
||||
grp.Parts[i].OffsetPosition = offset;
|
||||
}
|
||||
|
||||
for (int i = 0; i < rotations.Count; i++)
|
||||
{
|
||||
if (i != 0)
|
||||
grp.Parts[i].RotationOffset = rotations[i];
|
||||
}
|
||||
|
||||
grp.UpdateGroupRotationR(rotations[0]);
|
||||
data = ASCIIEncoding.ASCII.GetBytes(SceneObjectSerializer.ToOriginalXmlFormat(grp));
|
||||
}
|
||||
|
||||
AssetBase asset;
|
||||
asset = new AssetBase(assetID, assetName, assType, m_HostCapsObj.AgentID.ToString());
|
||||
@@ -497,7 +699,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
item.CurrentPermissions = (uint)PermissionMask.All;
|
||||
item.BasePermissions = (uint)PermissionMask.All;
|
||||
item.EveryOnePermissions = 0;
|
||||
item.NextPermissions = (uint)(PermissionMask.Move | PermissionMask.Modify | PermissionMask.Transfer);
|
||||
item.NextPermissions = (uint)PermissionMask.All;
|
||||
item.CreationDate = Util.UnixTimeSinceEpoch();
|
||||
|
||||
if (AddNewInventoryItem != null)
|
||||
@@ -506,8 +708,6 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
@@ -632,7 +832,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// Handle raw asset upload data via the capability.
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <param name="path"></param>
|
||||
@@ -670,6 +870,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
///Left this in and commented in case there are unforseen issues
|
||||
//private void SaveAssetToFile(string filename, byte[] data)
|
||||
//{
|
||||
@@ -679,6 +880,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
// bw.Close();
|
||||
// fs.Close();
|
||||
//}
|
||||
|
||||
private static void SaveAssetToFile(string filename, byte[] data)
|
||||
{
|
||||
string assetPath = "UserAssets";
|
||||
@@ -719,7 +921,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// Handle raw uploaded asset data.
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <param name="path"></param>
|
||||
@@ -752,6 +954,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
///Left this in and commented in case there are unforseen issues
|
||||
//private void SaveAssetToFile(string filename, byte[] data)
|
||||
//{
|
||||
@@ -761,6 +964,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
// bw.Close();
|
||||
// fs.Close();
|
||||
//}
|
||||
|
||||
private static void SaveAssetToFile(string filename, byte[] data)
|
||||
{
|
||||
string assetPath = "UserAssets";
|
||||
@@ -839,7 +1043,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
uploadComplete.new_asset = inventoryItemID;
|
||||
uploadComplete.compiled = errors.Count > 0 ? false : true;
|
||||
uploadComplete.state = "complete";
|
||||
uploadComplete.errors = new OSDArray();
|
||||
uploadComplete.errors = new OpenSim.Framework.Capabilities.OSDArray();
|
||||
uploadComplete.errors.Array = errors;
|
||||
|
||||
res = LLSDHelpers.SerialiseLLSDReply(uploadComplete);
|
||||
@@ -905,7 +1109,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// Handle raw uploaded baked texture data.
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <param name="path"></param>
|
||||
@@ -935,4 +1139,4 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -48,8 +48,8 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
|
||||
public class BunchOfCapsModule : INonSharedRegionModule
|
||||
{
|
||||
private static readonly ILog m_log =
|
||||
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
// private static readonly ILog m_log =
|
||||
// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private Scene m_Scene;
|
||||
|
||||
|
||||
@@ -50,8 +50,8 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
|
||||
public class GetMeshModule : INonSharedRegionModule
|
||||
{
|
||||
private static readonly ILog m_log =
|
||||
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
// private static readonly ILog m_log =
|
||||
// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private Scene m_scene;
|
||||
private IAssetService m_AssetService;
|
||||
@@ -113,12 +113,12 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
|
||||
public void RegisterCaps(UUID agentID, Caps caps)
|
||||
{
|
||||
UUID capID = UUID.Random();
|
||||
// UUID capID = UUID.Random();
|
||||
|
||||
//caps.RegisterHandler("GetTexture", new StreamHandler("GET", "/CAPS/" + capID, ProcessGetTexture));
|
||||
if (m_URL == "localhost")
|
||||
{
|
||||
m_log.InfoFormat("[GETMESH]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName);
|
||||
// m_log.DebugFormat("[GETMESH]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName);
|
||||
GetMeshHandler gmeshHandler = new GetMeshHandler(m_AssetService);
|
||||
IRequestHandler reqHandler = new RestHTTPHandler("GET", "/CAPS/" + UUID.Random(),
|
||||
delegate(Hashtable m_dhttpMethod)
|
||||
@@ -130,7 +130,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.InfoFormat("[GETMESH]: {0} in region {1}", m_URL, m_scene.RegionInfo.RegionName);
|
||||
// m_log.DebugFormat("[GETMESH]: {0} in region {1}", m_URL, m_scene.RegionInfo.RegionName);
|
||||
caps.RegisterHandler("GetMesh", m_URL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,8 +54,9 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
|
||||
public class GetTextureModule : INonSharedRegionModule
|
||||
{
|
||||
private static readonly ILog m_log =
|
||||
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
// private static readonly ILog m_log =
|
||||
// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private Scene m_scene;
|
||||
private IAssetService m_assetService;
|
||||
|
||||
@@ -128,12 +129,12 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
//caps.RegisterHandler("GetTexture", new StreamHandler("GET", "/CAPS/" + capID, ProcessGetTexture));
|
||||
if (m_URL == "localhost")
|
||||
{
|
||||
m_log.InfoFormat("[GETTEXTURE]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName);
|
||||
// m_log.DebugFormat("[GETTEXTURE]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName);
|
||||
caps.RegisterHandler("GetTexture", new GetTextureHandler("/CAPS/" + capID + "/", m_assetService));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.InfoFormat("[GETTEXTURE]: {0} in region {1}", m_URL, m_scene.RegionInfo.RegionName);
|
||||
// m_log.DebugFormat("[GETTEXTURE]: {0} in region {1}", m_URL, m_scene.RegionInfo.RegionName);
|
||||
caps.RegisterHandler("GetTexture", m_URL);
|
||||
}
|
||||
}
|
||||
|
||||
149
OpenSim/Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs
Normal file
149
OpenSim/Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs
Normal file
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Reflection;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
using Mono.Addins;
|
||||
using OpenMetaverse;
|
||||
using OpenMetaverse.StructuredData;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Servers.HttpServer;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using Caps = OpenSim.Framework.Capabilities.Caps;
|
||||
|
||||
namespace OpenSim.Region.ClientStack.Linden
|
||||
{
|
||||
/// <summary>
|
||||
/// MeshUploadFlag capability. This is required for uploading Mesh.
|
||||
/// </summary>
|
||||
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
|
||||
public class MeshUploadFlagModule : INonSharedRegionModule
|
||||
{
|
||||
// private static readonly ILog m_log =
|
||||
// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
/// <summary>
|
||||
/// Is this module enabled?
|
||||
/// </summary>
|
||||
public bool Enabled { get; private set; }
|
||||
|
||||
private Scene m_scene;
|
||||
private UUID m_agentID;
|
||||
|
||||
#region ISharedRegionModule Members
|
||||
|
||||
public MeshUploadFlagModule()
|
||||
{
|
||||
Enabled = true;
|
||||
}
|
||||
|
||||
public void Initialise(IConfigSource source)
|
||||
{
|
||||
IConfig config = source.Configs["Mesh"];
|
||||
if (config == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
Enabled = config.GetBoolean("AllowMeshUpload", Enabled);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddRegion(Scene s)
|
||||
{
|
||||
if (!Enabled)
|
||||
return;
|
||||
|
||||
m_scene = s;
|
||||
m_scene.EventManager.OnRegisterCaps += RegisterCaps;
|
||||
}
|
||||
|
||||
public void RemoveRegion(Scene s)
|
||||
{
|
||||
if (!Enabled)
|
||||
return;
|
||||
|
||||
m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
|
||||
}
|
||||
|
||||
public void RegionLoaded(Scene s)
|
||||
{
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
}
|
||||
|
||||
public void Close() { }
|
||||
|
||||
public string Name { get { return "MeshUploadFlagModule"; } }
|
||||
|
||||
public Type ReplaceableInterface
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public void RegisterCaps(UUID agentID, Caps caps)
|
||||
{
|
||||
IRequestHandler reqHandler = new RestHTTPHandler("GET", "/CAPS/" + UUID.Random(), MeshUploadFlag);
|
||||
caps.RegisterHandler("MeshUploadFlag", reqHandler);
|
||||
m_agentID = agentID;
|
||||
}
|
||||
|
||||
private Hashtable MeshUploadFlag(Hashtable mDhttpMethod)
|
||||
{
|
||||
// m_log.DebugFormat("[MESH UPLOAD FLAG MODULE]: MeshUploadFlag request");
|
||||
|
||||
OSDMap data = new OSDMap();
|
||||
ScenePresence sp = m_scene.GetScenePresence(m_agentID);
|
||||
data["username"] = sp.Firstname + "." + sp.Lastname;
|
||||
data["display_name_next_update"] = new OSDDate(DateTime.Now);
|
||||
data["legacy_first_name"] = sp.Firstname;
|
||||
data["mesh_upload_status"] = "valid";
|
||||
data["display_name"] = sp.Firstname + " " + sp.Lastname;
|
||||
data["legacy_last_name"] = sp.Lastname;
|
||||
data["id"] = m_agentID;
|
||||
data["is_display_name_default"] = true;
|
||||
|
||||
//Send back data
|
||||
Hashtable responsedata = new Hashtable();
|
||||
responsedata["int_response_code"] = 200;
|
||||
responsedata["content_type"] = "text/plain";
|
||||
responsedata["keepalive"] = false;
|
||||
responsedata["str_response_string"] = OSDParser.SerializeLLSDXmlString(data);
|
||||
return responsedata;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -160,8 +160,6 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
}
|
||||
}
|
||||
// }
|
||||
|
||||
|
||||
|
||||
string assetName = llsdRequest.name;
|
||||
string assetDes = llsdRequest.description;
|
||||
@@ -208,12 +206,10 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
return uploadResponse;
|
||||
}
|
||||
|
||||
|
||||
public void UploadCompleteHandler(string assetName, string assetDescription, UUID assetID,
|
||||
UUID inventoryItem, UUID parentFolder, byte[] data, string inventoryType,
|
||||
string assetType,UUID AgentID)
|
||||
{
|
||||
|
||||
sbyte assType = 0;
|
||||
sbyte inType = 0;
|
||||
|
||||
@@ -266,10 +262,10 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
item.CurrentPermissions = (uint)PermissionMask.All;
|
||||
item.BasePermissions = (uint)PermissionMask.All;
|
||||
item.EveryOnePermissions = 0;
|
||||
item.NextPermissions = (uint)(PermissionMask.Move | PermissionMask.Modify | PermissionMask.Transfer);
|
||||
item.NextPermissions = (uint)PermissionMask.All;
|
||||
item.CreationDate = Util.UnixTimeSinceEpoch();
|
||||
m_scene.AddInventoryItem(item);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -322,8 +322,6 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
rootpart.NextOwnerMask = next_owner_mask;
|
||||
rootpart.Material = (byte)material;
|
||||
|
||||
|
||||
|
||||
m_scene.PhysicsScene.AddPhysicsActorTaint(rootpart.PhysActor);
|
||||
|
||||
responsedata["int_response_code"] = 200; //501; //410; //404;
|
||||
|
||||
@@ -129,7 +129,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Parses ad request
|
||||
/// Parses add request
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <param name="AgentId"></param>
|
||||
@@ -250,11 +250,9 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
case 0x40:
|
||||
pbs.ReadProjectionData(extraParam.ExtraParamData, 0);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
pbs.PathBegin = (ushort) obj.PathBegin;
|
||||
pbs.PathCurve = (byte) obj.PathCurve;
|
||||
pbs.PathEnd = (ushort) obj.PathEnd;
|
||||
@@ -314,11 +312,11 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
primFace.RepeatV = face.ScaleT;
|
||||
primFace.TexMapType = (MappingType) (face.MediaFlags & 6);
|
||||
}
|
||||
|
||||
pbs.TextureEntry = tmp.GetBytes();
|
||||
prim.Shape = pbs;
|
||||
prim.Scale = obj.Scale;
|
||||
|
||||
|
||||
SceneObjectGroup grp = new SceneObjectGroup();
|
||||
|
||||
grp.SetRootPart(prim);
|
||||
@@ -332,7 +330,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
grp.AbsolutePosition = obj.Position;
|
||||
prim.RotationOffset = obj.Rotation;
|
||||
|
||||
grp.RootPart.IsAttachment = false;
|
||||
grp.IsAttachment = false;
|
||||
// Required for linking
|
||||
grp.RootPart.UpdateFlag = 0;
|
||||
|
||||
@@ -341,8 +339,8 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
m_scene.AddSceneObject(grp);
|
||||
grp.AbsolutePosition = obj.Position;
|
||||
}
|
||||
|
||||
allparts[i] = grp;
|
||||
|
||||
}
|
||||
|
||||
for (int j = 1; j < allparts.Length; j++)
|
||||
@@ -353,7 +351,9 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
}
|
||||
|
||||
rootGroup.ScheduleGroupForFullUpdate();
|
||||
pos = m_scene.GetNewRezLocation(Vector3.Zero, rootpos, UUID.Zero, rot, (byte)1, 1, true, allparts[0].GroupScale(), false);
|
||||
pos
|
||||
= m_scene.GetNewRezLocation(
|
||||
Vector3.Zero, rootpos, UUID.Zero, rot, (byte)1, 1, true, allparts[0].GroupScale, false);
|
||||
|
||||
responsedata["int_response_code"] = 200; //501; //410; //404;
|
||||
responsedata["content_type"] = "text/plain";
|
||||
|
||||
@@ -0,0 +1,202 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Reflection;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
using Mono.Addins;
|
||||
using OpenMetaverse;
|
||||
using OpenMetaverse.StructuredData;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Servers.HttpServer;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using Caps = OpenSim.Framework.Capabilities.Caps;
|
||||
|
||||
namespace OpenSim.Region.ClientStack.Linden
|
||||
{
|
||||
/// <summary>
|
||||
/// SimulatorFeatures capability.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is required for uploading Mesh.
|
||||
/// Since is accepts an open-ended response, we also send more information
|
||||
/// for viewers that care to interpret it.
|
||||
///
|
||||
/// NOTE: Part of this code was adapted from the Aurora project, specifically
|
||||
/// the normal part of the response in the capability handler.
|
||||
/// </remarks>
|
||||
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
|
||||
public class SimulatorFeaturesModule : ISharedRegionModule, ISimulatorFeaturesModule
|
||||
{
|
||||
// private static readonly ILog m_log =
|
||||
// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private Scene m_scene;
|
||||
|
||||
/// <summary>
|
||||
/// Simulator features
|
||||
/// </summary>
|
||||
private OSDMap m_features = new OSDMap();
|
||||
|
||||
private string m_MapImageServerURL = string.Empty;
|
||||
private string m_SearchURL = string.Empty;
|
||||
|
||||
#region ISharedRegionModule Members
|
||||
|
||||
public void Initialise(IConfigSource source)
|
||||
{
|
||||
IConfig config = source.Configs["SimulatorFeatures"];
|
||||
if (config != null)
|
||||
{
|
||||
m_MapImageServerURL = config.GetString("MapImageServerURI", string.Empty);
|
||||
if (m_MapImageServerURL != string.Empty)
|
||||
{
|
||||
m_MapImageServerURL = m_MapImageServerURL.Trim();
|
||||
if (!m_MapImageServerURL.EndsWith("/"))
|
||||
m_MapImageServerURL = m_MapImageServerURL + "/";
|
||||
}
|
||||
|
||||
m_SearchURL = config.GetString("SearchServerURI", string.Empty);
|
||||
}
|
||||
|
||||
AddDefaultFeatures();
|
||||
}
|
||||
|
||||
public void AddRegion(Scene s)
|
||||
{
|
||||
m_scene = s;
|
||||
m_scene.EventManager.OnRegisterCaps += RegisterCaps;
|
||||
}
|
||||
|
||||
public void RemoveRegion(Scene s)
|
||||
{
|
||||
m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
|
||||
}
|
||||
|
||||
public void RegionLoaded(Scene s)
|
||||
{
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
}
|
||||
|
||||
public void Close() { }
|
||||
|
||||
public string Name { get { return "SimulatorFeaturesModule"; } }
|
||||
|
||||
public Type ReplaceableInterface
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Add default features
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// TODO: These should be added from other modules rather than hardcoded.
|
||||
/// </remarks>
|
||||
private void AddDefaultFeatures()
|
||||
{
|
||||
lock (m_features)
|
||||
{
|
||||
m_features["MeshRezEnabled"] = true;
|
||||
m_features["MeshUploadEnabled"] = true;
|
||||
m_features["MeshXferEnabled"] = true;
|
||||
m_features["PhysicsMaterialsEnabled"] = true;
|
||||
|
||||
OSDMap typesMap = new OSDMap();
|
||||
typesMap["convex"] = true;
|
||||
typesMap["none"] = true;
|
||||
typesMap["prim"] = true;
|
||||
m_features["PhysicsShapeTypes"] = typesMap;
|
||||
|
||||
// Extra information for viewers that want to use it
|
||||
OSDMap gridServicesMap = new OSDMap();
|
||||
if (m_MapImageServerURL != string.Empty)
|
||||
gridServicesMap["map-server-url"] = m_MapImageServerURL;
|
||||
if (m_SearchURL != string.Empty)
|
||||
gridServicesMap["search"] = m_SearchURL;
|
||||
m_features["GridServices"] = gridServicesMap;
|
||||
}
|
||||
}
|
||||
|
||||
public void RegisterCaps(UUID agentID, Caps caps)
|
||||
{
|
||||
IRequestHandler reqHandler
|
||||
= new RestHTTPHandler("GET", "/CAPS/" + UUID.Random(), HandleSimulatorFeaturesRequest);
|
||||
|
||||
caps.RegisterHandler("SimulatorFeatures", reqHandler);
|
||||
}
|
||||
|
||||
public void AddFeature(string name, OSD value)
|
||||
{
|
||||
lock (m_features)
|
||||
m_features[name] = value;
|
||||
}
|
||||
|
||||
public bool RemoveFeature(string name)
|
||||
{
|
||||
lock (m_features)
|
||||
return m_features.Remove(name);
|
||||
}
|
||||
|
||||
public bool TryGetFeature(string name, out OSD value)
|
||||
{
|
||||
lock (m_features)
|
||||
return m_features.TryGetValue(name, out value);
|
||||
}
|
||||
|
||||
public OSDMap GetFeatures()
|
||||
{
|
||||
lock (m_features)
|
||||
return new OSDMap(m_features);
|
||||
}
|
||||
|
||||
private Hashtable HandleSimulatorFeaturesRequest(Hashtable mDhttpMethod)
|
||||
{
|
||||
// m_log.DebugFormat("[SIMULATOR FEATURES MODULE]: SimulatorFeatures request");
|
||||
|
||||
//Send back data
|
||||
Hashtable responsedata = new Hashtable();
|
||||
responsedata["int_response_code"] = 200;
|
||||
responsedata["content_type"] = "text/plain";
|
||||
responsedata["keepalive"] = false;
|
||||
|
||||
lock (m_features)
|
||||
responsedata["str_response_string"] = OSDParser.SerializeLLSDXmlString(m_features);
|
||||
|
||||
return responsedata;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -90,7 +90,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
public event ObjectAttach OnObjectAttach;
|
||||
public event ObjectDeselect OnObjectDetach;
|
||||
public event ObjectDrop OnObjectDrop;
|
||||
public event GenericCall1 OnCompleteMovementToRegion;
|
||||
public event Action<IClientAPI, bool> OnCompleteMovementToRegion;
|
||||
public event UpdateAgent OnPreAgentUpdate;
|
||||
public event UpdateAgent OnAgentUpdate;
|
||||
public event AgentRequestSit OnAgentRequestSit;
|
||||
@@ -232,7 +232,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
public event ScriptReset OnScriptReset;
|
||||
public event GetScriptRunning OnGetScriptRunning;
|
||||
public event SetScriptRunning OnSetScriptRunning;
|
||||
public event UpdateVector OnAutoPilotGo;
|
||||
public event Action<Vector3, bool> OnAutoPilotGo;
|
||||
public event TerrainUnacked OnUnackedTerrain;
|
||||
public event ActivateGesture OnActivateGesture;
|
||||
public event DeactivateGesture OnDeactivateGesture;
|
||||
@@ -438,6 +438,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
|
||||
#endregion Properties
|
||||
|
||||
// ~LLClientView()
|
||||
// {
|
||||
// m_log.DebugFormat("[LLCLIENTVIEW]: Destructor called for {0}, circuit code {1}", Name, CircuitCode);
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
@@ -529,7 +534,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
m_udpServer.Flush(m_udpClient);
|
||||
|
||||
// Remove ourselves from the scene
|
||||
m_scene.RemoveClient(AgentId);
|
||||
m_scene.RemoveClient(AgentId, true);
|
||||
|
||||
// We can't reach into other scenes and close the connection
|
||||
// We need to do this over grid communications
|
||||
@@ -591,22 +596,42 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add a handler for the given packet type.
|
||||
/// </summary>
|
||||
/// <remarks>The packet is handled on its own thread. If packets must be handled in the order in which thye
|
||||
/// are received then please us ethe synchronous version of this method.</remarks>
|
||||
/// <param name="packetType"></param>
|
||||
/// <param name="handler"></param>
|
||||
/// <returns>true if the handler was added. This is currently always the case.</returns>
|
||||
public bool AddLocalPacketHandler(PacketType packetType, PacketMethod handler)
|
||||
{
|
||||
return AddLocalPacketHandler(packetType, handler, true);
|
||||
}
|
||||
|
||||
public bool AddLocalPacketHandler(PacketType packetType, PacketMethod handler, bool async)
|
||||
/// <summary>
|
||||
/// Add a handler for the given packet type.
|
||||
/// </summary>
|
||||
/// <param name="packetType"></param>
|
||||
/// <param name="handler"></param>
|
||||
/// <param name="doAsync">
|
||||
/// If true, when the packet is received it is handled on its own thread rather than on the main inward bound
|
||||
/// packet handler thread. This vastly increases respnosiveness but some packets need to be handled
|
||||
/// synchronously.
|
||||
/// </param>
|
||||
/// <returns>true if the handler was added. This is currently always the case.</returns>
|
||||
public bool AddLocalPacketHandler(PacketType packetType, PacketMethod handler, bool doAsync)
|
||||
{
|
||||
bool result = false;
|
||||
lock (m_packetHandlers)
|
||||
{
|
||||
if (!m_packetHandlers.ContainsKey(packetType))
|
||||
{
|
||||
m_packetHandlers.Add(packetType, new PacketProcessor() { method = handler, Async = async });
|
||||
m_packetHandlers.Add(packetType, new PacketProcessor() { method = handler, Async = doAsync });
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -689,7 +714,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
|
||||
public virtual void Start()
|
||||
{
|
||||
m_scene.AddNewClient(this);
|
||||
m_scene.AddNewClient(this, PresenceType.User);
|
||||
|
||||
RefreshGroupMembership();
|
||||
}
|
||||
@@ -1476,6 +1501,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
money.MoneyData.TransactionSuccess = success;
|
||||
money.MoneyData.Description = description;
|
||||
money.MoneyData.MoneyBalance = balance;
|
||||
money.TransactionInfo.ItemDescription = Util.StringToBytes256("NONE");
|
||||
OutPacket(money, ThrottleOutPacketType.Task);
|
||||
}
|
||||
|
||||
@@ -2231,7 +2257,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
OutPacket(loadURL, ThrottleOutPacketType.Task);
|
||||
}
|
||||
|
||||
public void SendDialog(string objectname, UUID objectID, string ownerFirstName, string ownerLastName, string msg, UUID textureID, int ch, string[] buttonlabels)
|
||||
public void SendDialog(
|
||||
string objectname, UUID objectID, UUID ownerID, string ownerFirstName, string ownerLastName, string msg,
|
||||
UUID textureID, int ch, string[] buttonlabels)
|
||||
{
|
||||
ScriptDialogPacket dialog = (ScriptDialogPacket)PacketPool.Instance.GetPacket(PacketType.ScriptDialog);
|
||||
dialog.Data.ObjectID = objectID;
|
||||
@@ -2249,6 +2277,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
buttons[i].ButtonLabel = Util.StringToBytes256(buttonlabels[i]);
|
||||
}
|
||||
dialog.Buttons = buttons;
|
||||
|
||||
dialog.OwnerData = new ScriptDialogPacket.OwnerDataBlock[1];
|
||||
dialog.OwnerData[0] = new ScriptDialogPacket.OwnerDataBlock();
|
||||
dialog.OwnerData[0].OwnerID = ownerID;
|
||||
|
||||
OutPacket(dialog, ThrottleOutPacketType.Task);
|
||||
}
|
||||
|
||||
@@ -2320,8 +2353,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
OrbitalPosition = (OrbitalPosition - m_sunPainDaHalfOrbitalCutoff) * 0.6666666667f + m_sunPainDaHalfOrbitalCutoff;
|
||||
}
|
||||
|
||||
|
||||
|
||||
SimulatorViewerTimeMessagePacket viewertime = (SimulatorViewerTimeMessagePacket)PacketPool.Instance.GetPacket(PacketType.SimulatorViewerTimeMessage);
|
||||
viewertime.TimeInfo.SunDirection = Position;
|
||||
viewertime.TimeInfo.SunAngVelocity = Velocity;
|
||||
@@ -3716,7 +3747,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
if (!m_scene.TryGetScenePresence(part.OwnerID, out sp))
|
||||
continue;
|
||||
|
||||
List<SceneObjectGroup> atts = sp.Attachments;
|
||||
List<SceneObjectGroup> atts = sp.GetAttachments();
|
||||
bool found = false;
|
||||
foreach (SceneObjectGroup att in atts)
|
||||
{
|
||||
@@ -4142,8 +4173,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
while (updatesThisCall < m_maxUpdates)
|
||||
{
|
||||
lock (m_entityProps.SyncRoot)
|
||||
if (!m_entityProps.TryDequeue(out iupdate, out timeinqueue))
|
||||
break;
|
||||
if (!m_entityProps.TryDequeue(out iupdate, out timeinqueue))
|
||||
break;
|
||||
|
||||
ObjectPropertyUpdate update = (ObjectPropertyUpdate)iupdate;
|
||||
if (update.SendFamilyProps)
|
||||
@@ -4578,7 +4609,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
|
||||
if (landData.SimwideArea > 0)
|
||||
{
|
||||
int simulatorCapacity = (int)(((float)landData.SimwideArea / 65536.0f) * (float)m_scene.RegionInfo.ObjectCapacity * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus);
|
||||
int simulatorCapacity = (int)((double)(landData.SimwideArea * m_scene.RegionInfo.ObjectCapacity) * m_scene.RegionInfo.RegionSettings.ObjectBonus) / 65536;
|
||||
// Never report more than sim total capacity
|
||||
if (simulatorCapacity > m_scene.RegionInfo.ObjectCapacity)
|
||||
simulatorCapacity = m_scene.RegionInfo.ObjectCapacity;
|
||||
updateMessage.SimWideMaxPrims = simulatorCapacity;
|
||||
}
|
||||
else
|
||||
@@ -4786,7 +4820,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
{
|
||||
SceneObjectPart part = (SceneObjectPart)entity;
|
||||
|
||||
attachPoint = part.AttachmentPoint;
|
||||
attachPoint = part.ParentGroup.AttachmentPoint;
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[LLCLIENTVIEW]: Sending attachPoint {0} for {1} {2} to {3}",
|
||||
// attachPoint, part.Name, part.LocalId, Name);
|
||||
|
||||
collisionPlane = Vector4.Zero;
|
||||
position = part.RelativePosition;
|
||||
velocity = part.Velocity;
|
||||
@@ -4943,17 +4982,24 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
//update.JointType = 0;
|
||||
update.Material = data.Material;
|
||||
update.MediaURL = Utils.EmptyBytes; // FIXME: Support this in OpenSim
|
||||
if (data.IsAttachment)
|
||||
if (data.ParentGroup.IsAttachment)
|
||||
{
|
||||
update.NameValue = Util.StringToBytes256("AttachItemID STRING RW SV " + data.FromItemID);
|
||||
update.State = (byte)((data.AttachmentPoint % 16) * 16 + (data.AttachmentPoint / 16));
|
||||
update.State = (byte)((data.ParentGroup.AttachmentPoint % 16) * 16 + (data.ParentGroup.AttachmentPoint / 16));
|
||||
}
|
||||
else
|
||||
{
|
||||
update.NameValue = Utils.EmptyBytes;
|
||||
update.State = data.Shape.State;
|
||||
|
||||
// The root part state is the canonical state for all parts of the object. The other part states in the
|
||||
// case for attachments may contain conflicting values that can end up crashing the viewer.
|
||||
update.State = data.ParentGroup.RootPart.Shape.State;
|
||||
}
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[LLCLIENTVIEW]: Sending state {0} for {1} {2} to {3}",
|
||||
// update.State, data.Name, data.LocalId, Name);
|
||||
|
||||
update.ObjectData = objectData;
|
||||
update.ParentID = data.ParentID;
|
||||
update.PathBegin = data.Shape.PathBegin;
|
||||
@@ -5297,6 +5343,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest);
|
||||
AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes);
|
||||
AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard);
|
||||
|
||||
AddGenericPacketHandler("autopilot", HandleAutopilot);
|
||||
}
|
||||
|
||||
#region Packet Handlers
|
||||
@@ -5340,7 +5388,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
update = true;
|
||||
}
|
||||
|
||||
// These should be ordered from most-likely to
|
||||
// least likely to change. I've made an initial
|
||||
@@ -5348,6 +5398,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
|
||||
if (update)
|
||||
{
|
||||
// m_log.DebugFormat("[LLCLIENTVIEW]: Triggered AgentUpdate for {0}", sener.Name);
|
||||
|
||||
AgentUpdateArgs arg = new AgentUpdateArgs();
|
||||
arg.AgentID = x.AgentID;
|
||||
arg.BodyRotation = x.BodyRotation;
|
||||
@@ -6221,10 +6273,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
|
||||
private bool HandleCompleteAgentMovement(IClientAPI sender, Packet Pack)
|
||||
{
|
||||
GenericCall1 handlerCompleteMovementToRegion = OnCompleteMovementToRegion;
|
||||
Action<IClientAPI, bool> handlerCompleteMovementToRegion = OnCompleteMovementToRegion;
|
||||
if (handlerCompleteMovementToRegion != null)
|
||||
{
|
||||
handlerCompleteMovementToRegion(sender);
|
||||
handlerCompleteMovementToRegion(sender, true);
|
||||
}
|
||||
handlerCompleteMovementToRegion = null;
|
||||
|
||||
@@ -7600,13 +7652,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
IInventoryAccessModule invAccess = m_scene.RequestModuleInterface<IInventoryAccessModule>();
|
||||
if (invAccess != null)
|
||||
{
|
||||
if (!invAccess.GetAgentInventoryItem(this, itemID, requestID))
|
||||
if (!invAccess.CanGetAgentInventoryItem(this, itemID, requestID))
|
||||
return false;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7620,7 +7672,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
{
|
||||
AssetUploadRequestPacket request = (AssetUploadRequestPacket)Pack;
|
||||
|
||||
|
||||
// m_log.Debug("upload request " + request.ToString());
|
||||
// m_log.Debug("upload request was for assetid: " + request.AssetBlock.TransactionID.Combine(this.SecureSessionId).ToString());
|
||||
UUID temp = UUID.Combine(request.AssetBlock.TransactionID, SecureSessionId);
|
||||
@@ -8358,16 +8409,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
AssetLandmark lm;
|
||||
if (lmid != UUID.Zero)
|
||||
{
|
||||
|
||||
//AssetBase lma = m_assetCache.GetAsset(lmid, false);
|
||||
AssetBase lma = m_assetService.Get(lmid.ToString());
|
||||
|
||||
if (lma == null)
|
||||
{
|
||||
// Failed to find landmark
|
||||
TeleportCancelPacket tpCancel = (TeleportCancelPacket)PacketPool.Instance.GetPacket(PacketType.TeleportCancel);
|
||||
tpCancel.Info.SessionID = tpReq.Info.SessionID;
|
||||
tpCancel.Info.AgentID = tpReq.Info.AgentID;
|
||||
OutPacket(tpCancel, ThrottleOutPacketType.Task);
|
||||
|
||||
// Let's try to search in the user's home asset server
|
||||
lma = FindAssetInUserAssetServer(lmid.ToString());
|
||||
|
||||
if (lma == null)
|
||||
{
|
||||
// Really doesn't exist
|
||||
TeleportCancelPacket tpCancel = (TeleportCancelPacket)PacketPool.Instance.GetPacket(PacketType.TeleportCancel);
|
||||
tpCancel.Info.SessionID = tpReq.Info.SessionID;
|
||||
tpCancel.Info.AgentID = tpReq.Info.AgentID;
|
||||
OutPacket(tpCancel, ThrottleOutPacketType.Task);
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
@@ -8398,13 +8458,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
TeleportLandmarkRequest handlerTeleportLandmarkRequest = OnTeleportLandmarkRequest;
|
||||
if (handlerTeleportLandmarkRequest != null)
|
||||
{
|
||||
handlerTeleportLandmarkRequest(this, lm.RegionID, lm.Position);
|
||||
handlerTeleportLandmarkRequest(this, lm);
|
||||
}
|
||||
else
|
||||
{
|
||||
//no event handler so cancel request
|
||||
|
||||
|
||||
TeleportCancelPacket tpCancel = (TeleportCancelPacket)PacketPool.Instance.GetPacket(PacketType.TeleportCancel);
|
||||
tpCancel.Info.AgentID = tpReq.Info.AgentID;
|
||||
tpCancel.Info.SessionID = tpReq.Info.SessionID;
|
||||
@@ -8414,6 +8472,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
return true;
|
||||
}
|
||||
|
||||
private AssetBase FindAssetInUserAssetServer(string id)
|
||||
{
|
||||
AgentCircuitData aCircuit = ((Scene)Scene).AuthenticateHandler.GetAgentCircuitData(CircuitCode);
|
||||
if (aCircuit != null && aCircuit.ServiceURLs != null && aCircuit.ServiceURLs.ContainsKey("AssetServerURI"))
|
||||
{
|
||||
string assetServer = aCircuit.ServiceURLs["AssetServerURI"].ToString();
|
||||
return ((Scene)Scene).AssetService.Get(assetServer + "/" + id);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private bool HandleTeleportLocationRequest(IClientAPI sender, Packet Pack)
|
||||
{
|
||||
TeleportLocationRequestPacket tpLocReq = (TeleportLocationRequestPacket)Pack;
|
||||
@@ -11284,8 +11354,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
protected bool HandleMultipleObjUpdate(IClientAPI simClient, Packet packet)
|
||||
{
|
||||
MultipleObjectUpdatePacket multipleupdate = (MultipleObjectUpdatePacket)packet;
|
||||
if (multipleupdate.AgentData.SessionID != SessionId) return false;
|
||||
// m_log.Debug("new multi update packet " + multipleupdate.ToString());
|
||||
|
||||
if (multipleupdate.AgentData.SessionID != SessionId)
|
||||
return false;
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[CLIENT]: Incoming MultipleObjectUpdatePacket contained {0} blocks", multipleupdate.ObjectData.Length);
|
||||
|
||||
Scene tScene = (Scene)m_scene;
|
||||
|
||||
for (int i = 0; i < multipleupdate.ObjectData.Length; i++)
|
||||
@@ -11306,7 +11381,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
}
|
||||
else
|
||||
{
|
||||
// UUID partId = part.UUID;
|
||||
// m_log.DebugFormat(
|
||||
// "[CLIENT]: Processing block {0} type {1} for {2} {3}",
|
||||
// i, block.Type, part.Name, part.LocalId);
|
||||
|
||||
// // Do this once since fetch parts creates a new array.
|
||||
// SceneObjectPart[] parts = part.ParentGroup.Parts;
|
||||
// for (int j = 0; j < parts.Length; j++)
|
||||
// {
|
||||
// part.StoreUndoState();
|
||||
// parts[j].IgnoreUndoUpdate = true;
|
||||
// }
|
||||
|
||||
UpdatePrimGroupRotation handlerUpdatePrimGroupRotation;
|
||||
|
||||
switch (block.Type)
|
||||
@@ -11321,6 +11407,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
handlerUpdatePrimSinglePosition(localId, pos1, this);
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
Quaternion rot1 = new Quaternion(block.Data, 0, true);
|
||||
|
||||
@@ -11331,6 +11418,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
handlerUpdatePrimSingleRotation(localId, rot1, this);
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
Vector3 rotPos = new Vector3(block.Data, 0);
|
||||
Quaternion rot2 = new Quaternion(block.Data, 12, true);
|
||||
@@ -11343,6 +11431,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
handlerUpdatePrimSingleRotationPosition(localId, rot2, rotPos, this);
|
||||
}
|
||||
break;
|
||||
|
||||
case 4:
|
||||
case 20:
|
||||
Vector3 scale4 = new Vector3(block.Data, 0);
|
||||
@@ -11354,8 +11443,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
handlerUpdatePrimScale(localId, scale4, this);
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
|
||||
case 5:
|
||||
Vector3 scale1 = new Vector3(block.Data, 12);
|
||||
Vector3 pos11 = new Vector3(block.Data, 0);
|
||||
|
||||
@@ -11372,6 +11461,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 9:
|
||||
Vector3 pos2 = new Vector3(block.Data, 0);
|
||||
|
||||
@@ -11379,10 +11469,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
|
||||
if (handlerUpdateVector != null)
|
||||
{
|
||||
|
||||
handlerUpdateVector(localId, pos2, this);
|
||||
}
|
||||
break;
|
||||
|
||||
case 10:
|
||||
Quaternion rot3 = new Quaternion(block.Data, 0, true);
|
||||
|
||||
@@ -11393,6 +11483,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
handlerUpdatePrimRotation(localId, rot3, this);
|
||||
}
|
||||
break;
|
||||
|
||||
case 11:
|
||||
Vector3 pos3 = new Vector3(block.Data, 0);
|
||||
Quaternion rot4 = new Quaternion(block.Data, 12, true);
|
||||
@@ -11416,6 +11507,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
handlerUpdatePrimGroupScale(localId, scale7, this);
|
||||
}
|
||||
break;
|
||||
|
||||
case 13:
|
||||
Vector3 scale2 = new Vector3(block.Data, 12);
|
||||
Vector3 pos4 = new Vector3(block.Data, 0);
|
||||
@@ -11435,6 +11527,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 29:
|
||||
Vector3 scale5 = new Vector3(block.Data, 12);
|
||||
Vector3 pos5 = new Vector3(block.Data, 0);
|
||||
@@ -11443,6 +11536,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
if (handlerUpdatePrimGroupScale != null)
|
||||
{
|
||||
// m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
|
||||
part.StoreUndoState(true);
|
||||
part.IgnoreUndoUpdate = true;
|
||||
handlerUpdatePrimGroupScale(localId, scale5, this);
|
||||
handlerUpdateVector = OnUpdatePrimGroupPosition;
|
||||
|
||||
@@ -11450,8 +11545,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
{
|
||||
handlerUpdateVector(localId, pos5, this);
|
||||
}
|
||||
|
||||
part.IgnoreUndoUpdate = false;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 21:
|
||||
Vector3 scale6 = new Vector3(block.Data, 12);
|
||||
Vector3 pos6 = new Vector3(block.Data, 0);
|
||||
@@ -11459,6 +11558,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
handlerUpdatePrimScale = OnUpdatePrimScale;
|
||||
if (handlerUpdatePrimScale != null)
|
||||
{
|
||||
part.StoreUndoState(false);
|
||||
part.IgnoreUndoUpdate = true;
|
||||
|
||||
// m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
|
||||
handlerUpdatePrimScale(localId, scale6, this);
|
||||
handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition;
|
||||
@@ -11466,15 +11568,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
{
|
||||
handlerUpdatePrimSinglePosition(localId, pos6, this);
|
||||
}
|
||||
|
||||
part.IgnoreUndoUpdate = false;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
m_log.Debug("[CLIENT] MultipleObjUpdate recieved an unknown packet type: " + (block.Type));
|
||||
m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type));
|
||||
break;
|
||||
}
|
||||
|
||||
// for (int j = 0; j < parts.Length; j++)
|
||||
// parts[j].IgnoreUndoUpdate = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -11634,55 +11743,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Breaks down the genericMessagePacket into specific events
|
||||
/// </summary>
|
||||
/// <param name="gmMethod"></param>
|
||||
/// <param name="gmInvoice"></param>
|
||||
/// <param name="gmParams"></param>
|
||||
public void DecipherGenericMessage(string gmMethod, UUID gmInvoice, GenericMessagePacket.ParamListBlock[] gmParams)
|
||||
protected void HandleAutopilot(Object sender, string method, List<String> args)
|
||||
{
|
||||
switch (gmMethod)
|
||||
{
|
||||
case "autopilot":
|
||||
float locx;
|
||||
float locy;
|
||||
float locz;
|
||||
float locx = 0;
|
||||
float locy = 0;
|
||||
float locz = 0;
|
||||
uint regionX = 0;
|
||||
uint regionY = 0;
|
||||
|
||||
try
|
||||
{
|
||||
uint regionX;
|
||||
uint regionY;
|
||||
Utils.LongToUInts(Scene.RegionInfo.RegionHandle, out regionX, out regionY);
|
||||
locx = Convert.ToSingle(Utils.BytesToString(gmParams[0].Parameter)) - regionX;
|
||||
locy = Convert.ToSingle(Utils.BytesToString(gmParams[1].Parameter)) - regionY;
|
||||
locz = Convert.ToSingle(Utils.BytesToString(gmParams[2].Parameter));
|
||||
}
|
||||
catch (InvalidCastException)
|
||||
{
|
||||
m_log.Error("[CLIENT]: Invalid autopilot request");
|
||||
return;
|
||||
}
|
||||
Utils.LongToUInts(m_scene.RegionInfo.RegionHandle, out regionX, out regionY);
|
||||
locx = Convert.ToSingle(args[0]) - (float)regionX;
|
||||
locy = Convert.ToSingle(args[1]) - (float)regionY;
|
||||
locz = Convert.ToSingle(args[2]);
|
||||
|
||||
UpdateVector handlerAutoPilotGo = OnAutoPilotGo;
|
||||
if (handlerAutoPilotGo != null)
|
||||
{
|
||||
handlerAutoPilotGo(0, new Vector3(locx, locy, locz), this);
|
||||
}
|
||||
m_log.InfoFormat("[CLIENT]: Client Requests autopilot to position <{0},{1},{2}>", locx, locy, locz);
|
||||
|
||||
|
||||
break;
|
||||
default:
|
||||
m_log.Debug("[CLIENT]: Unknown Generic Message, Method: " + gmMethod + ". Invoice: " + gmInvoice + ". Dumping Params:");
|
||||
for (int hi = 0; hi < gmParams.Length; hi++)
|
||||
{
|
||||
Console.WriteLine(gmParams[hi].ToString());
|
||||
}
|
||||
//gmpack.MethodData.
|
||||
break;
|
||||
|
||||
}
|
||||
Action<Vector3, bool> handlerAutoPilotGo = OnAutoPilotGo;
|
||||
if (handlerAutoPilotGo != null)
|
||||
handlerAutoPilotGo(new Vector3(locx, locy, locz), false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -12097,7 +12173,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
OutPacket(packet, ThrottleOutPacketType.Task);
|
||||
}
|
||||
|
||||
public void SendTextBoxRequest(string message, int chatChannel, string objectname, string ownerFirstName, string ownerLastName, UUID objectId)
|
||||
public void SendTextBoxRequest(string message, int chatChannel, string objectname, UUID ownerID, string ownerFirstName, string ownerLastName, UUID objectId)
|
||||
{
|
||||
ScriptDialogPacket dialog = (ScriptDialogPacket)PacketPool.Instance.GetPacket(PacketType.ScriptDialog);
|
||||
dialog.Data.ObjectID = objectId;
|
||||
@@ -12113,6 +12189,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
buttons[0] = new ScriptDialogPacket.ButtonsBlock();
|
||||
buttons[0].ButtonLabel = Util.StringToBytes256("!!llTextBox!!");
|
||||
dialog.Buttons = buttons;
|
||||
|
||||
dialog.OwnerData = new ScriptDialogPacket.OwnerDataBlock[1];
|
||||
dialog.OwnerData[0] = new ScriptDialogPacket.OwnerDataBlock();
|
||||
dialog.OwnerData[0].OwnerID = ownerID;
|
||||
|
||||
OutPacket(dialog, ThrottleOutPacketType.Task);
|
||||
}
|
||||
|
||||
|
||||
@@ -521,7 +521,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
// No dequeued packet waiting to be sent, try to pull one off
|
||||
// this queue
|
||||
queue = m_packetOutboxes[i];
|
||||
if (queue.Dequeue(out packet))
|
||||
if (queue != null && queue.Dequeue(out packet))
|
||||
{
|
||||
// A packet was pulled off the queue. See if we have
|
||||
// enough tokens in the bucket to send it out
|
||||
|
||||
@@ -160,6 +160,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
|
||||
public Socket Server { get { return null; } }
|
||||
|
||||
private int m_malformedCount = 0; // Guard against a spamming attack
|
||||
|
||||
public LLUDPServer(IPAddress listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port, IConfigSource configSource, AgentCircuitManager circuitManager)
|
||||
: base(listenIP, (int)port)
|
||||
{
|
||||
@@ -612,6 +614,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
|
||||
#region Decoding
|
||||
|
||||
if (buffer.DataLength < 7)
|
||||
return; // Drop undersizd packet
|
||||
|
||||
int headerLen = 7;
|
||||
if (buffer.Data[6] == 0xFF)
|
||||
{
|
||||
if (buffer.Data[7] == 0xFF)
|
||||
headerLen = 10;
|
||||
else
|
||||
headerLen = 8;
|
||||
}
|
||||
|
||||
if (buffer.DataLength < headerLen)
|
||||
return; // Malformed header
|
||||
|
||||
try
|
||||
{
|
||||
packet = Packet.BuildPacket(buffer.Data, ref packetEnd,
|
||||
@@ -621,6 +638,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
catch (MalformedDataException)
|
||||
{
|
||||
}
|
||||
catch (IndexOutOfRangeException)
|
||||
{
|
||||
return; // Drop short packet
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
if (m_malformedCount < 100)
|
||||
m_log.DebugFormat("[LLUDPSERVER]: Dropped malformed packet: " + e.ToString());
|
||||
m_malformedCount++;
|
||||
if ((m_malformedCount % 100000) == 0)
|
||||
m_log.DebugFormat("[LLUDPSERVER]: Received {0} malformed packets so far, probable network attack.", m_malformedCount);
|
||||
}
|
||||
|
||||
// Fail-safe check
|
||||
if (packet == null)
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
private static Int32 m_counter = 0;
|
||||
|
||||
private Int32 m_identifier;
|
||||
// private Int32 m_identifier;
|
||||
|
||||
/// <summary>
|
||||
/// Number of ticks (ms) per quantum, drip rate and max burst
|
||||
@@ -173,7 +173,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
/// second. If zero, the bucket always remains full</param>
|
||||
public TokenBucket(TokenBucket parent, Int64 dripRate)
|
||||
{
|
||||
m_identifier = m_counter++;
|
||||
// m_identifier = m_counter++;
|
||||
m_counter++;
|
||||
|
||||
Parent = parent;
|
||||
RequestedDripRate = dripRate;
|
||||
@@ -320,7 +321,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
|
||||
public class AdaptiveTokenBucket : TokenBucket
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
/// <summary>
|
||||
/// The minimum rate for flow control. Minimum drip rate is one
|
||||
|
||||
@@ -64,13 +64,13 @@ namespace Flotsam.RegionModules.AssetCache
|
||||
private bool m_Enabled;
|
||||
|
||||
private const string m_ModuleName = "FlotsamAssetCache";
|
||||
private const string m_DefaultCacheDirectory = m_ModuleName;
|
||||
private const string m_DefaultCacheDirectory = "./assetcache";
|
||||
private string m_CacheDirectory = m_DefaultCacheDirectory;
|
||||
|
||||
private readonly List<char> m_InvalidChars = new List<char>();
|
||||
|
||||
private int m_LogLevel = 0;
|
||||
private ulong m_HitRateDisplay = 1; // How often to display hit statistics, given in requests
|
||||
private ulong m_HitRateDisplay = 100; // How often to display hit statistics, given in requests
|
||||
|
||||
private static ulong m_Requests;
|
||||
private static ulong m_RequestsForInprogress;
|
||||
@@ -86,15 +86,17 @@ namespace Flotsam.RegionModules.AssetCache
|
||||
private List<string> m_CurrentlyWriting = new List<string>();
|
||||
#endif
|
||||
|
||||
private bool m_FileCacheEnabled = true;
|
||||
|
||||
private ExpiringCache<string, AssetBase> m_MemoryCache;
|
||||
private bool m_MemoryCacheEnabled = true;
|
||||
private bool m_MemoryCacheEnabled = false;
|
||||
|
||||
// Expiration is expressed in hours.
|
||||
private const double m_DefaultMemoryExpiration = 1.0;
|
||||
private const double m_DefaultMemoryExpiration = 2;
|
||||
private const double m_DefaultFileExpiration = 48;
|
||||
private TimeSpan m_MemoryExpiration = TimeSpan.FromHours(m_DefaultMemoryExpiration);
|
||||
private TimeSpan m_FileExpiration = TimeSpan.FromHours(m_DefaultFileExpiration);
|
||||
private TimeSpan m_FileExpirationCleanupTimer = TimeSpan.FromHours(m_DefaultFileExpiration);
|
||||
private TimeSpan m_FileExpirationCleanupTimer = TimeSpan.FromHours(0.166);
|
||||
|
||||
private static int m_CacheDirectoryTiers = 1;
|
||||
private static int m_CacheDirectoryTierLen = 3;
|
||||
@@ -141,27 +143,40 @@ namespace Flotsam.RegionModules.AssetCache
|
||||
IConfig assetConfig = source.Configs["AssetCache"];
|
||||
if (assetConfig == null)
|
||||
{
|
||||
m_log.Warn("[FLOTSAM ASSET CACHE]: AssetCache missing from OpenSim.ini, using defaults.");
|
||||
m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Cache Directory", m_DefaultCacheDirectory);
|
||||
return;
|
||||
m_log.Warn(
|
||||
"[FLOTSAM ASSET CACHE]: AssetCache section missing from config (not copied config-include/FlotsamCache.ini.example? Using defaults.");
|
||||
}
|
||||
else
|
||||
{
|
||||
m_FileCacheEnabled = assetConfig.GetBoolean("FileCacheEnabled", m_FileCacheEnabled);
|
||||
m_CacheDirectory = assetConfig.GetString("CacheDirectory", m_DefaultCacheDirectory);
|
||||
|
||||
m_MemoryCacheEnabled = assetConfig.GetBoolean("MemoryCacheEnabled", m_MemoryCacheEnabled);
|
||||
m_MemoryExpiration = TimeSpan.FromHours(assetConfig.GetDouble("MemoryCacheTimeout", m_DefaultMemoryExpiration));
|
||||
|
||||
#if WAIT_ON_INPROGRESS_REQUESTS
|
||||
m_WaitOnInprogressTimeout = assetConfig.GetInt("WaitOnInprogressTimeout", 3000);
|
||||
#endif
|
||||
|
||||
m_LogLevel = assetConfig.GetInt("LogLevel", m_LogLevel);
|
||||
m_HitRateDisplay = (ulong)assetConfig.GetLong("HitRateDisplay", (long)m_HitRateDisplay);
|
||||
|
||||
m_FileExpiration = TimeSpan.FromHours(assetConfig.GetDouble("FileCacheTimeout", m_DefaultFileExpiration));
|
||||
m_FileExpirationCleanupTimer
|
||||
= TimeSpan.FromHours(
|
||||
assetConfig.GetDouble("FileCleanupTimer", m_FileExpirationCleanupTimer.TotalHours));
|
||||
|
||||
m_CacheDirectoryTiers = assetConfig.GetInt("CacheDirectoryTiers", m_CacheDirectoryTiers);
|
||||
m_CacheDirectoryTierLen = assetConfig.GetInt("CacheDirectoryTierLength", m_CacheDirectoryTierLen);
|
||||
|
||||
m_CacheWarnAt = assetConfig.GetInt("CacheWarnAt", m_CacheWarnAt);
|
||||
|
||||
m_DeepScanBeforePurge = assetConfig.GetBoolean("DeepScanBeforePurge", m_DeepScanBeforePurge);
|
||||
}
|
||||
|
||||
m_CacheDirectory = assetConfig.GetString("CacheDirectory", m_DefaultCacheDirectory);
|
||||
m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Cache Directory", m_CacheDirectory);
|
||||
m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Cache Directory {0}", m_CacheDirectory);
|
||||
|
||||
m_MemoryCacheEnabled = assetConfig.GetBoolean("MemoryCacheEnabled", false);
|
||||
m_MemoryExpiration = TimeSpan.FromHours(assetConfig.GetDouble("MemoryCacheTimeout", m_DefaultMemoryExpiration));
|
||||
|
||||
#if WAIT_ON_INPROGRESS_REQUESTS
|
||||
m_WaitOnInprogressTimeout = assetConfig.GetInt("WaitOnInprogressTimeout", 3000);
|
||||
#endif
|
||||
|
||||
m_LogLevel = assetConfig.GetInt("LogLevel", 0);
|
||||
m_HitRateDisplay = (ulong)assetConfig.GetInt("HitRateDisplay", 1000);
|
||||
|
||||
m_FileExpiration = TimeSpan.FromHours(assetConfig.GetDouble("FileCacheTimeout", m_DefaultFileExpiration));
|
||||
m_FileExpirationCleanupTimer = TimeSpan.FromHours(assetConfig.GetDouble("FileCleanupTimer", m_DefaultFileExpiration));
|
||||
if ((m_FileExpiration > TimeSpan.Zero) && (m_FileExpirationCleanupTimer > TimeSpan.Zero))
|
||||
if (m_FileCacheEnabled && (m_FileExpiration > TimeSpan.Zero) && (m_FileExpirationCleanupTimer > TimeSpan.Zero))
|
||||
{
|
||||
m_CacheCleanTimer = new System.Timers.Timer(m_FileExpirationCleanupTimer.TotalMilliseconds);
|
||||
m_CacheCleanTimer.AutoReset = true;
|
||||
@@ -170,7 +185,6 @@ namespace Flotsam.RegionModules.AssetCache
|
||||
m_CacheCleanTimer.Start();
|
||||
}
|
||||
|
||||
m_CacheDirectoryTiers = assetConfig.GetInt("CacheDirectoryTiers", 1);
|
||||
if (m_CacheDirectoryTiers < 1)
|
||||
{
|
||||
m_CacheDirectoryTiers = 1;
|
||||
@@ -180,7 +194,6 @@ namespace Flotsam.RegionModules.AssetCache
|
||||
m_CacheDirectoryTiers = 3;
|
||||
}
|
||||
|
||||
m_CacheDirectoryTierLen = assetConfig.GetInt("CacheDirectoryTierLength", 3);
|
||||
if (m_CacheDirectoryTierLen < 1)
|
||||
{
|
||||
m_CacheDirectoryTierLen = 1;
|
||||
@@ -190,14 +203,10 @@ namespace Flotsam.RegionModules.AssetCache
|
||||
m_CacheDirectoryTierLen = 4;
|
||||
}
|
||||
|
||||
m_CacheWarnAt = assetConfig.GetInt("CacheWarnAt", 30000);
|
||||
|
||||
m_DeepScanBeforePurge = assetConfig.GetBoolean("DeepScanBeforePurge", false);
|
||||
|
||||
MainConsole.Instance.Commands.AddCommand(this.Name, true, "fcache status", "fcache status", "Display cache status", HandleConsoleCommand);
|
||||
MainConsole.Instance.Commands.AddCommand(this.Name, true, "fcache clear", "fcache clear [file] [memory]", "Remove all assets in the file and/or memory cache", HandleConsoleCommand);
|
||||
MainConsole.Instance.Commands.AddCommand(this.Name, true, "fcache assets", "fcache assets", "Attempt a deep scan and cache of all assets in all scenes", HandleConsoleCommand);
|
||||
MainConsole.Instance.Commands.AddCommand(this.Name, true, "fcache expire", "fcache expire <datetime>", "Purge cached assets older then the specified date/time", HandleConsoleCommand);
|
||||
MainConsole.Instance.Commands.AddCommand(Name, true, "fcache status", "fcache status", "Display cache status", HandleConsoleCommand);
|
||||
MainConsole.Instance.Commands.AddCommand(Name, true, "fcache clear", "fcache clear [file] [memory]", "Remove all assets in the cache. If file or memory is specified then only this cache is cleared.", HandleConsoleCommand);
|
||||
MainConsole.Instance.Commands.AddCommand(Name, true, "fcache assets", "fcache assets", "Attempt a deep scan and cache of all assets in all scenes", HandleConsoleCommand);
|
||||
MainConsole.Instance.Commands.AddCommand(Name, true, "fcache expire", "fcache expire <datetime>", "Purge cached assets older then the specified date/time", HandleConsoleCommand);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -220,7 +229,6 @@ namespace Flotsam.RegionModules.AssetCache
|
||||
if (m_AssetService == null)
|
||||
{
|
||||
m_AssetService = scene.RequestModuleInterface<IAssetService>();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -244,18 +252,15 @@ namespace Flotsam.RegionModules.AssetCache
|
||||
|
||||
private void UpdateMemoryCache(string key, AssetBase asset)
|
||||
{
|
||||
if (m_MemoryCacheEnabled)
|
||||
m_MemoryCache.AddOrUpdate(key, asset, m_MemoryExpiration);
|
||||
m_MemoryCache.AddOrUpdate(key, asset, m_MemoryExpiration);
|
||||
}
|
||||
|
||||
public void Cache(AssetBase asset)
|
||||
private void UpdateFileCache(string key, AssetBase asset)
|
||||
{
|
||||
// TODO: Spawn this off to some seperate thread to do the actual writing
|
||||
if (asset != null)
|
||||
{
|
||||
UpdateMemoryCache(asset.ID, asset);
|
||||
|
||||
string filename = GetFileName(asset.ID);
|
||||
string filename = GetFileName(key);
|
||||
|
||||
try
|
||||
{
|
||||
@@ -272,8 +277,8 @@ namespace Flotsam.RegionModules.AssetCache
|
||||
catch
|
||||
{
|
||||
}
|
||||
} else {
|
||||
|
||||
} else {
|
||||
|
||||
// Once we start writing, make sure we flag that we're writing
|
||||
// that object to the cache so that we don't try to write the
|
||||
// same file multiple times.
|
||||
@@ -308,82 +313,130 @@ namespace Flotsam.RegionModules.AssetCache
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LogException(e);
|
||||
m_log.ErrorFormat(
|
||||
"[FLOTSAM ASSET CACHE]: Failed to update cache for asset {0}. Exception {1} {2}",
|
||||
asset.ID, e.Message, e.StackTrace);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Cache(AssetBase asset)
|
||||
{
|
||||
// TODO: Spawn this off to some seperate thread to do the actual writing
|
||||
if (asset != null)
|
||||
{
|
||||
//m_log.DebugFormat("[FLOTSAM ASSET CACHE]: Caching asset with id {0}", asset.ID);
|
||||
|
||||
if (m_MemoryCacheEnabled)
|
||||
UpdateMemoryCache(asset.ID, asset);
|
||||
|
||||
if (m_FileCacheEnabled)
|
||||
UpdateFileCache(asset.ID, asset);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Try to get an asset from the in-memory cache.
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
private AssetBase GetFromMemoryCache(string id)
|
||||
{
|
||||
AssetBase asset = null;
|
||||
|
||||
if (m_MemoryCache.TryGetValue(id, out asset))
|
||||
m_MemoryHits++;
|
||||
|
||||
return asset;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Try to get an asset from the file cache.
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
private AssetBase GetFromFileCache(string id)
|
||||
{
|
||||
AssetBase asset = null;
|
||||
|
||||
string filename = GetFileName(id);
|
||||
if (File.Exists(filename))
|
||||
{
|
||||
FileStream stream = null;
|
||||
try
|
||||
{
|
||||
stream = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||
BinaryFormatter bformatter = new BinaryFormatter();
|
||||
|
||||
asset = (AssetBase)bformatter.Deserialize(stream);
|
||||
|
||||
m_DiskHits++;
|
||||
}
|
||||
catch (System.Runtime.Serialization.SerializationException e)
|
||||
{
|
||||
m_log.ErrorFormat(
|
||||
"[FLOTSAM ASSET CACHE]: Failed to get file {0} for asset {1}. Exception {2} {3}",
|
||||
filename, id, e.Message, e.StackTrace);
|
||||
|
||||
// If there was a problem deserializing the asset, the asset may
|
||||
// either be corrupted OR was serialized under an old format
|
||||
// {different version of AssetBase} -- we should attempt to
|
||||
// delete it and re-cache
|
||||
File.Delete(filename);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat(
|
||||
"[FLOTSAM ASSET CACHE]: Failed to get file {0} for asset {1}. Exception {2} {3}",
|
||||
filename, id, e.Message, e.StackTrace);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (stream != null)
|
||||
stream.Close();
|
||||
}
|
||||
}
|
||||
|
||||
#if WAIT_ON_INPROGRESS_REQUESTS
|
||||
// Check if we're already downloading this asset. If so, try to wait for it to
|
||||
// download.
|
||||
if (m_WaitOnInprogressTimeout > 0)
|
||||
{
|
||||
m_RequestsForInprogress++;
|
||||
|
||||
ManualResetEvent waitEvent;
|
||||
if (m_CurrentlyWriting.TryGetValue(filename, out waitEvent))
|
||||
{
|
||||
waitEvent.WaitOne(m_WaitOnInprogressTimeout);
|
||||
return Get(id);
|
||||
}
|
||||
}
|
||||
#else
|
||||
// Track how often we have the problem that an asset is requested while
|
||||
// it is still being downloaded by a previous request.
|
||||
if (m_CurrentlyWriting.Contains(filename))
|
||||
{
|
||||
m_RequestsForInprogress++;
|
||||
}
|
||||
#endif
|
||||
return asset;
|
||||
}
|
||||
|
||||
public AssetBase Get(string id)
|
||||
{
|
||||
m_Requests++;
|
||||
|
||||
AssetBase asset = null;
|
||||
|
||||
if (m_MemoryCacheEnabled && m_MemoryCache.TryGetValue(id, out asset))
|
||||
if (m_MemoryCacheEnabled)
|
||||
asset = GetFromMemoryCache(id);
|
||||
|
||||
if (asset == null && m_FileCacheEnabled)
|
||||
{
|
||||
m_MemoryHits++;
|
||||
}
|
||||
else
|
||||
{
|
||||
string filename = GetFileName(id);
|
||||
if (File.Exists(filename))
|
||||
{
|
||||
FileStream stream = null;
|
||||
try
|
||||
{
|
||||
stream = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||
BinaryFormatter bformatter = new BinaryFormatter();
|
||||
asset = GetFromFileCache(id);
|
||||
|
||||
asset = (AssetBase)bformatter.Deserialize(stream);
|
||||
|
||||
UpdateMemoryCache(id, asset);
|
||||
|
||||
m_DiskHits++;
|
||||
}
|
||||
catch (System.Runtime.Serialization.SerializationException e)
|
||||
{
|
||||
LogException(e);
|
||||
|
||||
// If there was a problem deserializing the asset, the asset may
|
||||
// either be corrupted OR was serialized under an old format
|
||||
// {different version of AssetBase} -- we should attempt to
|
||||
// delete it and re-cache
|
||||
File.Delete(filename);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LogException(e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (stream != null)
|
||||
stream.Close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if WAIT_ON_INPROGRESS_REQUESTS
|
||||
// Check if we're already downloading this asset. If so, try to wait for it to
|
||||
// download.
|
||||
if (m_WaitOnInprogressTimeout > 0)
|
||||
{
|
||||
m_RequestsForInprogress++;
|
||||
|
||||
ManualResetEvent waitEvent;
|
||||
if (m_CurrentlyWriting.TryGetValue(filename, out waitEvent))
|
||||
{
|
||||
waitEvent.WaitOne(m_WaitOnInprogressTimeout);
|
||||
return Get(id);
|
||||
}
|
||||
}
|
||||
#else
|
||||
// Track how often we have the problem that an asset is requested while
|
||||
// it is still being downloaded by a previous request.
|
||||
if (m_CurrentlyWriting.Contains(filename))
|
||||
{
|
||||
m_RequestsForInprogress++;
|
||||
}
|
||||
#endif
|
||||
if (m_MemoryCacheEnabled && asset != null)
|
||||
UpdateMemoryCache(id, asset);
|
||||
}
|
||||
|
||||
if (((m_LogLevel >= 1)) && (m_HitRateDisplay != 0) && (m_Requests % m_HitRateDisplay == 0))
|
||||
@@ -400,7 +453,6 @@ namespace Flotsam.RegionModules.AssetCache
|
||||
}
|
||||
|
||||
m_log.InfoFormat("[FLOTSAM ASSET CACHE]: {0} unnessesary requests due to requests for assets that are currently downloading.", m_RequestsForInprogress);
|
||||
|
||||
}
|
||||
|
||||
return asset;
|
||||
@@ -414,14 +466,17 @@ namespace Flotsam.RegionModules.AssetCache
|
||||
public void Expire(string id)
|
||||
{
|
||||
if (m_LogLevel >= 2)
|
||||
m_log.DebugFormat("[FLOTSAM ASSET CACHE]: Expiring Asset {0}.", id);
|
||||
m_log.DebugFormat("[FLOTSAM ASSET CACHE]: Expiring Asset {0}", id);
|
||||
|
||||
try
|
||||
{
|
||||
string filename = GetFileName(id);
|
||||
if (File.Exists(filename))
|
||||
if (m_FileCacheEnabled)
|
||||
{
|
||||
File.Delete(filename);
|
||||
string filename = GetFileName(id);
|
||||
if (File.Exists(filename))
|
||||
{
|
||||
File.Delete(filename);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_MemoryCacheEnabled)
|
||||
@@ -429,18 +484,23 @@ namespace Flotsam.RegionModules.AssetCache
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LogException(e);
|
||||
m_log.ErrorFormat(
|
||||
"[FLOTSAM ASSET CACHE]: Failed to expire cached file {0}. Exception {1} {2}",
|
||||
id, e.Message, e.StackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
if (m_LogLevel >= 2)
|
||||
m_log.Debug("[FLOTSAM ASSET CACHE]: Clearing Cache.");
|
||||
m_log.Debug("[FLOTSAM ASSET CACHE]: Clearing caches.");
|
||||
|
||||
foreach (string dir in Directory.GetDirectories(m_CacheDirectory))
|
||||
if (m_FileCacheEnabled)
|
||||
{
|
||||
Directory.Delete(dir);
|
||||
foreach (string dir in Directory.GetDirectories(m_CacheDirectory))
|
||||
{
|
||||
Directory.Delete(dir);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_MemoryCacheEnabled)
|
||||
@@ -475,9 +535,9 @@ namespace Flotsam.RegionModules.AssetCache
|
||||
/// removes empty tier directories.
|
||||
/// </summary>
|
||||
/// <param name="dir"></param>
|
||||
/// <param name="purgeLine"></param>
|
||||
private void CleanExpiredFiles(string dir, DateTime purgeLine)
|
||||
{
|
||||
|
||||
foreach (string file in Directory.GetFiles(dir))
|
||||
{
|
||||
if (File.GetLastAccessTime(file) < purgeLine)
|
||||
@@ -546,31 +606,59 @@ namespace Flotsam.RegionModules.AssetCache
|
||||
|
||||
try
|
||||
{
|
||||
if (!Directory.Exists(directory))
|
||||
try
|
||||
{
|
||||
Directory.CreateDirectory(directory);
|
||||
if (!Directory.Exists(directory))
|
||||
{
|
||||
Directory.CreateDirectory(directory);
|
||||
}
|
||||
|
||||
stream = File.Open(tempname, FileMode.Create);
|
||||
BinaryFormatter bformatter = new BinaryFormatter();
|
||||
bformatter.Serialize(stream, asset);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
m_log.ErrorFormat(
|
||||
"[FLOTSAM ASSET CACHE]: Failed to write asset {0} to temporary location {1} (final {2}) on cache in {3}. Exception {4} {5}.",
|
||||
asset.ID, tempname, filename, directory, e.Message, e.StackTrace);
|
||||
|
||||
return;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (stream != null)
|
||||
stream.Close();
|
||||
}
|
||||
|
||||
stream = File.Open(tempname, FileMode.Create);
|
||||
BinaryFormatter bformatter = new BinaryFormatter();
|
||||
bformatter.Serialize(stream, asset);
|
||||
stream.Close();
|
||||
|
||||
// Now that it's written, rename it so that it can be found.
|
||||
File.Move(tempname, filename);
|
||||
|
||||
if (m_LogLevel >= 2)
|
||||
m_log.DebugFormat("[FLOTSAM ASSET CACHE]: Cache Stored :: {0}", asset.ID);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LogException(e);
|
||||
try
|
||||
{
|
||||
// Now that it's written, rename it so that it can be found.
|
||||
//
|
||||
// File.Copy(tempname, filename, true);
|
||||
// File.Delete(tempname);
|
||||
//
|
||||
// For a brief period, this was done as a separate copy and then temporary file delete operation to
|
||||
// avoid an IOException caused by move if some competing thread had already written the file.
|
||||
// However, this causes exceptions on Windows when other threads attempt to read a file
|
||||
// which is still being copied. So instead, go back to moving the file and swallow any IOException.
|
||||
//
|
||||
// This situation occurs fairly rarely anyway. We assume in this that moves are atomic on the
|
||||
// filesystem.
|
||||
File.Move(tempname, filename);
|
||||
|
||||
if (m_LogLevel >= 2)
|
||||
m_log.DebugFormat("[FLOTSAM ASSET CACHE]: Cache Stored :: {0}", asset.ID);
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
// If we see an IOException here it's likely that some other competing thread has written the
|
||||
// cache file first, so ignore. Other IOException errors (e.g. filesystem full) should be
|
||||
// signally by the earlier temporary file writing code.
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (stream != null)
|
||||
stream.Close();
|
||||
|
||||
// Even if the write fails with an exception, we need to make sure
|
||||
// that we release the lock on that file, otherwise it'll never get
|
||||
// cached
|
||||
@@ -584,22 +672,9 @@ namespace Flotsam.RegionModules.AssetCache
|
||||
waitEvent.Set();
|
||||
}
|
||||
#else
|
||||
if (m_CurrentlyWriting.Contains(filename))
|
||||
{
|
||||
m_CurrentlyWriting.Remove(filename);
|
||||
}
|
||||
m_CurrentlyWriting.Remove(filename);
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private static void LogException(Exception e)
|
||||
{
|
||||
string[] text = e.ToString().Split(new char[] { '\n' });
|
||||
foreach (string t in text)
|
||||
{
|
||||
m_log.ErrorFormat("[FLOTSAM ASSET CACHE]: {0} ", t);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -655,8 +730,7 @@ namespace Flotsam.RegionModules.AssetCache
|
||||
s.ForEachSOG(delegate(SceneObjectGroup e)
|
||||
{
|
||||
gatherer.GatherAssetUuids(e, assets);
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
foreach (UUID assetID in assets.Keys)
|
||||
@@ -689,7 +763,9 @@ namespace Flotsam.RegionModules.AssetCache
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LogException(e);
|
||||
m_log.ErrorFormat(
|
||||
"[FLOTSAM ASSET CACHE]: Couldn't clear asset cache directory {0} from {1}. Exception {2} {3}",
|
||||
dir, m_CacheDirectory, e.Message, e.StackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -701,7 +777,9 @@ namespace Flotsam.RegionModules.AssetCache
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LogException(e);
|
||||
m_log.ErrorFormat(
|
||||
"[FLOTSAM ASSET CACHE]: Couldn't clear asset cache file {0} from {1}. Exception {1} {2}",
|
||||
file, m_CacheDirectory, e.Message, e.StackTrace);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -715,61 +793,97 @@ namespace Flotsam.RegionModules.AssetCache
|
||||
switch (cmd)
|
||||
{
|
||||
case "status":
|
||||
m_log.InfoFormat("[FLOTSAM ASSET CACHE] Memory Cache : {0} assets", m_MemoryCache.Count);
|
||||
if (m_MemoryCacheEnabled)
|
||||
m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Memory Cache : {0} assets", m_MemoryCache.Count);
|
||||
else
|
||||
m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Memory cache disabled");
|
||||
|
||||
int fileCount = GetFileCacheCount(m_CacheDirectory);
|
||||
m_log.InfoFormat("[FLOTSAM ASSET CACHE] File Cache : {0} assets", fileCount);
|
||||
|
||||
foreach (string s in Directory.GetFiles(m_CacheDirectory, "*.fac"))
|
||||
if (m_FileCacheEnabled)
|
||||
{
|
||||
m_log.Info("[FLOTSAM ASSET CACHE] Deep Scans were performed on the following regions:");
|
||||
|
||||
string RegionID = s.Remove(0,s.IndexOf("_")).Replace(".fac","");
|
||||
DateTime RegionDeepScanTMStamp = File.GetLastWriteTime(s);
|
||||
m_log.InfoFormat("[FLOTSAM ASSET CACHE] Region: {0}, {1}", RegionID, RegionDeepScanTMStamp.ToString("MM/dd/yyyy hh:mm:ss"));
|
||||
int fileCount = GetFileCacheCount(m_CacheDirectory);
|
||||
m_log.InfoFormat("[FLOTSAM ASSET CACHE]: File Cache : {0} assets", fileCount);
|
||||
|
||||
foreach (string s in Directory.GetFiles(m_CacheDirectory, "*.fac"))
|
||||
{
|
||||
m_log.Info("[FLOTSAM ASSET CACHE]: Deep scans have previously been performed on the following regions:");
|
||||
|
||||
string RegionID = s.Remove(0,s.IndexOf("_")).Replace(".fac","");
|
||||
DateTime RegionDeepScanTMStamp = File.GetLastWriteTime(s);
|
||||
m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Region: {0}, {1}", RegionID, RegionDeepScanTMStamp.ToString("MM/dd/yyyy hh:mm:ss"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.InfoFormat("[FLOTSAM ASSET CACHE]: File cache disabled");
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case "clear":
|
||||
if (cmdparams.Length < 3)
|
||||
if (cmdparams.Length < 2)
|
||||
{
|
||||
m_log.Warn("[FLOTSAM ASSET CACHE] Please specify memory and/or file cache.");
|
||||
m_log.Warn("[FLOTSAM ASSET CACHE]: Usage is fcache clear [file] [memory]");
|
||||
break;
|
||||
}
|
||||
|
||||
bool clearMemory = false, clearFile = false;
|
||||
|
||||
if (cmdparams.Length == 2)
|
||||
{
|
||||
clearMemory = true;
|
||||
clearFile = true;
|
||||
}
|
||||
foreach (string s in cmdparams)
|
||||
{
|
||||
if (s.ToLower() == "memory")
|
||||
clearMemory = true;
|
||||
else if (s.ToLower() == "file")
|
||||
clearFile = true;
|
||||
}
|
||||
|
||||
if (clearMemory)
|
||||
{
|
||||
if (m_MemoryCacheEnabled)
|
||||
{
|
||||
m_MemoryCache.Clear();
|
||||
m_log.Info("[FLOTSAM ASSET CACHE] Memory cache cleared.");
|
||||
m_log.Info("[FLOTSAM ASSET CACHE]: Memory cache cleared.");
|
||||
}
|
||||
else if (s.ToLower() == "file")
|
||||
else
|
||||
{
|
||||
ClearFileCache();
|
||||
m_log.Info("[FLOTSAM ASSET CACHE] File cache cleared.");
|
||||
m_log.Info("[FLOTSAM ASSET CACHE]: Memory cache not enabled.");
|
||||
}
|
||||
}
|
||||
|
||||
if (clearFile)
|
||||
{
|
||||
if (m_FileCacheEnabled)
|
||||
{
|
||||
ClearFileCache();
|
||||
m_log.Info("[FLOTSAM ASSET CACHE]: File cache cleared.");
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.Info("[FLOTSAM ASSET CACHE]: File cache not enabled.");
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
|
||||
case "assets":
|
||||
m_log.Info("[FLOTSAM ASSET CACHE] Caching all assets, in all scenes.");
|
||||
m_log.Info("[FLOTSAM ASSET CACHE]: Caching all assets, in all scenes.");
|
||||
|
||||
Util.FireAndForget(delegate {
|
||||
int assetsCached = CacheScenes();
|
||||
m_log.InfoFormat("[FLOTSAM ASSET CACHE] Completed Scene Caching, {0} assets found.", assetsCached);
|
||||
|
||||
m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Completed Scene Caching, {0} assets found.", assetsCached);
|
||||
});
|
||||
|
||||
break;
|
||||
|
||||
case "expire":
|
||||
|
||||
|
||||
if (cmdparams.Length < 3)
|
||||
{
|
||||
m_log.InfoFormat("[FLOTSAM ASSET CACHE] Invalid parameters for Expire, please specify a valid date & time", cmd);
|
||||
m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Invalid parameters for Expire, please specify a valid date & time", cmd);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -787,26 +901,28 @@ namespace Flotsam.RegionModules.AssetCache
|
||||
|
||||
if (!DateTime.TryParse(s_expirationDate, out expirationDate))
|
||||
{
|
||||
m_log.InfoFormat("[FLOTSAM ASSET CACHE] {0} is not a valid date & time", cmd);
|
||||
m_log.InfoFormat("[FLOTSAM ASSET CACHE]: {0} is not a valid date & time", cmd);
|
||||
break;
|
||||
}
|
||||
|
||||
CleanExpiredFiles(m_CacheDirectory, expirationDate);
|
||||
if (m_FileCacheEnabled)
|
||||
CleanExpiredFiles(m_CacheDirectory, expirationDate);
|
||||
else
|
||||
m_log.InfoFormat("[FLOTSAM ASSET CACHE]: File cache not active, not clearing.");
|
||||
|
||||
break;
|
||||
default:
|
||||
m_log.InfoFormat("[FLOTSAM ASSET CACHE] Unknown command {0}", cmd);
|
||||
m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Unknown command {0}", cmd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (cmdparams.Length == 1)
|
||||
{
|
||||
m_log.InfoFormat("[FLOTSAM ASSET CACHE] flotsamcache status - Display cache status");
|
||||
m_log.InfoFormat("[FLOTSAM ASSET CACHE] flotsamcache clearmem - Remove all assets cached in memory");
|
||||
m_log.InfoFormat("[FLOTSAM ASSET CACHE] flotsamcache clearfile - Remove all assets cached on disk");
|
||||
m_log.InfoFormat("[FLOTSAM ASSET CACHE] flotsamcache cachescenes - Attempt a deep cache of all assets in all scenes");
|
||||
m_log.InfoFormat("[FLOTSAM ASSET CACHE] flotsamcache <datetime> - Purge assets older then the specified date & time");
|
||||
|
||||
m_log.InfoFormat("[FLOTSAM ASSET CACHE]: fcache status - Display cache status");
|
||||
m_log.InfoFormat("[FLOTSAM ASSET CACHE]: fcache clearmem - Remove all assets cached in memory");
|
||||
m_log.InfoFormat("[FLOTSAM ASSET CACHE]: fcache clearfile - Remove all assets cached on disk");
|
||||
m_log.InfoFormat("[FLOTSAM ASSET CACHE]: fcache cachescenes - Attempt a deep cache of all assets in all scenes");
|
||||
m_log.InfoFormat("[FLOTSAM ASSET CACHE]: fcache <datetime> - Purge assets older then the specified date & time");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -814,7 +930,6 @@ namespace Flotsam.RegionModules.AssetCache
|
||||
|
||||
#region IAssetService Members
|
||||
|
||||
|
||||
public AssetMetadata GetMetadata(string id)
|
||||
{
|
||||
AssetBase asset = Get(id);
|
||||
@@ -844,7 +959,6 @@ namespace Flotsam.RegionModules.AssetCache
|
||||
Cache(asset);
|
||||
|
||||
return asset.ID;
|
||||
|
||||
}
|
||||
|
||||
public bool UpdateContent(string id, byte[] data)
|
||||
|
||||
127
OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs
Normal file
127
OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs
Normal file
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using log4net.Config;
|
||||
using Nini.Config;
|
||||
using NUnit.Framework;
|
||||
using OpenMetaverse;
|
||||
using OpenMetaverse.Assets;
|
||||
using Flotsam.RegionModules.AssetCache;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Region.Framework.Scenes.Serialization;
|
||||
using OpenSim.Tests.Common;
|
||||
using OpenSim.Tests.Common.Mock;
|
||||
|
||||
namespace OpenSim.Region.CoreModules.Asset.Tests
|
||||
{
|
||||
/// <summary>
|
||||
/// At the moment we're only test the in-memory part of the FlotsamAssetCache. This is a considerable weakness.
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class FlotsamAssetCacheTests
|
||||
{
|
||||
protected TestScene m_scene;
|
||||
protected FlotsamAssetCache m_cache;
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
IConfigSource config = new IniConfigSource();
|
||||
|
||||
config.AddConfig("Modules");
|
||||
config.Configs["Modules"].Set("AssetCaching", "FlotsamAssetCache");
|
||||
config.AddConfig("AssetCache");
|
||||
config.Configs["AssetCache"].Set("FileCacheEnabled", "false");
|
||||
config.Configs["AssetCache"].Set("MemoryCacheEnabled", "true");
|
||||
|
||||
m_cache = new FlotsamAssetCache();
|
||||
m_scene = SceneHelpers.SetupScene();
|
||||
SceneHelpers.SetupSceneModules(m_scene, config, m_cache);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestCacheAsset()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
AssetBase asset = AssetHelpers.CreateAsset();
|
||||
asset.ID = TestHelpers.ParseTail(0x1).ToString();
|
||||
|
||||
// Check we don't get anything before the asset is put in the cache
|
||||
AssetBase retrievedAsset = m_cache.Get(asset.ID.ToString());
|
||||
Assert.That(retrievedAsset, Is.Null);
|
||||
|
||||
m_cache.Store(asset);
|
||||
|
||||
// Check that asset is now in cache
|
||||
retrievedAsset = m_cache.Get(asset.ID.ToString());
|
||||
Assert.That(retrievedAsset, Is.Not.Null);
|
||||
Assert.That(retrievedAsset.ID, Is.EqualTo(asset.ID));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestExpireAsset()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
AssetBase asset = AssetHelpers.CreateAsset();
|
||||
asset.ID = TestHelpers.ParseTail(0x2).ToString();
|
||||
|
||||
m_cache.Store(asset);
|
||||
|
||||
m_cache.Expire(asset.ID);
|
||||
|
||||
AssetBase retrievedAsset = m_cache.Get(asset.ID.ToString());
|
||||
Assert.That(retrievedAsset, Is.Null);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestClearCache()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
AssetBase asset = AssetHelpers.CreateAsset();
|
||||
asset.ID = TestHelpers.ParseTail(0x2).ToString();
|
||||
|
||||
m_cache.Store(asset);
|
||||
|
||||
m_cache.Clear();
|
||||
|
||||
AssetBase retrievedAsset = m_cache.Get(asset.ID.ToString());
|
||||
Assert.That(retrievedAsset, Is.Null);
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,319 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Timers;
|
||||
using Timer=System.Timers.Timer;
|
||||
using Nini.Config;
|
||||
using NUnit.Framework;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Communications;
|
||||
using OpenSim.Region.CoreModules.Avatar.Attachments;
|
||||
using OpenSim.Region.CoreModules.Framework.InventoryAccess;
|
||||
using OpenSim.Region.CoreModules.World.Serialiser;
|
||||
using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Tests.Common;
|
||||
using OpenSim.Tests.Common.Mock;
|
||||
|
||||
namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
|
||||
{
|
||||
/// <summary>
|
||||
/// Attachment tests
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class AttachmentsModuleTests
|
||||
{
|
||||
private Scene scene;
|
||||
private AttachmentsModule m_attMod;
|
||||
private ScenePresence m_presence;
|
||||
|
||||
[TestFixtureSetUp]
|
||||
public void FixtureInit()
|
||||
{
|
||||
// Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread.
|
||||
Util.FireAndForgetMethod = FireAndForgetMethod.None;
|
||||
}
|
||||
|
||||
[SetUp]
|
||||
public void Init()
|
||||
{
|
||||
IConfigSource config = new IniConfigSource();
|
||||
config.AddConfig("Modules");
|
||||
config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule");
|
||||
|
||||
scene = SceneHelpers.SetupScene();
|
||||
m_attMod = new AttachmentsModule();
|
||||
SceneHelpers.SetupSceneModules(scene, config, m_attMod, new BasicInventoryAccessModule());
|
||||
}
|
||||
|
||||
[TestFixtureTearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
// We must set this back afterwards, otherwise later tests will fail since they're expecting multiple
|
||||
// threads. Possibly, later tests should be rewritten not to worry about such things.
|
||||
Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add the standard presence for a test.
|
||||
/// </summary>
|
||||
private void AddPresence()
|
||||
{
|
||||
UUID userId = TestHelpers.ParseTail(0x1);
|
||||
UserAccountHelpers.CreateUserWithInventory(scene, userId);
|
||||
m_presence = SceneHelpers.AddScenePresence(scene, userId);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestAddAttachmentFromGround()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
AddPresence();
|
||||
string attName = "att";
|
||||
|
||||
SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName).ParentGroup;
|
||||
|
||||
m_attMod.AttachObject(m_presence.ControllingClient, so, (uint)AttachmentPoint.Chest, false);
|
||||
|
||||
// Check status on scene presence
|
||||
Assert.That(m_presence.HasAttachments(), Is.True);
|
||||
List<SceneObjectGroup> attachments = m_presence.GetAttachments();
|
||||
Assert.That(attachments.Count, Is.EqualTo(1));
|
||||
SceneObjectGroup attSo = attachments[0];
|
||||
Assert.That(attSo.Name, Is.EqualTo(attName));
|
||||
Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest));
|
||||
Assert.That(attSo.IsAttachment);
|
||||
Assert.That(attSo.UsesPhysics, Is.False);
|
||||
Assert.That(attSo.IsTemporary, Is.False);
|
||||
|
||||
// Check item status
|
||||
Assert.That(m_presence.Appearance.GetAttachpoint(
|
||||
attSo.GetFromItemID()), Is.EqualTo((int)AttachmentPoint.Chest));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestAddAttachmentFromInventory()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
AddPresence();
|
||||
|
||||
UUID attItemId = TestHelpers.ParseTail(0x2);
|
||||
UUID attAssetId = TestHelpers.ParseTail(0x3);
|
||||
string attName = "att";
|
||||
|
||||
UserInventoryHelpers.CreateInventoryItem(
|
||||
scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object);
|
||||
|
||||
m_attMod.RezSingleAttachmentFromInventory(
|
||||
m_presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest);
|
||||
|
||||
// Check scene presence status
|
||||
Assert.That(m_presence.HasAttachments(), Is.True);
|
||||
List<SceneObjectGroup> attachments = m_presence.GetAttachments();
|
||||
Assert.That(attachments.Count, Is.EqualTo(1));
|
||||
SceneObjectGroup attSo = attachments[0];
|
||||
Assert.That(attSo.Name, Is.EqualTo(attName));
|
||||
Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest));
|
||||
Assert.That(attSo.IsAttachment);
|
||||
Assert.That(attSo.UsesPhysics, Is.False);
|
||||
Assert.That(attSo.IsTemporary, Is.False);
|
||||
|
||||
// Check appearance status
|
||||
Assert.That(m_presence.Appearance.GetAttachments().Count, Is.EqualTo(1));
|
||||
Assert.That(m_presence.Appearance.GetAttachpoint(attItemId), Is.EqualTo((int)AttachmentPoint.Chest));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDetachAttachmentToGround()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
AddPresence();
|
||||
|
||||
UUID attItemId = TestHelpers.ParseTail(0x2);
|
||||
UUID attAssetId = TestHelpers.ParseTail(0x3);
|
||||
string attName = "att";
|
||||
|
||||
UserInventoryHelpers.CreateInventoryItem(
|
||||
scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object);
|
||||
|
||||
ISceneEntity so = m_attMod.RezSingleAttachmentFromInventory(
|
||||
m_presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest);
|
||||
m_attMod.DetachSingleAttachmentToGround(so.LocalId, m_presence.ControllingClient);
|
||||
|
||||
// Check scene presence status
|
||||
Assert.That(m_presence.HasAttachments(), Is.False);
|
||||
List<SceneObjectGroup> attachments = m_presence.GetAttachments();
|
||||
Assert.That(attachments.Count, Is.EqualTo(0));
|
||||
|
||||
// Check appearance status
|
||||
Assert.That(m_presence.Appearance.GetAttachments().Count, Is.EqualTo(0));
|
||||
|
||||
// Check item status
|
||||
Assert.That(scene.InventoryService.GetItem(new InventoryItemBase(attItemId)), Is.Null);
|
||||
|
||||
// Check object in scene
|
||||
Assert.That(scene.GetSceneObjectGroup("att"), Is.Not.Null);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDetachAttachmentToInventory()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
AddPresence();
|
||||
|
||||
UUID attItemId = TestHelpers.ParseTail(0x2);
|
||||
UUID attAssetId = TestHelpers.ParseTail(0x3);
|
||||
string attName = "att";
|
||||
|
||||
UserInventoryHelpers.CreateInventoryItem(
|
||||
scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object);
|
||||
|
||||
m_attMod.RezSingleAttachmentFromInventory(
|
||||
m_presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest);
|
||||
m_attMod.DetachSingleAttachmentToInv(attItemId, m_presence.ControllingClient);
|
||||
|
||||
// Check status on scene presence
|
||||
Assert.That(m_presence.HasAttachments(), Is.False);
|
||||
List<SceneObjectGroup> attachments = m_presence.GetAttachments();
|
||||
Assert.That(attachments.Count, Is.EqualTo(0));
|
||||
|
||||
// Check item status
|
||||
Assert.That(m_presence.Appearance.GetAttachpoint(attItemId), Is.EqualTo(0));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test that attachments don't hang about in the scene when the agent is closed
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestRemoveAttachmentsOnAvatarExit()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
UUID userId = TestHelpers.ParseTail(0x1);
|
||||
UUID attItemId = TestHelpers.ParseTail(0x2);
|
||||
UUID attAssetId = TestHelpers.ParseTail(0x3);
|
||||
string attName = "att";
|
||||
|
||||
UserAccountHelpers.CreateUserWithInventory(scene, userId);
|
||||
InventoryItemBase attItem
|
||||
= UserInventoryHelpers.CreateInventoryItem(
|
||||
scene, attName, attItemId, attAssetId, userId, InventoryType.Object);
|
||||
|
||||
AgentCircuitData acd = SceneHelpers.GenerateAgentData(userId);
|
||||
acd.Appearance = new AvatarAppearance();
|
||||
acd.Appearance.SetAttachment((int)AttachmentPoint.Chest, attItem.ID, attItem.AssetID);
|
||||
ScenePresence presence = SceneHelpers.AddScenePresence(scene, acd);
|
||||
|
||||
SceneObjectGroup rezzedAtt = presence.GetAttachments()[0];
|
||||
|
||||
scene.IncomingCloseAgent(presence.UUID);
|
||||
|
||||
// Check that we can't retrieve this attachment from the scene.
|
||||
Assert.That(scene.GetSceneObjectGroup(rezzedAtt.UUID), Is.Null);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestRezAttachmentsOnAvatarEntrance()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
UUID userId = TestHelpers.ParseTail(0x1);
|
||||
UUID attItemId = TestHelpers.ParseTail(0x2);
|
||||
UUID attAssetId = TestHelpers.ParseTail(0x3);
|
||||
string attName = "att";
|
||||
|
||||
UserAccountHelpers.CreateUserWithInventory(scene, userId);
|
||||
InventoryItemBase attItem
|
||||
= UserInventoryHelpers.CreateInventoryItem(
|
||||
scene, attName, attItemId, attAssetId, userId, InventoryType.Object);
|
||||
|
||||
AgentCircuitData acd = SceneHelpers.GenerateAgentData(userId);
|
||||
acd.Appearance = new AvatarAppearance();
|
||||
acd.Appearance.SetAttachment((int)AttachmentPoint.Chest, attItem.ID, attItem.AssetID);
|
||||
ScenePresence presence = SceneHelpers.AddScenePresence(scene, acd);
|
||||
|
||||
Assert.That(presence.HasAttachments(), Is.True);
|
||||
List<SceneObjectGroup> attachments = presence.GetAttachments();
|
||||
|
||||
Assert.That(attachments.Count, Is.EqualTo(1));
|
||||
SceneObjectGroup attSo = attachments[0];
|
||||
Assert.That(attSo.Name, Is.EqualTo(attName));
|
||||
Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest));
|
||||
Assert.That(attSo.IsAttachment);
|
||||
Assert.That(attSo.UsesPhysics, Is.False);
|
||||
Assert.That(attSo.IsTemporary, Is.False);
|
||||
|
||||
// Check appearance status
|
||||
List<AvatarAttachment> retreivedAttachments = presence.Appearance.GetAttachments();
|
||||
Assert.That(retreivedAttachments.Count, Is.EqualTo(1));
|
||||
Assert.That(retreivedAttachments[0].AttachPoint, Is.EqualTo((int)AttachmentPoint.Chest));
|
||||
Assert.That(retreivedAttachments[0].ItemID, Is.EqualTo(attItemId));
|
||||
Assert.That(retreivedAttachments[0].AssetID, Is.EqualTo(attAssetId));
|
||||
Assert.That(presence.Appearance.GetAttachpoint(attItemId), Is.EqualTo((int)AttachmentPoint.Chest));
|
||||
}
|
||||
|
||||
// I'm commenting this test because scene setup NEEDS InventoryService to
|
||||
// be non-null
|
||||
//[Test]
|
||||
// public void T032_CrossAttachments()
|
||||
// {
|
||||
// TestHelpers.InMethod();
|
||||
//
|
||||
// ScenePresence presence = scene.GetScenePresence(agent1);
|
||||
// ScenePresence presence2 = scene2.GetScenePresence(agent1);
|
||||
// presence2.AddAttachment(sog1);
|
||||
// presence2.AddAttachment(sog2);
|
||||
//
|
||||
// ISharedRegionModule serialiser = new SerialiserModule();
|
||||
// SceneHelpers.SetupSceneModules(scene, new IniConfigSource(), serialiser);
|
||||
// SceneHelpers.SetupSceneModules(scene2, new IniConfigSource(), serialiser);
|
||||
//
|
||||
// Assert.That(presence.HasAttachments(), Is.False, "Presence has attachments before cross");
|
||||
//
|
||||
// //Assert.That(presence2.CrossAttachmentsIntoNewRegion(region1, true), Is.True, "Cross was not successful");
|
||||
// Assert.That(presence2.HasAttachments(), Is.False, "Presence2 objects were not deleted");
|
||||
// Assert.That(presence.HasAttachments(), Is.True, "Presence has not received new objects");
|
||||
// }
|
||||
}
|
||||
}
|
||||
@@ -104,7 +104,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
public void NewClient(IClientAPI client)
|
||||
{
|
||||
client.OnRequestWearables += SendWearables;
|
||||
client.OnSetAppearance += SetAppearance;
|
||||
client.OnSetAppearance += SetAppearanceFromClient;
|
||||
client.OnAvatarNowWearing += AvatarIsWearing;
|
||||
}
|
||||
|
||||
@@ -115,17 +115,21 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Check for the existence of the baked texture assets.
|
||||
/// </summary>
|
||||
/// <param name="client"></param>
|
||||
public bool ValidateBakedTextureCache(IClientAPI client)
|
||||
{
|
||||
return ValidateBakedTextureCache(client, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check for the existence of the baked texture assets. Request a rebake
|
||||
/// unless checkonly is true.
|
||||
/// </summary>
|
||||
/// <param name="client"></param>
|
||||
/// <param name="checkonly"></param>
|
||||
public bool ValidateBakedTextureCache(IClientAPI client)
|
||||
{
|
||||
return ValidateBakedTextureCache(client, true);
|
||||
}
|
||||
|
||||
private bool ValidateBakedTextureCache(IClientAPI client, bool checkonly)
|
||||
{
|
||||
ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
|
||||
@@ -147,6 +151,10 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
if (face == null)
|
||||
continue;
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[AVFACTORY]: Looking for texture {0}, id {1} for {2} {3}",
|
||||
// face.TextureID, idx, client.Name, client.AgentId);
|
||||
|
||||
// if the texture is one of the "defaults" then skip it
|
||||
// this should probably be more intelligent (skirt texture doesnt matter
|
||||
// if the avatar isnt wearing a skirt) but if any of the main baked
|
||||
@@ -156,34 +164,37 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
|
||||
defonly = false; // found a non-default texture reference
|
||||
|
||||
if (! CheckBakedTextureAsset(client,face.TextureID,idx))
|
||||
if (!CheckBakedTextureAsset(client, face.TextureID, idx))
|
||||
{
|
||||
// the asset didn't exist if we are only checking, then we found a bad
|
||||
// one and we're done otherwise, ask for a rebake
|
||||
if (checkonly) return false;
|
||||
if (checkonly)
|
||||
return false;
|
||||
|
||||
m_log.InfoFormat("[AVFACTORY]: missing baked texture {0}, requesting rebake",face.TextureID);
|
||||
m_log.InfoFormat("[AVFACTORY]: missing baked texture {0}, requesting rebake", face.TextureID);
|
||||
|
||||
client.SendRebakeAvatarTextures(face.TextureID);
|
||||
}
|
||||
}
|
||||
|
||||
m_log.DebugFormat("[AVFACTORY]: completed texture check for {0}", client.AgentId);
|
||||
m_log.DebugFormat("[AVFACTORY]: Completed texture check for {0}", client.AgentId);
|
||||
|
||||
// If we only found default textures, then the appearance is not cached
|
||||
return (defonly ? false : true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set appearance data (textureentry and slider settings) received from the client
|
||||
/// Set appearance data (texture asset IDs and slider settings) received from the client
|
||||
/// </summary>
|
||||
/// <param name="client"></param>
|
||||
/// <param name="texture"></param>
|
||||
/// <param name="visualParam"></param>
|
||||
public void SetAppearance(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams)
|
||||
public void SetAppearanceFromClient(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams)
|
||||
{
|
||||
ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
|
||||
if (sp == null)
|
||||
{
|
||||
m_log.WarnFormat("[AVFACTORY]: SetAppearance unable to find presence for {0}",client.AgentId);
|
||||
m_log.WarnFormat("[AVFACTORY]: SetAppearance unable to find presence for {0}", client.AgentId);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -211,18 +222,18 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
changed = sp.Appearance.SetTextureEntries(textureEntry) || changed;
|
||||
|
||||
m_log.InfoFormat("[AVFACTORY]: received texture update for {0}", client.AgentId);
|
||||
Util.FireAndForget(delegate(object o) { ValidateBakedTextureCache(client,false); });
|
||||
Util.FireAndForget(delegate(object o) { ValidateBakedTextureCache(client, false); });
|
||||
|
||||
// This appears to be set only in the final stage of the appearance
|
||||
// update transaction. In theory, we should be able to do an immediate
|
||||
// appearance send and save here.
|
||||
|
||||
// save only if there were changes, send no matter what (doesn't hurt to send twice)
|
||||
if (changed)
|
||||
QueueAppearanceSave(client.AgentId);
|
||||
QueueAppearanceSend(client.AgentId);
|
||||
}
|
||||
// save only if there were changes, send no matter what (doesn't hurt to send twice)
|
||||
if (changed)
|
||||
QueueAppearanceSave(client.AgentId);
|
||||
|
||||
QueueAppearanceSend(client.AgentId);
|
||||
}
|
||||
|
||||
// m_log.WarnFormat("[AVFACTORY]: complete SetAppearance for {0}:\n{1}",client.AgentId,sp.Appearance.ToString());
|
||||
@@ -246,6 +257,117 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
return true;
|
||||
}
|
||||
|
||||
public Dictionary<BakeType, Primitive.TextureEntryFace> GetBakedTextureFaces(UUID agentId)
|
||||
{
|
||||
ScenePresence sp = m_scene.GetScenePresence(agentId);
|
||||
|
||||
if (sp == null)
|
||||
return new Dictionary<BakeType, Primitive.TextureEntryFace>();
|
||||
|
||||
return GetBakedTextureFaces(sp);
|
||||
}
|
||||
|
||||
private Dictionary<BakeType, Primitive.TextureEntryFace> GetBakedTextureFaces(ScenePresence sp)
|
||||
{
|
||||
if (sp.IsChildAgent)
|
||||
return new Dictionary<BakeType, Primitive.TextureEntryFace>();
|
||||
|
||||
Dictionary<BakeType, Primitive.TextureEntryFace> bakedTextures
|
||||
= new Dictionary<BakeType, Primitive.TextureEntryFace>();
|
||||
|
||||
AvatarAppearance appearance = sp.Appearance;
|
||||
Primitive.TextureEntryFace[] faceTextures = appearance.Texture.FaceTextures;
|
||||
|
||||
foreach (int i in Enum.GetValues(typeof(BakeType)))
|
||||
{
|
||||
BakeType bakeType = (BakeType)i;
|
||||
|
||||
if (bakeType == BakeType.Unknown)
|
||||
continue;
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[AVFACTORY]: NPC avatar {0} has texture id {1} : {2}",
|
||||
// acd.AgentID, i, acd.Appearance.Texture.FaceTextures[i]);
|
||||
|
||||
int ftIndex = (int)AppearanceManager.BakeTypeToAgentTextureIndex(bakeType);
|
||||
bakedTextures[bakeType] = faceTextures[ftIndex];
|
||||
}
|
||||
|
||||
return bakedTextures;
|
||||
}
|
||||
|
||||
public bool SaveBakedTextures(UUID agentId)
|
||||
{
|
||||
ScenePresence sp = m_scene.GetScenePresence(agentId);
|
||||
|
||||
if (sp == null)
|
||||
return false;
|
||||
|
||||
m_log.DebugFormat(
|
||||
"[AV FACTORY]: Permanently saving baked textures for {0} in {1}",
|
||||
sp.Name, m_scene.RegionInfo.RegionName);
|
||||
|
||||
Dictionary<BakeType, Primitive.TextureEntryFace> bakedTextures = GetBakedTextureFaces(sp);
|
||||
|
||||
if (bakedTextures.Count == 0)
|
||||
return false;
|
||||
|
||||
foreach (BakeType bakeType in bakedTextures.Keys)
|
||||
{
|
||||
Primitive.TextureEntryFace bakedTextureFace = bakedTextures[bakeType];
|
||||
|
||||
if (bakedTextureFace == null)
|
||||
{
|
||||
m_log.WarnFormat(
|
||||
"[AV FACTORY]: No texture ID set for {0} for {1} in {2} not found when trying to save permanently",
|
||||
bakeType, sp.Name, m_scene.RegionInfo.RegionName);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
AssetBase asset = m_scene.AssetService.Get(bakedTextureFace.TextureID.ToString());
|
||||
|
||||
if (asset != null)
|
||||
{
|
||||
asset.Temporary = false;
|
||||
asset.Local = false;
|
||||
m_scene.AssetService.Store(asset);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.WarnFormat(
|
||||
"[AV FACTORY]: Baked texture id {0} not found for bake {1} for avatar {2} in {3} when trying to save permanently",
|
||||
bakedTextureFace.TextureID, bakeType, sp.Name, m_scene.RegionInfo.RegionName);
|
||||
}
|
||||
}
|
||||
|
||||
// for (int i = 0; i < faceTextures.Length; i++)
|
||||
// {
|
||||
//// m_log.DebugFormat(
|
||||
//// "[AVFACTORY]: NPC avatar {0} has texture id {1} : {2}",
|
||||
//// acd.AgentID, i, acd.Appearance.Texture.FaceTextures[i]);
|
||||
//
|
||||
// if (faceTextures[i] == null)
|
||||
// continue;
|
||||
//
|
||||
// AssetBase asset = m_scene.AssetService.Get(faceTextures[i].TextureID.ToString());
|
||||
//
|
||||
// if (asset != null)
|
||||
// {
|
||||
// asset.Temporary = false;
|
||||
// m_scene.AssetService.Store(asset);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// m_log.WarnFormat(
|
||||
// "[AV FACTORY]: Baked texture {0} for {1} in {2} not found when trying to save permanently",
|
||||
// faceTextures[i].TextureID, sp.Name, m_scene.RegionInfo.RegionName);
|
||||
// }
|
||||
// }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#region UpdateAppearanceTimer
|
||||
|
||||
/// <summary>
|
||||
@@ -278,26 +400,13 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleAppearanceSend(UUID agentid)
|
||||
private void SaveAppearance(UUID agentid)
|
||||
{
|
||||
ScenePresence sp = m_scene.GetScenePresence(agentid);
|
||||
if (sp == null)
|
||||
{
|
||||
m_log.WarnFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentid);
|
||||
return;
|
||||
}
|
||||
// We must set appearance parameters in the en_US culture in order to avoid issues where values are saved
|
||||
// in a culture where decimal points are commas and then reloaded in a culture which just treats them as
|
||||
// number seperators.
|
||||
Culture.SetCurrentCulture();
|
||||
|
||||
// m_log.WarnFormat("[AVFACTORY]: Handle appearance send for {0}", agentid);
|
||||
|
||||
// Send the appearance to everyone in the scene
|
||||
sp.SendAppearanceToAllOtherAgents();
|
||||
|
||||
// Send animations back to the avatar as well
|
||||
sp.Animator.SendAnimPack();
|
||||
}
|
||||
|
||||
private void HandleAppearanceSave(UUID agentid)
|
||||
{
|
||||
ScenePresence sp = m_scene.GetScenePresence(agentid);
|
||||
if (sp == null)
|
||||
{
|
||||
@@ -321,7 +430,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
{
|
||||
if (kvp.Value < now)
|
||||
{
|
||||
Util.FireAndForget(delegate(object o) { HandleAppearanceSend(kvp.Key); });
|
||||
Util.FireAndForget(delegate(object o) { SendAppearance(kvp.Key); });
|
||||
m_sendqueue.Remove(kvp.Key);
|
||||
}
|
||||
}
|
||||
@@ -334,7 +443,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
{
|
||||
if (kvp.Value < now)
|
||||
{
|
||||
Util.FireAndForget(delegate(object o) { HandleAppearanceSave(kvp.Key); });
|
||||
Util.FireAndForget(delegate(object o) { SaveAppearance(kvp.Key); });
|
||||
m_savequeue.Remove(kvp.Key);
|
||||
}
|
||||
}
|
||||
@@ -358,7 +467,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
return;
|
||||
}
|
||||
|
||||
// m_log.WarnFormat("[AVFACTORY]: Received request for wearables of {0}", client.AgentId);
|
||||
// m_log.DebugFormat("[AVFACTORY]: Received request for wearables of {0}", client.Name);
|
||||
|
||||
client.SendWearables(sp.Appearance.Wearables, sp.Appearance.Serial++);
|
||||
}
|
||||
@@ -380,11 +489,11 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
// m_log.WarnFormat("[AVFACTORY]: AvatarIsWearing called for {0}", client.AgentId);
|
||||
|
||||
// we need to clean out the existing textures
|
||||
sp.Appearance.ResetAppearance();
|
||||
sp.Appearance.ResetAppearance();
|
||||
|
||||
// operate on a copy of the appearance so we don't have to lock anything
|
||||
// operate on a copy of the appearance so we don't have to lock anything yet
|
||||
AvatarAppearance avatAppearance = new AvatarAppearance(sp.Appearance, false);
|
||||
|
||||
|
||||
foreach (AvatarWearingArgs.Wearable wear in e.NowWearing)
|
||||
{
|
||||
if (wear.Type < AvatarWearable.MAX_WEARABLES)
|
||||
@@ -396,12 +505,37 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
// This could take awhile since it needs to pull inventory
|
||||
SetAppearanceAssets(sp.UUID, ref avatAppearance);
|
||||
|
||||
// could get fancier with the locks here, but in the spirit of "last write wins"
|
||||
// this should work correctly, also, we don't need to send the appearance here
|
||||
// since the "iswearing" will trigger a new set of visual param and baked texture changes
|
||||
// when those complete, the new appearance will be sent
|
||||
sp.Appearance = avatAppearance;
|
||||
QueueAppearanceSave(client.AgentId);
|
||||
lock (m_setAppearanceLock)
|
||||
{
|
||||
// Update only those fields that we have changed. This is important because the viewer
|
||||
// often sends AvatarIsWearing and SetAppearance packets at once, and AvatarIsWearing
|
||||
// shouldn't overwrite the changes made in SetAppearance.
|
||||
sp.Appearance.Wearables = avatAppearance.Wearables;
|
||||
sp.Appearance.Texture = avatAppearance.Texture;
|
||||
|
||||
// We don't need to send the appearance here since the "iswearing" will trigger a new set
|
||||
// of visual param and baked texture changes. When those complete, the new appearance will be sent
|
||||
|
||||
QueueAppearanceSave(client.AgentId);
|
||||
}
|
||||
}
|
||||
|
||||
public bool SendAppearance(UUID agentId)
|
||||
{
|
||||
ScenePresence sp = m_scene.GetScenePresence(agentId);
|
||||
if (sp == null)
|
||||
{
|
||||
m_log.WarnFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentId);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Send the appearance to everyone in the scene
|
||||
sp.SendAppearanceToAllOtherAgents();
|
||||
|
||||
// Send animations back to the avatar as well
|
||||
sp.Animator.SendAnimPack();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void SetAppearanceAssets(UUID userID, ref AvatarAppearance appearance)
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Nini.Config;
|
||||
using NUnit.Framework;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.CoreModules.Asset;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Tests.Common;
|
||||
using OpenSim.Tests.Common.Mock;
|
||||
|
||||
namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
{
|
||||
[TestFixture]
|
||||
public class AvatarFactoryModuleTests
|
||||
{
|
||||
/// <summary>
|
||||
/// Only partial right now since we don't yet test that it's ended up in the avatar appearance service.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestSetAppearance()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
UUID userId = TestHelpers.ParseTail(0x1);
|
||||
|
||||
AvatarFactoryModule afm = new AvatarFactoryModule();
|
||||
TestScene scene = SceneHelpers.SetupScene();
|
||||
SceneHelpers.SetupSceneModules(scene, afm);
|
||||
IClientAPI tc = SceneHelpers.AddScenePresence(scene, userId).ControllingClient;
|
||||
|
||||
byte[] visualParams = new byte[AvatarAppearance.VISUALPARAM_COUNT];
|
||||
for (byte i = 0; i < visualParams.Length; i++)
|
||||
visualParams[i] = i;
|
||||
|
||||
afm.SetAppearanceFromClient(tc, new Primitive.TextureEntry(TestHelpers.ParseTail(0x10)), visualParams);
|
||||
|
||||
ScenePresence sp = scene.GetScenePresence(userId);
|
||||
|
||||
// TODO: Check baked texture
|
||||
Assert.AreEqual(visualParams, sp.Appearance.VisualParams);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestSaveBakedTextures()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
UUID userId = TestHelpers.ParseTail(0x1);
|
||||
UUID eyesTextureId = TestHelpers.ParseTail(0x2);
|
||||
|
||||
// We need an asset cache because otherwise the LocalAssetServiceConnector will short-circuit directly
|
||||
// to the AssetService, which will then store temporary and local assets permanently
|
||||
CoreAssetCache assetCache = new CoreAssetCache();
|
||||
|
||||
AvatarFactoryModule afm = new AvatarFactoryModule();
|
||||
TestScene scene = SceneHelpers.SetupScene(assetCache);
|
||||
SceneHelpers.SetupSceneModules(scene, afm);
|
||||
IClientAPI tc = SceneHelpers.AddScenePresence(scene, userId).ControllingClient;
|
||||
|
||||
// TODO: Use the actual BunchOfCaps functionality once we slot in the CapabilitiesModules
|
||||
AssetBase uploadedAsset;
|
||||
uploadedAsset = new AssetBase(eyesTextureId, "Baked Texture", (sbyte)AssetType.Texture, userId.ToString());
|
||||
uploadedAsset.Data = new byte[] { 2 };
|
||||
uploadedAsset.Temporary = true;
|
||||
uploadedAsset.Local = true; // Local assets aren't persisted, non-local are
|
||||
scene.AssetService.Store(uploadedAsset);
|
||||
|
||||
byte[] visualParams = new byte[AvatarAppearance.VISUALPARAM_COUNT];
|
||||
for (byte i = 0; i < visualParams.Length; i++)
|
||||
visualParams[i] = i;
|
||||
|
||||
Primitive.TextureEntry bakedTextureEntry = new Primitive.TextureEntry(TestHelpers.ParseTail(0x10));
|
||||
uint eyesFaceIndex = (uint)AppearanceManager.BakeTypeToAgentTextureIndex(BakeType.Eyes);
|
||||
Primitive.TextureEntryFace eyesFace = bakedTextureEntry.CreateFace(eyesFaceIndex);
|
||||
eyesFace.TextureID = eyesTextureId;
|
||||
|
||||
afm.SetAppearanceFromClient(tc, bakedTextureEntry, visualParams);
|
||||
afm.SaveBakedTextures(userId);
|
||||
// Dictionary<BakeType, Primitive.TextureEntryFace> bakedTextures = afm.GetBakedTextureFaces(userId);
|
||||
|
||||
// We should also inpsect the asset data store layer directly, but this is difficult to get at right now.
|
||||
assetCache.Clear();
|
||||
|
||||
AssetBase eyesBake = scene.AssetService.Get(eyesTextureId.ToString());
|
||||
Assert.That(eyesBake, Is.Not.Null);
|
||||
Assert.That(eyesBake.Temporary, Is.False);
|
||||
Assert.That(eyesBake.Local, Is.False);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -124,7 +124,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog
|
||||
|
||||
ScenePresence sp = m_scene.GetScenePresence(avatarID);
|
||||
if (sp != null)
|
||||
sp.ControllingClient.SendDialog(objectName, objectID, ownerFirstName, ownerLastName, message, textureID, ch, buttonlabels);
|
||||
sp.ControllingClient.SendDialog(
|
||||
objectName, objectID, ownerID, ownerFirstName, ownerLastName, message, textureID, ch, buttonlabels);
|
||||
}
|
||||
|
||||
public void SendUrlToUser(
|
||||
@@ -140,10 +141,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog
|
||||
{
|
||||
UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, ownerid);
|
||||
string ownerFirstName, ownerLastName;
|
||||
UUID ownerID = UUID.Zero;
|
||||
if (account != null)
|
||||
{
|
||||
ownerFirstName = account.FirstName;
|
||||
ownerLastName = account.LastName;
|
||||
ownerID = account.PrincipalID;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -154,7 +157,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog
|
||||
ScenePresence sp = m_scene.GetScenePresence(avatarid);
|
||||
|
||||
if (sp != null)
|
||||
sp.ControllingClient.SendTextBoxRequest(message, chatChannel, name, ownerFirstName, ownerLastName, objectid);
|
||||
sp.ControllingClient.SendTextBoxRequest(message, chatChannel, name, ownerID, ownerFirstName, ownerLastName, objectid);
|
||||
}
|
||||
|
||||
public void SendNotificationToUsersInRegion(
|
||||
|
||||
@@ -49,6 +49,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
{
|
||||
public class FriendsModule : ISharedRegionModule, IFriendsModule
|
||||
{
|
||||
protected bool m_Enabled = false;
|
||||
|
||||
protected class UserFriendData
|
||||
{
|
||||
public UUID PrincipalID;
|
||||
@@ -67,7 +69,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly FriendInfo[] EMPTY_FRIENDS = new FriendInfo[0];
|
||||
protected static readonly FriendInfo[] EMPTY_FRIENDS = new FriendInfo[0];
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
protected List<Scene> m_Scenes = new List<Scene>();
|
||||
@@ -130,7 +132,24 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
}
|
||||
}
|
||||
|
||||
#region ISharedRegionModule
|
||||
public void Initialise(IConfigSource config)
|
||||
{
|
||||
IConfig moduleConfig = config.Configs["Modules"];
|
||||
if (moduleConfig != null)
|
||||
{
|
||||
string name = moduleConfig.GetString("FriendsModule", "FriendsModule");
|
||||
if (name == Name)
|
||||
{
|
||||
InitModule(config);
|
||||
|
||||
m_Enabled = true;
|
||||
m_log.InfoFormat("[FRIENDS MODULE]: {0} enabled.", Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void InitModule(IConfigSource config)
|
||||
{
|
||||
IConfig friendsConfig = config.Configs["Friends"];
|
||||
if (friendsConfig != null)
|
||||
@@ -153,7 +172,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
m_log.Error("[FRIENDS]: No Connector defined in section Friends, or failed to load, cannot continue");
|
||||
throw new Exception("Connector load error");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
@@ -164,8 +182,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
{
|
||||
}
|
||||
|
||||
public void AddRegion(Scene scene)
|
||||
public virtual void AddRegion(Scene scene)
|
||||
{
|
||||
if (!m_Enabled)
|
||||
return;
|
||||
m_log.DebugFormat("[FRIENDS MODULE]: AddRegion on {0}", Name);
|
||||
|
||||
m_Scenes.Add(scene);
|
||||
scene.RegisterModuleInterface<IFriendsModule>(this);
|
||||
|
||||
@@ -181,10 +203,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
|
||||
public void RemoveRegion(Scene scene)
|
||||
{
|
||||
if (!m_Enabled)
|
||||
return;
|
||||
|
||||
m_Scenes.Remove(scene);
|
||||
}
|
||||
|
||||
public string Name
|
||||
public virtual string Name
|
||||
{
|
||||
get { return "FriendsModule"; }
|
||||
}
|
||||
@@ -194,13 +219,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
public uint GetFriendPerms(UUID principalID, UUID friendID)
|
||||
#endregion
|
||||
|
||||
public virtual uint GetFriendPerms(UUID principalID, UUID friendID)
|
||||
{
|
||||
FriendInfo[] friends = GetFriends(principalID);
|
||||
foreach (FriendInfo fi in friends)
|
||||
FriendInfo finfo = GetFriend(friends, friendID);
|
||||
if (finfo != null)
|
||||
{
|
||||
if (fi.Friend == friendID.ToString())
|
||||
return (uint)fi.TheirFlags;
|
||||
return (uint)finfo.TheirFlags;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -214,30 +241,34 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
client.OnTerminateFriendship += OnTerminateFriendship;
|
||||
client.OnGrantUserRights += OnGrantUserRights;
|
||||
|
||||
// Asynchronously fetch the friends list or increment the refcount for the existing
|
||||
// friends list
|
||||
Util.FireAndForget(
|
||||
delegate(object o)
|
||||
{
|
||||
lock (m_Friends)
|
||||
{
|
||||
UserFriendData friendsData;
|
||||
if (m_Friends.TryGetValue(client.AgentId, out friendsData))
|
||||
{
|
||||
friendsData.Refcount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
friendsData = new UserFriendData();
|
||||
friendsData.PrincipalID = client.AgentId;
|
||||
friendsData.Friends = FriendsService.GetFriends(client.AgentId);
|
||||
friendsData.Refcount = 1;
|
||||
Util.FireAndForget(delegate { FetchFriendslist(client); });
|
||||
}
|
||||
|
||||
m_Friends[client.AgentId] = friendsData;
|
||||
}
|
||||
}
|
||||
/// Fetch the friends list or increment the refcount for the existing
|
||||
/// friends list
|
||||
/// Returns true if the list was fetched, false if it wasn't
|
||||
protected virtual bool FetchFriendslist(IClientAPI client)
|
||||
{
|
||||
UUID agentID = client.AgentId;
|
||||
lock (m_Friends)
|
||||
{
|
||||
UserFriendData friendsData;
|
||||
if (m_Friends.TryGetValue(agentID, out friendsData))
|
||||
{
|
||||
friendsData.Refcount++;
|
||||
return false;
|
||||
}
|
||||
);
|
||||
else
|
||||
{
|
||||
friendsData = new UserFriendData();
|
||||
friendsData.PrincipalID = agentID;
|
||||
friendsData.Friends = GetFriendsFromService(client);
|
||||
friendsData.Refcount = 1;
|
||||
|
||||
m_Friends[agentID] = friendsData;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnClientClosed(UUID agentID, Scene scene)
|
||||
@@ -263,14 +294,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
|
||||
private void OnMakeRootAgent(ScenePresence sp)
|
||||
{
|
||||
UUID agentID = sp.ControllingClient.AgentId;
|
||||
UpdateFriendsCache(agentID);
|
||||
RefetchFriends(sp.ControllingClient);
|
||||
}
|
||||
|
||||
private void OnClientLogin(IClientAPI client)
|
||||
{
|
||||
UUID agentID = client.AgentId;
|
||||
|
||||
//m_log.DebugFormat("[XXX]: OnClientLogin!");
|
||||
// Inform the friends that this user is online
|
||||
StatusChange(agentID, true);
|
||||
|
||||
@@ -279,7 +310,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
m_NeedsListOfFriends.Add(agentID);
|
||||
}
|
||||
|
||||
public void SendFriendsOnlineIfNeeded(IClientAPI client)
|
||||
public virtual bool SendFriendsOnlineIfNeeded(IClientAPI client)
|
||||
{
|
||||
UUID agentID = client.AgentId;
|
||||
|
||||
@@ -287,7 +318,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
lock (m_NeedsListOfFriends)
|
||||
{
|
||||
if (!m_NeedsListOfFriends.Remove(agentID))
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Send the friends online
|
||||
@@ -313,10 +344,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
foreach (string fid in outstanding)
|
||||
{
|
||||
UUID fromAgentID;
|
||||
if (!UUID.TryParse(fid, out fromAgentID))
|
||||
string firstname = "Unknown", lastname = "User";
|
||||
if (!GetAgentInfo(client.Scene.RegionInfo.ScopeID, fid, out fromAgentID, out firstname, out lastname))
|
||||
{
|
||||
m_log.DebugFormat("[FRIENDS MODULE]: skipping malformed friend {0}", fid);
|
||||
continue;
|
||||
|
||||
UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(client.Scene.RegionInfo.ScopeID, fromAgentID);
|
||||
}
|
||||
|
||||
PresenceInfo presence = null;
|
||||
PresenceInfo[] presences = PresenceService.GetAgents(new string[] { fid });
|
||||
@@ -326,13 +359,37 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
im.offline = 0;
|
||||
|
||||
im.fromAgentID = fromAgentID.Guid;
|
||||
im.fromAgentName = account.FirstName + " " + account.LastName;
|
||||
im.fromAgentName = firstname + " " + lastname;
|
||||
im.offline = (byte)((presence == null) ? 1 : 0);
|
||||
im.imSessionID = im.fromAgentID;
|
||||
im.message = FriendshipMessage(fid);
|
||||
|
||||
// Finally
|
||||
LocalFriendshipOffered(agentID, im);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected virtual string FriendshipMessage(string friendID)
|
||||
{
|
||||
return "Will you be my friend?";
|
||||
}
|
||||
|
||||
protected virtual bool GetAgentInfo(UUID scopeID, string fid, out UUID agentID, out string first, out string last)
|
||||
{
|
||||
first = "Unknown"; last = "User";
|
||||
if (!UUID.TryParse(fid, out agentID))
|
||||
return false;
|
||||
|
||||
UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(scopeID, agentID);
|
||||
if (account != null)
|
||||
{
|
||||
first = account.FirstName;
|
||||
last = account.LastName;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
List<UUID> GetOnlineFriends(UUID userID)
|
||||
@@ -348,19 +405,22 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
}
|
||||
|
||||
if (friendList.Count > 0)
|
||||
{
|
||||
PresenceInfo[] presence = PresenceService.GetAgents(friendList.ToArray());
|
||||
foreach (PresenceInfo pi in presence)
|
||||
{
|
||||
UUID presenceID;
|
||||
if (UUID.TryParse(pi.UserID, out presenceID))
|
||||
online.Add(presenceID);
|
||||
}
|
||||
}
|
||||
GetOnlineFriends(userID, friendList, online);
|
||||
|
||||
return online;
|
||||
}
|
||||
|
||||
protected virtual void GetOnlineFriends(UUID userID, List<string> friendList, /*collector*/ List<UUID> online)
|
||||
{
|
||||
PresenceInfo[] presence = PresenceService.GetAgents(friendList.ToArray());
|
||||
foreach (PresenceInfo pi in presence)
|
||||
{
|
||||
UUID presenceID;
|
||||
if (UUID.TryParse(pi.UserID, out presenceID))
|
||||
online.Add(presenceID);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Find the client for a ID
|
||||
/// </summary>
|
||||
@@ -415,51 +475,51 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
Util.FireAndForget(
|
||||
delegate
|
||||
{
|
||||
foreach (FriendInfo fi in friendList)
|
||||
{
|
||||
//m_log.DebugFormat("[FRIENDS]: Notifying {0}", fi.PrincipalID);
|
||||
// Notify about this user status
|
||||
StatusNotify(fi, agentID, online);
|
||||
}
|
||||
m_log.DebugFormat("[FRIENDS MODULE]: Notifying {0} friends", friendList.Count);
|
||||
// Notify about this user status
|
||||
StatusNotify(friendList, agentID, online);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private void StatusNotify(FriendInfo friend, UUID userID, bool online)
|
||||
protected virtual void StatusNotify(List<FriendInfo> friendList, UUID userID, bool online)
|
||||
{
|
||||
UUID friendID;
|
||||
if (UUID.TryParse(friend.Friend, out friendID))
|
||||
foreach (FriendInfo friend in friendList)
|
||||
{
|
||||
// Try local
|
||||
if (LocalStatusNotification(userID, friendID, online))
|
||||
return;
|
||||
|
||||
// The friend is not here [as root]. Let's forward.
|
||||
PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() });
|
||||
if (friendSessions != null && friendSessions.Length > 0)
|
||||
UUID friendID;
|
||||
if (UUID.TryParse(friend.Friend, out friendID))
|
||||
{
|
||||
PresenceInfo friendSession = null;
|
||||
foreach (PresenceInfo pinfo in friendSessions)
|
||||
if (pinfo.RegionID != UUID.Zero) // let's guard against sessions-gone-bad
|
||||
{
|
||||
friendSession = pinfo;
|
||||
break;
|
||||
}
|
||||
// Try local
|
||||
if (LocalStatusNotification(userID, friendID, online))
|
||||
return;
|
||||
|
||||
if (friendSession != null)
|
||||
// The friend is not here [as root]. Let's forward.
|
||||
PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() });
|
||||
if (friendSessions != null && friendSessions.Length > 0)
|
||||
{
|
||||
GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID);
|
||||
//m_log.DebugFormat("[FRIENDS]: Remote Notify to region {0}", region.RegionName);
|
||||
m_FriendsSimConnector.StatusNotify(region, userID, friendID, online);
|
||||
}
|
||||
}
|
||||
PresenceInfo friendSession = null;
|
||||
foreach (PresenceInfo pinfo in friendSessions)
|
||||
if (pinfo.RegionID != UUID.Zero) // let's guard against sessions-gone-bad
|
||||
{
|
||||
friendSession = pinfo;
|
||||
break;
|
||||
}
|
||||
|
||||
// Friend is not online. Ignore.
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.WarnFormat("[FRIENDS]: Error parsing friend ID {0}", friend.Friend);
|
||||
if (friendSession != null)
|
||||
{
|
||||
GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID);
|
||||
//m_log.DebugFormat("[FRIENDS]: Remote Notify to region {0}", region.RegionName);
|
||||
m_FriendsSimConnector.StatusNotify(region, userID, friendID, online);
|
||||
}
|
||||
}
|
||||
|
||||
// Friend is not online. Ignore.
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.WarnFormat("[FRIENDS]: Error parsing friend ID {0}", friend.Friend);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -475,7 +535,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
|
||||
// This user wants to be friends with the other user.
|
||||
// Let's add the relation backwards, in case the other is not online
|
||||
FriendsService.StoreFriend(friendID, principalID.ToString(), 0);
|
||||
StoreBackwards(friendID, principalID);
|
||||
|
||||
// Now let's ask the other user to be friends with this user
|
||||
ForwardFriendshipOffer(principalID, friendID, im);
|
||||
@@ -487,11 +547,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
// !!!!!!!! This is a hack so that we don't have to keep state (transactionID/imSessionID)
|
||||
// We stick this agent's ID as imSession, so that it's directly available on the receiving end
|
||||
im.imSessionID = im.fromAgentID;
|
||||
im.fromAgentName = GetFriendshipRequesterName(agentID);
|
||||
|
||||
// Try the local sim
|
||||
UserAccount account = UserAccountService.GetUserAccount(UUID.Zero, agentID);
|
||||
im.fromAgentName = (account == null) ? "Unknown" : account.FirstName + " " + account.LastName;
|
||||
|
||||
// Try the local sim
|
||||
if (LocalFriendshipOffered(friendID, im))
|
||||
return;
|
||||
|
||||
@@ -509,12 +567,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
// If the prospective friend is not online, he'll get the message upon login.
|
||||
}
|
||||
|
||||
protected virtual string GetFriendshipRequesterName(UUID agentID)
|
||||
{
|
||||
UserAccount account = UserAccountService.GetUserAccount(UUID.Zero, agentID);
|
||||
return (account == null) ? "Unknown" : account.FirstName + " " + account.LastName;
|
||||
}
|
||||
|
||||
private void OnApproveFriendRequest(IClientAPI client, UUID agentID, UUID friendID, List<UUID> callingCardFolders)
|
||||
{
|
||||
m_log.DebugFormat("[FRIENDS]: {0} accepted friendship from {1}", agentID, friendID);
|
||||
|
||||
FriendsService.StoreFriend(agentID, friendID.ToString(), 1);
|
||||
FriendsService.StoreFriend(friendID, agentID.ToString(), 1);
|
||||
|
||||
StoreFriendships(agentID, friendID);
|
||||
|
||||
ICallingCardModule ccm = client.Scene.RequestModuleInterface<ICallingCardModule>();
|
||||
if (ccm != null)
|
||||
@@ -523,7 +586,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
}
|
||||
|
||||
// Update the local cache
|
||||
UpdateFriendsCache(agentID);
|
||||
RefetchFriends(client);
|
||||
|
||||
//
|
||||
// Notify the friend
|
||||
@@ -554,8 +617,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
{
|
||||
m_log.DebugFormat("[FRIENDS]: {0} denied friendship to {1}", agentID, friendID);
|
||||
|
||||
FriendsService.Delete(agentID, friendID.ToString());
|
||||
FriendsService.Delete(friendID, agentID.ToString());
|
||||
DeleteFriendship(agentID, friendID);
|
||||
|
||||
//
|
||||
// Notify the friend
|
||||
@@ -582,11 +644,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
|
||||
private void OnTerminateFriendship(IClientAPI client, UUID agentID, UUID exfriendID)
|
||||
{
|
||||
FriendsService.Delete(agentID, exfriendID.ToString());
|
||||
FriendsService.Delete(exfriendID, agentID.ToString());
|
||||
if (!DeleteFriendship(agentID, exfriendID))
|
||||
client.SendAlertMessage("Unable to terminate friendship on this sim.");
|
||||
|
||||
// Update local cache
|
||||
UpdateFriendsCache(agentID);
|
||||
RefetchFriends(client);
|
||||
|
||||
client.SendTerminateFriend(exfriendID);
|
||||
|
||||
@@ -612,23 +674,25 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
|
||||
private void OnGrantUserRights(IClientAPI remoteClient, UUID requester, UUID target, int rights)
|
||||
{
|
||||
m_log.DebugFormat("[FRIENDS MODULE]: User {0} changing rights to {1} for friend {2}", requester, rights, target);
|
||||
|
||||
FriendInfo[] friends = GetFriends(remoteClient.AgentId);
|
||||
if (friends.Length == 0)
|
||||
return;
|
||||
|
||||
m_log.DebugFormat("[FRIENDS MODULE]: User {0} changing rights to {1} for friend {2}", requester, rights, target);
|
||||
// Let's find the friend in this user's friend list
|
||||
FriendInfo friend = null;
|
||||
foreach (FriendInfo fi in friends)
|
||||
{
|
||||
if (fi.Friend == target.ToString())
|
||||
friend = fi;
|
||||
return;
|
||||
}
|
||||
|
||||
// Let's find the friend in this user's friend list
|
||||
FriendInfo friend = GetFriend(friends, target);
|
||||
|
||||
if (friend != null) // Found it
|
||||
{
|
||||
// Store it on the DB
|
||||
FriendsService.StoreFriend(requester, target.ToString(), rights);
|
||||
if (!StoreRights(requester, target, rights))
|
||||
{
|
||||
remoteClient.SendAlertMessage("Unable to grant rights.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Store it in the local cache
|
||||
int myFlags = friend.MyFlags;
|
||||
@@ -658,6 +722,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
m_log.DebugFormat("[FRIENDS MODULE]: friend {0} not found for {1}", target, requester);
|
||||
}
|
||||
|
||||
protected virtual FriendInfo GetFriend(FriendInfo[] friends, UUID friendID)
|
||||
{
|
||||
foreach (FriendInfo fi in friends)
|
||||
{
|
||||
if (fi.Friend == friendID.ToString())
|
||||
return fi;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
#region Local
|
||||
@@ -693,7 +769,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
|
||||
|
||||
// Update the local cache
|
||||
UpdateFriendsCache(friendID);
|
||||
RefetchFriends(friendClient);
|
||||
|
||||
// we're done
|
||||
return true;
|
||||
@@ -726,7 +802,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
// the friend in this sim as root agent
|
||||
friendClient.SendTerminateFriend(exfriendID);
|
||||
// update local cache
|
||||
UpdateFriendsCache(exfriendID);
|
||||
RefetchFriends(friendClient);
|
||||
// we're done
|
||||
return true;
|
||||
}
|
||||
@@ -756,15 +832,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
}
|
||||
|
||||
// Update local cache
|
||||
lock (m_Friends)
|
||||
{
|
||||
FriendInfo[] friends = GetFriends(friendID);
|
||||
foreach (FriendInfo finfo in friends)
|
||||
{
|
||||
if (finfo.Friend == userID.ToString())
|
||||
finfo.TheirFlags = rights;
|
||||
}
|
||||
}
|
||||
UpdateLocalCache(userID, friendID, rights);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -775,10 +843,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
|
||||
public bool LocalStatusNotification(UUID userID, UUID friendID, bool online)
|
||||
{
|
||||
//m_log.DebugFormat("[FRIENDS]: Local Status Notify {0} that user {1} is {2}", friendID, userID, online);
|
||||
IClientAPI friendClient = LocateClientObject(friendID);
|
||||
if (friendClient != null)
|
||||
{
|
||||
//m_log.DebugFormat("[FRIENDS]: Local Status Notify {0} that user {1} is {2}", friendID, userID, online);
|
||||
// the friend in this sim as root agent
|
||||
if (online)
|
||||
friendClient.SendAgentOnline(new UUID[] { userID });
|
||||
@@ -793,7 +861,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
|
||||
#endregion
|
||||
|
||||
private FriendInfo[] GetFriends(UUID agentID)
|
||||
#region Get / Set friends in several flavours
|
||||
/// <summary>
|
||||
/// Get friends from local cache only
|
||||
/// </summary>
|
||||
/// <param name="agentID"></param>
|
||||
/// <returns></returns>
|
||||
protected FriendInfo[] GetFriends(UUID agentID)
|
||||
{
|
||||
UserFriendData friendsData;
|
||||
|
||||
@@ -806,14 +880,63 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
return EMPTY_FRIENDS;
|
||||
}
|
||||
|
||||
private void UpdateFriendsCache(UUID agentID)
|
||||
/// <summary>
|
||||
/// Update loca cache only
|
||||
/// </summary>
|
||||
/// <param name="userID"></param>
|
||||
/// <param name="friendID"></param>
|
||||
/// <param name="rights"></param>
|
||||
protected void UpdateLocalCache(UUID userID, UUID friendID, int rights)
|
||||
{
|
||||
// Update local cache
|
||||
lock (m_Friends)
|
||||
{
|
||||
FriendInfo[] friends = GetFriends(friendID);
|
||||
FriendInfo finfo = GetFriend(friends, userID);
|
||||
finfo.TheirFlags = rights;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual FriendInfo[] GetFriendsFromService(IClientAPI client)
|
||||
{
|
||||
return FriendsService.GetFriends(client.AgentId);
|
||||
}
|
||||
|
||||
private void RefetchFriends(IClientAPI client)
|
||||
{
|
||||
UUID agentID = client.AgentId;
|
||||
lock (m_Friends)
|
||||
{
|
||||
UserFriendData friendsData;
|
||||
if (m_Friends.TryGetValue(agentID, out friendsData))
|
||||
friendsData.Friends = FriendsService.GetFriends(agentID);
|
||||
friendsData.Friends = GetFriendsFromService(client);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual bool StoreRights(UUID agentID, UUID friendID, int rights)
|
||||
{
|
||||
FriendsService.StoreFriend(agentID.ToString(), friendID.ToString(), rights);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected virtual void StoreBackwards(UUID friendID, UUID agentID)
|
||||
{
|
||||
FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), 0);
|
||||
}
|
||||
|
||||
protected virtual void StoreFriendships(UUID agentID, UUID friendID)
|
||||
{
|
||||
FriendsService.StoreFriend(agentID.ToString(), friendID.ToString(), 1);
|
||||
FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), 1);
|
||||
}
|
||||
|
||||
protected virtual bool DeleteFriendship(UUID agentID, UUID exfriendID)
|
||||
{
|
||||
FriendsService.Delete(agentID, exfriendID.ToString());
|
||||
FriendsService.Delete(exfriendID, agentID.ToString());
|
||||
return true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
623
OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs
Normal file
623
OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs
Normal file
@@ -0,0 +1,623 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
using Nwc.XmlRpc;
|
||||
using Mono.Addins;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using OpenSim.Services.Connectors.Hypergrid;
|
||||
using FriendInfo = OpenSim.Services.Interfaces.FriendInfo;
|
||||
using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo;
|
||||
using GridRegion = OpenSim.Services.Interfaces.GridRegion;
|
||||
|
||||
namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
{
|
||||
public class HGFriendsModule : FriendsModule, ISharedRegionModule, IFriendsModule, IFriendsSimConnector
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
#region ISharedRegionModule
|
||||
public override string Name
|
||||
{
|
||||
get { return "HGFriendsModule"; }
|
||||
}
|
||||
|
||||
public override void AddRegion(Scene scene)
|
||||
{
|
||||
if (!m_Enabled)
|
||||
return;
|
||||
|
||||
base.AddRegion(scene);
|
||||
scene.RegisterModuleInterface<IFriendsSimConnector>(this);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IFriendsSimConnector
|
||||
|
||||
/// <summary>
|
||||
/// Notify the user that the friend's status changed
|
||||
/// </summary>
|
||||
/// <param name="userID">user to be notified</param>
|
||||
/// <param name="friendID">friend whose status changed</param>
|
||||
/// <param name="online">status</param>
|
||||
/// <returns></returns>
|
||||
public bool StatusNotify(UUID friendID, UUID userID, bool online)
|
||||
{
|
||||
return LocalStatusNotification(friendID, userID, online);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
protected override bool FetchFriendslist(IClientAPI client)
|
||||
{
|
||||
if (base.FetchFriendslist(client))
|
||||
{
|
||||
UUID agentID = client.AgentId;
|
||||
// we do this only for the root agent
|
||||
if (m_Friends[agentID].Refcount == 1)
|
||||
{
|
||||
// We need to preload the user management cache with the names
|
||||
// of foreign friends, just like we do with SOPs' creators
|
||||
foreach (FriendInfo finfo in m_Friends[agentID].Friends)
|
||||
{
|
||||
if (finfo.TheirFlags != -1)
|
||||
{
|
||||
UUID id;
|
||||
if (!UUID.TryParse(finfo.Friend, out id))
|
||||
{
|
||||
string url = string.Empty, first = string.Empty, last = string.Empty, tmp = string.Empty;
|
||||
if (Util.ParseUniversalUserIdentifier(finfo.Friend, out id, out url, out first, out last, out tmp))
|
||||
{
|
||||
IUserManagement uMan = m_Scenes[0].RequestModuleInterface<IUserManagement>();
|
||||
uMan.AddUser(id, url + ";" + first + " " + last);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool SendFriendsOnlineIfNeeded(IClientAPI client)
|
||||
{
|
||||
if (base.SendFriendsOnlineIfNeeded(client))
|
||||
{
|
||||
AgentCircuitData aCircuit = ((Scene)client.Scene).AuthenticateHandler.GetAgentCircuitData(client.AgentId);
|
||||
if (aCircuit != null && (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0)
|
||||
{
|
||||
UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(client.Scene.RegionInfo.ScopeID, client.AgentId);
|
||||
if (account == null) // foreign
|
||||
{
|
||||
FriendInfo[] friends = GetFriends(client.AgentId);
|
||||
foreach (FriendInfo f in friends)
|
||||
{
|
||||
client.SendChangeUserRights(new UUID(f.Friend), client.AgentId, f.TheirFlags);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected override void GetOnlineFriends(UUID userID, List<string> friendList, /*collector*/ List<UUID> online)
|
||||
{
|
||||
List<string> fList = new List<string>();
|
||||
foreach (string s in friendList)
|
||||
fList.Add(s.Substring(0, 36));
|
||||
|
||||
PresenceInfo[] presence = PresenceService.GetAgents(fList.ToArray());
|
||||
foreach (PresenceInfo pi in presence)
|
||||
{
|
||||
UUID presenceID;
|
||||
if (UUID.TryParse(pi.UserID, out presenceID))
|
||||
online.Add(presenceID);
|
||||
}
|
||||
}
|
||||
|
||||
//protected override void GetOnlineFriends(UUID userID, List<string> friendList, /*collector*/ List<UUID> online)
|
||||
//{
|
||||
// // Let's single out the UUIs
|
||||
// List<string> localFriends = new List<string>();
|
||||
// List<string> foreignFriends = new List<string>();
|
||||
// string tmp = string.Empty;
|
||||
|
||||
// foreach (string s in friendList)
|
||||
// {
|
||||
// UUID id;
|
||||
// if (UUID.TryParse(s, out id))
|
||||
// localFriends.Add(s);
|
||||
// else if (Util.ParseUniversalUserIdentifier(s, out id, out tmp, out tmp, out tmp, out tmp))
|
||||
// {
|
||||
// foreignFriends.Add(s);
|
||||
// // add it here too, who knows maybe the foreign friends happens to be on this grid
|
||||
// localFriends.Add(id.ToString());
|
||||
// }
|
||||
// }
|
||||
|
||||
// // OK, see who's present on this grid
|
||||
// List<string> toBeRemoved = new List<string>();
|
||||
// PresenceInfo[] presence = PresenceService.GetAgents(localFriends.ToArray());
|
||||
// foreach (PresenceInfo pi in presence)
|
||||
// {
|
||||
// UUID presenceID;
|
||||
// if (UUID.TryParse(pi.UserID, out presenceID))
|
||||
// {
|
||||
// online.Add(presenceID);
|
||||
// foreach (string s in foreignFriends)
|
||||
// if (s.StartsWith(pi.UserID))
|
||||
// toBeRemoved.Add(s);
|
||||
// }
|
||||
// }
|
||||
|
||||
// foreach (string s in toBeRemoved)
|
||||
// foreignFriends.Remove(s);
|
||||
|
||||
// // OK, let's send this up the stack, and leave a closure here
|
||||
// // collecting online friends in other grids
|
||||
// Util.FireAndForget(delegate { CollectOnlineFriendsElsewhere(userID, foreignFriends); });
|
||||
|
||||
//}
|
||||
|
||||
//private void CollectOnlineFriendsElsewhere(UUID userID, List<string> foreignFriends)
|
||||
//{
|
||||
// // let's divide the friends on a per-domain basis
|
||||
// Dictionary<string, List<string>> friendsPerDomain = new Dictionary<string, List<string>>();
|
||||
// foreach (string friend in foreignFriends)
|
||||
// {
|
||||
// UUID friendID;
|
||||
// if (!UUID.TryParse(friend, out friendID))
|
||||
// {
|
||||
// // it's a foreign friend
|
||||
// string url = string.Empty, tmp = string.Empty;
|
||||
// if (Util.ParseUniversalUserIdentifier(friend, out friendID, out url, out tmp, out tmp, out tmp))
|
||||
// {
|
||||
// if (!friendsPerDomain.ContainsKey(url))
|
||||
// friendsPerDomain[url] = new List<string>();
|
||||
// friendsPerDomain[url].Add(friend);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// // Now, call those worlds
|
||||
|
||||
// foreach (KeyValuePair<string, List<string>> kvp in friendsPerDomain)
|
||||
// {
|
||||
// List<string> ids = new List<string>();
|
||||
// foreach (string f in kvp.Value)
|
||||
// ids.Add(f);
|
||||
// UserAgentServiceConnector uConn = new UserAgentServiceConnector(kvp.Key);
|
||||
// List<UUID> online = uConn.GetOnlineFriends(userID, ids);
|
||||
// // Finally send the notifications to the user
|
||||
// // this whole process may take a while, so let's check at every
|
||||
// // iteration that the user is still here
|
||||
// IClientAPI client = LocateClientObject(userID);
|
||||
// if (client != null)
|
||||
// client.SendAgentOnline(online.ToArray());
|
||||
// else
|
||||
// break;
|
||||
// }
|
||||
|
||||
//}
|
||||
|
||||
protected override void StatusNotify(List<FriendInfo> friendList, UUID userID, bool online)
|
||||
{
|
||||
// First, let's divide the friends on a per-domain basis
|
||||
Dictionary<string, List<FriendInfo>> friendsPerDomain = new Dictionary<string, List<FriendInfo>>();
|
||||
foreach (FriendInfo friend in friendList)
|
||||
{
|
||||
UUID friendID;
|
||||
if (UUID.TryParse(friend.Friend, out friendID))
|
||||
{
|
||||
if (!friendsPerDomain.ContainsKey("local"))
|
||||
friendsPerDomain["local"] = new List<FriendInfo>();
|
||||
friendsPerDomain["local"].Add(friend);
|
||||
}
|
||||
else
|
||||
{
|
||||
// it's a foreign friend
|
||||
string url = string.Empty, tmp = string.Empty;
|
||||
if (Util.ParseUniversalUserIdentifier(friend.Friend, out friendID, out url, out tmp, out tmp, out tmp))
|
||||
{
|
||||
// Let's try our luck in the local sim. Who knows, maybe it's here
|
||||
if (LocalStatusNotification(userID, friendID, online))
|
||||
continue;
|
||||
|
||||
if (!friendsPerDomain.ContainsKey(url))
|
||||
friendsPerDomain[url] = new List<FriendInfo>();
|
||||
friendsPerDomain[url].Add(friend);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// For the local friends, just call the base method
|
||||
// Let's do this first of all
|
||||
if (friendsPerDomain.ContainsKey("local"))
|
||||
base.StatusNotify(friendsPerDomain["local"], userID, online);
|
||||
|
||||
foreach (KeyValuePair<string, List<FriendInfo>> kvp in friendsPerDomain)
|
||||
{
|
||||
if (kvp.Key != "local")
|
||||
{
|
||||
// For the others, call the user agent service
|
||||
List<string> ids = new List<string>();
|
||||
foreach (FriendInfo f in kvp.Value)
|
||||
ids.Add(f.Friend);
|
||||
UserAgentServiceConnector uConn = new UserAgentServiceConnector(kvp.Key);
|
||||
List<UUID> friendsOnline = uConn.StatusNotification(ids, userID, online);
|
||||
|
||||
if (online && friendsOnline.Count > 0)
|
||||
{
|
||||
IClientAPI client = LocateClientObject(userID);
|
||||
if (client != null)
|
||||
client.SendAgentOnline(friendsOnline.ToArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool GetAgentInfo(UUID scopeID, string fid, out UUID agentID, out string first, out string last)
|
||||
{
|
||||
first = "Unknown"; last = "User";
|
||||
if (base.GetAgentInfo(scopeID, fid, out agentID, out first, out last))
|
||||
return true;
|
||||
|
||||
// fid is not a UUID...
|
||||
string url = string.Empty, tmp = string.Empty;
|
||||
if (Util.ParseUniversalUserIdentifier(fid, out agentID, out url, out first, out last, out tmp))
|
||||
{
|
||||
IUserManagement userMan = m_Scenes[0].RequestModuleInterface<IUserManagement>();
|
||||
userMan.AddUser(agentID, first, last, url);
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected override string GetFriendshipRequesterName(UUID agentID)
|
||||
{
|
||||
// For the time being we assume that HG friendship requests can only happen
|
||||
// when avies are on the same region.
|
||||
IClientAPI client = LocateClientObject(agentID);
|
||||
if (client != null)
|
||||
return client.FirstName + " " + client.LastName;
|
||||
else
|
||||
return base.GetFriendshipRequesterName(agentID);
|
||||
}
|
||||
|
||||
protected override string FriendshipMessage(string friendID)
|
||||
{
|
||||
UUID id;
|
||||
if (UUID.TryParse(friendID, out id))
|
||||
return base.FriendshipMessage(friendID);
|
||||
|
||||
return "Please confirm this friendship you made while you were away.";
|
||||
}
|
||||
|
||||
protected override FriendInfo GetFriend(FriendInfo[] friends, UUID friendID)
|
||||
{
|
||||
foreach (FriendInfo fi in friends)
|
||||
{
|
||||
if (fi.Friend.StartsWith(friendID.ToString()))
|
||||
return fi;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
protected override FriendInfo[] GetFriendsFromService(IClientAPI client)
|
||||
{
|
||||
UserAccount account1 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, client.AgentId);
|
||||
if (account1 != null)
|
||||
return base.GetFriendsFromService(client);
|
||||
|
||||
FriendInfo[] finfos = new FriendInfo[0];
|
||||
// Foreigner
|
||||
AgentCircuitData agentClientCircuit = ((Scene)(client.Scene)).AuthenticateHandler.GetAgentCircuitData(client.CircuitCode);
|
||||
if (agentClientCircuit != null)
|
||||
{
|
||||
string agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit);
|
||||
|
||||
finfos = FriendsService.GetFriends(agentUUI);
|
||||
m_log.DebugFormat("[HGFRIENDS MODULE]: Fetched {0} local friends for visitor {1}", finfos.Length, agentUUI);
|
||||
}
|
||||
return finfos;
|
||||
}
|
||||
|
||||
protected override bool StoreRights(UUID agentID, UUID friendID, int rights)
|
||||
{
|
||||
UserAccount account1 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, agentID);
|
||||
UserAccount account2 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, friendID);
|
||||
// Are they both local users?
|
||||
if (account1 != null && account2 != null)
|
||||
{
|
||||
// local grid users
|
||||
return base.StoreRights(agentID, friendID, rights);
|
||||
}
|
||||
|
||||
if (account1 != null) // agent is local, friend is foreigner
|
||||
{
|
||||
FriendInfo[] finfos = GetFriends(agentID);
|
||||
FriendInfo finfo = GetFriend(finfos, friendID);
|
||||
if (finfo != null)
|
||||
{
|
||||
FriendsService.StoreFriend(agentID.ToString(), finfo.Friend, rights);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (account2 != null) // agent is foreigner, friend is local
|
||||
{
|
||||
string agentUUI = GetUUI(friendID, agentID);
|
||||
if (agentUUI != string.Empty)
|
||||
{
|
||||
FriendsService.StoreFriend(agentUUI, friendID.ToString(), rights);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
protected override void StoreBackwards(UUID friendID, UUID agentID)
|
||||
{
|
||||
UserAccount account1 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, agentID);
|
||||
UserAccount account2 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, friendID);
|
||||
// Are they both local users?
|
||||
if (account1 != null && account2 != null)
|
||||
{
|
||||
// local grid users
|
||||
m_log.DebugFormat("[HGFRIENDS MODULE]: Users are both local");
|
||||
base.StoreBackwards(friendID, agentID);
|
||||
return;
|
||||
}
|
||||
|
||||
// no provision for this temporary friendship state
|
||||
//FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), 0);
|
||||
}
|
||||
|
||||
protected override void StoreFriendships(UUID agentID, UUID friendID)
|
||||
{
|
||||
UserAccount agentAccount = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, agentID);
|
||||
UserAccount friendAccount = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, friendID);
|
||||
// Are they both local users?
|
||||
if (agentAccount != null && friendAccount != null)
|
||||
{
|
||||
// local grid users
|
||||
m_log.DebugFormat("[HGFRIENDS MODULE]: Users are both local");
|
||||
base.StoreFriendships(agentID, friendID);
|
||||
return;
|
||||
}
|
||||
|
||||
// ok, at least one of them is foreigner, let's get their data
|
||||
IClientAPI agentClient = LocateClientObject(agentID);
|
||||
IClientAPI friendClient = LocateClientObject(friendID);
|
||||
AgentCircuitData agentClientCircuit = null;
|
||||
AgentCircuitData friendClientCircuit = null;
|
||||
string agentUUI = string.Empty;
|
||||
string friendUUI = string.Empty;
|
||||
string agentFriendService = string.Empty;
|
||||
string friendFriendService = string.Empty;
|
||||
|
||||
if (agentClient != null)
|
||||
{
|
||||
agentClientCircuit = ((Scene)(agentClient.Scene)).AuthenticateHandler.GetAgentCircuitData(agentClient.CircuitCode);
|
||||
agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit);
|
||||
agentFriendService = agentClientCircuit.ServiceURLs["FriendsServerURI"].ToString();
|
||||
}
|
||||
if (friendClient != null)
|
||||
{
|
||||
friendClientCircuit = ((Scene)(friendClient.Scene)).AuthenticateHandler.GetAgentCircuitData(friendClient.CircuitCode);
|
||||
friendUUI = Util.ProduceUserUniversalIdentifier(friendClientCircuit);
|
||||
friendFriendService = friendClientCircuit.ServiceURLs["FriendsServerURI"].ToString();
|
||||
}
|
||||
|
||||
m_log.DebugFormat("[HGFRIENDS MODULE] HG Friendship! thisUUI={0}; friendUUI={1}; foreignThisFriendService={2}; foreignFriendFriendService={3}",
|
||||
agentUUI, friendUUI, agentFriendService, friendFriendService);
|
||||
|
||||
// Generate a random 8-character hex number that will sign this friendship
|
||||
string secret = UUID.Random().ToString().Substring(0, 8);
|
||||
|
||||
if (agentAccount != null) // agent is local, 'friend' is foreigner
|
||||
{
|
||||
// This may happen when the agent returned home, in which case the friend is not there
|
||||
// We need to look for its information in the friends list itself
|
||||
bool confirming = false;
|
||||
if (friendUUI == string.Empty)
|
||||
{
|
||||
FriendInfo[] finfos = GetFriends(agentID);
|
||||
foreach (FriendInfo finfo in finfos)
|
||||
{
|
||||
if (finfo.TheirFlags == -1)
|
||||
{
|
||||
if (finfo.Friend.StartsWith(friendID.ToString()))
|
||||
{
|
||||
friendUUI = finfo.Friend;
|
||||
confirming = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If it's confirming the friendship, we already have the full friendUUI with the secret
|
||||
string theFriendUUID = confirming ? friendUUI : friendUUI + ";" + secret;
|
||||
|
||||
// store in the local friends service a reference to the foreign friend
|
||||
FriendsService.StoreFriend(agentID.ToString(), theFriendUUID, 1);
|
||||
// and also the converse
|
||||
FriendsService.StoreFriend(theFriendUUID, agentID.ToString(), 1);
|
||||
|
||||
if (!confirming && friendClientCircuit != null)
|
||||
{
|
||||
// store in the foreign friends service a reference to the local agent
|
||||
HGFriendsServicesConnector friendsConn = new HGFriendsServicesConnector(friendFriendService, friendClientCircuit.SessionID, friendClientCircuit.ServiceSessionID);
|
||||
friendsConn.NewFriendship(friendID, agentUUI + ";" + secret);
|
||||
}
|
||||
}
|
||||
else if (friendAccount != null) // 'friend' is local, agent is foreigner
|
||||
{
|
||||
// store in the local friends service a reference to the foreign agent
|
||||
FriendsService.StoreFriend(friendID.ToString(), agentUUI + ";" + secret, 1);
|
||||
// and also the converse
|
||||
FriendsService.StoreFriend(agentUUI + ";" + secret, friendID.ToString(), 1);
|
||||
|
||||
if (agentClientCircuit != null)
|
||||
{
|
||||
// store in the foreign friends service a reference to the local agent
|
||||
HGFriendsServicesConnector friendsConn = new HGFriendsServicesConnector(agentFriendService, agentClientCircuit.SessionID, agentClientCircuit.ServiceSessionID);
|
||||
friendsConn.NewFriendship(agentID, friendUUI + ";" + secret);
|
||||
}
|
||||
}
|
||||
else // They're both foreigners!
|
||||
{
|
||||
HGFriendsServicesConnector friendsConn;
|
||||
if (agentClientCircuit != null)
|
||||
{
|
||||
friendsConn = new HGFriendsServicesConnector(agentFriendService, agentClientCircuit.SessionID, agentClientCircuit.ServiceSessionID);
|
||||
friendsConn.NewFriendship(agentID, friendUUI + ";" + secret);
|
||||
}
|
||||
if (friendClientCircuit != null)
|
||||
{
|
||||
friendsConn = new HGFriendsServicesConnector(friendFriendService, friendClientCircuit.SessionID, friendClientCircuit.ServiceSessionID);
|
||||
friendsConn.NewFriendship(friendID, agentUUI + ";" + secret);
|
||||
}
|
||||
}
|
||||
// my brain hurts now
|
||||
}
|
||||
|
||||
protected override bool DeleteFriendship(UUID agentID, UUID exfriendID)
|
||||
{
|
||||
UserAccount agentAccount = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, agentID);
|
||||
UserAccount friendAccount = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, exfriendID);
|
||||
// Are they both local users?
|
||||
if (agentAccount != null && friendAccount != null)
|
||||
{
|
||||
// local grid users
|
||||
return base.DeleteFriendship(agentID, exfriendID);
|
||||
}
|
||||
|
||||
// ok, at least one of them is foreigner, let's get their data
|
||||
string agentUUI = string.Empty;
|
||||
string friendUUI = string.Empty;
|
||||
|
||||
if (agentAccount != null) // agent is local, 'friend' is foreigner
|
||||
{
|
||||
// We need to look for its information in the friends list itself
|
||||
FriendInfo[] finfos = GetFriends(agentID);
|
||||
FriendInfo finfo = GetFriend(finfos, exfriendID);
|
||||
if (finfo != null)
|
||||
{
|
||||
friendUUI = finfo.Friend;
|
||||
|
||||
// delete in the local friends service the reference to the foreign friend
|
||||
FriendsService.Delete(agentID, friendUUI);
|
||||
// and also the converse
|
||||
FriendsService.Delete(friendUUI, agentID.ToString());
|
||||
|
||||
// notify the exfriend's service
|
||||
Util.FireAndForget(delegate { Delete(exfriendID, agentID, friendUUI); });
|
||||
|
||||
m_log.DebugFormat("[HGFRIENDS MODULE]: {0} terminated {1}", agentID, friendUUI);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (friendAccount != null) // agent is foreigner, 'friend' is local
|
||||
{
|
||||
agentUUI = GetUUI(exfriendID, agentID);
|
||||
|
||||
if (agentUUI != string.Empty)
|
||||
{
|
||||
// delete in the local friends service the reference to the foreign agent
|
||||
FriendsService.Delete(exfriendID, agentUUI);
|
||||
// and also the converse
|
||||
FriendsService.Delete(agentUUI, exfriendID.ToString());
|
||||
|
||||
// notify the agent's service?
|
||||
Util.FireAndForget(delegate { Delete(agentID, exfriendID, agentUUI); });
|
||||
|
||||
m_log.DebugFormat("[HGFRIENDS MODULE]: {0} terminated {1}", agentUUI, exfriendID);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
//else They're both foreigners! Can't handle this
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private string GetUUI(UUID localUser, UUID foreignUser)
|
||||
{
|
||||
// Let's see if the user is here by any chance
|
||||
FriendInfo[] finfos = GetFriends(localUser);
|
||||
if (finfos != EMPTY_FRIENDS) // friend is here, cool
|
||||
{
|
||||
FriendInfo finfo = GetFriend(finfos, foreignUser);
|
||||
if (finfo != null)
|
||||
{
|
||||
return finfo.Friend;
|
||||
}
|
||||
}
|
||||
else // user is not currently on this sim, need to get from the service
|
||||
{
|
||||
finfos = FriendsService.GetFriends(localUser);
|
||||
foreach (FriendInfo finfo in finfos)
|
||||
{
|
||||
if (finfo.Friend.StartsWith(foreignUser.ToString())) // found it!
|
||||
{
|
||||
return finfo.Friend;
|
||||
}
|
||||
}
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
private void Delete(UUID foreignUser, UUID localUser, string uui)
|
||||
{
|
||||
UUID id;
|
||||
string url = string.Empty, secret = string.Empty, tmp = string.Empty;
|
||||
if (Util.ParseUniversalUserIdentifier(uui, out id, out url, out tmp, out tmp, out secret))
|
||||
{
|
||||
m_log.DebugFormat("[HGFRIENDS MODULE]: Deleting friendship from {0}", url);
|
||||
HGFriendsServicesConnector friendConn = new HGFriendsServicesConnector(url);
|
||||
friendConn.DeleteFriendship(foreignUser, localUser, secret);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,350 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Reflection;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
using Nwc.XmlRpc;
|
||||
using Mono.Addins;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using GridRegion = OpenSim.Services.Interfaces.GridRegion;
|
||||
using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using OpenSim.Services.Connectors.InstantMessage;
|
||||
using OpenSim.Services.Connectors.Hypergrid;
|
||||
using OpenSim.Server.Handlers.Hypergrid;
|
||||
|
||||
namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
|
||||
{
|
||||
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
|
||||
public class HGMessageTransferModule : ISharedRegionModule, IMessageTransferModule, IInstantMessageSimConnector
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
protected bool m_Enabled = false;
|
||||
protected List<Scene> m_Scenes = new List<Scene>();
|
||||
|
||||
protected IInstantMessage m_IMService;
|
||||
protected Dictionary<UUID, object> m_UserLocationMap = new Dictionary<UUID, object>();
|
||||
|
||||
public event UndeliveredMessage OnUndeliveredMessage;
|
||||
|
||||
IUserManagement m_uMan;
|
||||
IUserManagement UserManagementModule
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_uMan == null)
|
||||
m_uMan = m_Scenes[0].RequestModuleInterface<IUserManagement>();
|
||||
return m_uMan;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Initialise(IConfigSource config)
|
||||
{
|
||||
IConfig cnf = config.Configs["Messaging"];
|
||||
if (cnf != null && cnf.GetString(
|
||||
"MessageTransferModule", "MessageTransferModule") != Name)
|
||||
{
|
||||
m_log.Debug("[HG MESSAGE TRANSFER]: Disabled by configuration");
|
||||
return;
|
||||
}
|
||||
|
||||
InstantMessageServerConnector imServer = new InstantMessageServerConnector(config, MainServer.Instance, this);
|
||||
m_IMService = imServer.GetService();
|
||||
m_Enabled = true;
|
||||
}
|
||||
|
||||
public virtual void AddRegion(Scene scene)
|
||||
{
|
||||
if (!m_Enabled)
|
||||
return;
|
||||
|
||||
lock (m_Scenes)
|
||||
{
|
||||
m_log.DebugFormat("[HG MESSAGE TRANSFER]: Message transfer module {0} active", Name);
|
||||
scene.RegisterModuleInterface<IMessageTransferModule>(this);
|
||||
m_Scenes.Add(scene);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void PostInitialise()
|
||||
{
|
||||
if (!m_Enabled)
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
public virtual void RegionLoaded(Scene scene)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void RemoveRegion(Scene scene)
|
||||
{
|
||||
if (!m_Enabled)
|
||||
return;
|
||||
|
||||
lock (m_Scenes)
|
||||
{
|
||||
m_Scenes.Remove(scene);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Close()
|
||||
{
|
||||
}
|
||||
|
||||
public virtual string Name
|
||||
{
|
||||
get { return "HGMessageTransferModule"; }
|
||||
}
|
||||
|
||||
public virtual Type ReplaceableInterface
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
public void SendInstantMessage(GridInstantMessage im, MessageResultNotification result)
|
||||
{
|
||||
UUID toAgentID = new UUID(im.toAgentID);
|
||||
|
||||
// Try root avatar only first
|
||||
foreach (Scene scene in m_Scenes)
|
||||
{
|
||||
if (scene.Entities.ContainsKey(toAgentID) &&
|
||||
scene.Entities[toAgentID] is ScenePresence)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[INSTANT MESSAGE]: Looking for root agent {0} in {1}",
|
||||
// toAgentID.ToString(), scene.RegionInfo.RegionName);
|
||||
|
||||
ScenePresence user = (ScenePresence) scene.Entities[toAgentID];
|
||||
if (!user.IsChildAgent)
|
||||
{
|
||||
// Local message
|
||||
// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to root agent {0} {1}", user.Name, toAgentID);
|
||||
user.ControllingClient.SendInstantMessage(im);
|
||||
|
||||
// Message sent
|
||||
result(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// try child avatar second
|
||||
foreach (Scene scene in m_Scenes)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[INSTANT MESSAGE]: Looking for child of {0} in {1}", toAgentID, scene.RegionInfo.RegionName);
|
||||
|
||||
if (scene.Entities.ContainsKey(toAgentID) &&
|
||||
scene.Entities[toAgentID] is ScenePresence)
|
||||
{
|
||||
// Local message
|
||||
ScenePresence user = (ScenePresence) scene.Entities[toAgentID];
|
||||
|
||||
// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to child agent {0} {1}", user.Name, toAgentID);
|
||||
user.ControllingClient.SendInstantMessage(im);
|
||||
|
||||
// Message sent
|
||||
result(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to {0} via XMLRPC", im.toAgentID);
|
||||
// Is the user a local user?
|
||||
UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, toAgentID);
|
||||
string url = string.Empty;
|
||||
bool foreigner = false;
|
||||
if (account == null) // foreign user
|
||||
{
|
||||
url = UserManagementModule.GetUserServerURL(toAgentID, "IMServerURI");
|
||||
foreigner = true;
|
||||
}
|
||||
|
||||
Util.FireAndForget(delegate
|
||||
{
|
||||
bool success = false;
|
||||
if (foreigner && url == string.Empty) // we don't know about this user
|
||||
{
|
||||
string recipientUUI = TryGetRecipientUUI(new UUID(im.fromAgentID), toAgentID);
|
||||
m_log.DebugFormat("[HG MESSAGE TRANSFER]: Got UUI {0}", recipientUUI);
|
||||
if (recipientUUI != string.Empty)
|
||||
{
|
||||
UUID id; string u = string.Empty, first = string.Empty, last = string.Empty, secret = string.Empty;
|
||||
if (Util.ParseUniversalUserIdentifier(recipientUUI, out id, out u, out first, out last, out secret))
|
||||
{
|
||||
success = m_IMService.OutgoingInstantMessage(im, u, true);
|
||||
if (success)
|
||||
UserManagementModule.AddUser(toAgentID, u + ";" + first + " " + last);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
success = m_IMService.OutgoingInstantMessage(im, url, foreigner);
|
||||
|
||||
if (!success && !foreigner)
|
||||
HandleUndeliveredMessage(im, result);
|
||||
else
|
||||
result(success);
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
protected bool SendIMToScene(GridInstantMessage gim, UUID toAgentID)
|
||||
{
|
||||
bool successful = false;
|
||||
foreach (Scene scene in m_Scenes)
|
||||
{
|
||||
if (scene.Entities.ContainsKey(toAgentID) &&
|
||||
scene.Entities[toAgentID] is ScenePresence)
|
||||
{
|
||||
ScenePresence user =
|
||||
(ScenePresence)scene.Entities[toAgentID];
|
||||
|
||||
if (!user.IsChildAgent)
|
||||
{
|
||||
scene.EventManager.TriggerIncomingInstantMessage(gim);
|
||||
successful = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!successful)
|
||||
{
|
||||
// If the message can't be delivered to an agent, it
|
||||
// is likely to be a group IM. On a group IM, the
|
||||
// imSessionID = toAgentID = group id. Raise the
|
||||
// unhandled IM event to give the groups module
|
||||
// a chance to pick it up. We raise that in a random
|
||||
// scene, since the groups module is shared.
|
||||
//
|
||||
m_Scenes[0].EventManager.TriggerUnhandledInstantMessage(gim);
|
||||
}
|
||||
|
||||
return successful;
|
||||
}
|
||||
|
||||
protected void HandleUndeliveredMessage(GridInstantMessage im, MessageResultNotification result)
|
||||
{
|
||||
UndeliveredMessage handlerUndeliveredMessage = OnUndeliveredMessage;
|
||||
|
||||
// If this event has handlers, then an IM from an agent will be
|
||||
// considered delivered. This will suppress the error message.
|
||||
//
|
||||
if (handlerUndeliveredMessage != null)
|
||||
{
|
||||
handlerUndeliveredMessage(im);
|
||||
if (im.dialog == (byte)InstantMessageDialog.MessageFromAgent)
|
||||
result(true);
|
||||
else
|
||||
result(false);
|
||||
return;
|
||||
}
|
||||
|
||||
//m_log.DebugFormat("[INSTANT MESSAGE]: Undeliverable");
|
||||
result(false);
|
||||
}
|
||||
|
||||
private string TryGetRecipientUUI(UUID fromAgent, UUID toAgent)
|
||||
{
|
||||
// Let's call back the fromAgent's user agent service
|
||||
// Maybe that service knows about the toAgent
|
||||
IClientAPI client = LocateClientObject(fromAgent);
|
||||
if (client != null)
|
||||
{
|
||||
AgentCircuitData circuit = m_Scenes[0].AuthenticateHandler.GetAgentCircuitData(client.AgentId);
|
||||
if (circuit != null)
|
||||
{
|
||||
if (circuit.ServiceURLs.ContainsKey("HomeURI"))
|
||||
{
|
||||
string uasURL = circuit.ServiceURLs["HomeURI"].ToString();
|
||||
m_log.DebugFormat("[HG MESSAGE TRANSFER]: getting UUI of user {0} from {1}", toAgent, uasURL);
|
||||
UserAgentServiceConnector uasConn = new UserAgentServiceConnector(uasURL);
|
||||
return uasConn.GetUUI(fromAgent, toAgent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Find the scene for an agent
|
||||
/// </summary>
|
||||
private Scene GetClientScene(UUID agentId)
|
||||
{
|
||||
lock (m_Scenes)
|
||||
{
|
||||
foreach (Scene scene in m_Scenes)
|
||||
{
|
||||
ScenePresence presence = scene.GetScenePresence(agentId);
|
||||
if (presence != null && !presence.IsChildAgent)
|
||||
return scene;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Find the client for a ID
|
||||
/// </summary>
|
||||
public IClientAPI LocateClientObject(UUID agentID)
|
||||
{
|
||||
Scene scene = GetClientScene(agentID);
|
||||
if (scene != null)
|
||||
{
|
||||
ScenePresence presence = scene.GetScenePresence(agentID);
|
||||
if (presence != null)
|
||||
return presence.ControllingClient;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
#region IInstantMessageSimConnector
|
||||
public bool SendInstantMessage(GridInstantMessage im)
|
||||
{
|
||||
//m_log.DebugFormat("[XXX] Hook SendInstantMessage {0}", im.message);
|
||||
UUID agentID = new UUID(im.toAgentID);
|
||||
return SendIMToScene(im, agentID);
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -172,69 +172,62 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
|
||||
private void RetrieveInstantMessages(IClientAPI client)
|
||||
{
|
||||
if (m_RestURL == String.Empty)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.DebugFormat("[OFFLINE MESSAGING]: Retrieving stored messages for {0}", client.AgentId);
|
||||
|
||||
m_log.DebugFormat("[OFFLINE MESSAGING] Retrieving stored messages for {0}", client.AgentId);
|
||||
|
||||
List<GridInstantMessage> msglist = SynchronousRestObjectPoster.BeginPostObject<UUID, List<GridInstantMessage>>(
|
||||
List<GridInstantMessage> msglist
|
||||
= SynchronousRestObjectRequester.MakeRequest<UUID, List<GridInstantMessage>>(
|
||||
"POST", m_RestURL + "/RetrieveMessages/", client.AgentId);
|
||||
|
||||
if (msglist != null)
|
||||
{
|
||||
foreach (GridInstantMessage im in msglist)
|
||||
if (msglist != null)
|
||||
{
|
||||
// client.SendInstantMessage(im);
|
||||
foreach (GridInstantMessage im in msglist)
|
||||
{
|
||||
// client.SendInstantMessage(im);
|
||||
|
||||
// Send through scene event manager so all modules get a chance
|
||||
// to look at this message before it gets delivered.
|
||||
//
|
||||
// Needed for proper state management for stored group
|
||||
// invitations
|
||||
//
|
||||
// Send through scene event manager so all modules get a chance
|
||||
// to look at this message before it gets delivered.
|
||||
//
|
||||
// Needed for proper state management for stored group
|
||||
// invitations
|
||||
//
|
||||
|
||||
im.offline = 1;
|
||||
im.offline = 1;
|
||||
|
||||
Scene s = FindScene(client.AgentId);
|
||||
if (s != null)
|
||||
s.EventManager.TriggerIncomingInstantMessage(im);
|
||||
Scene s = FindScene(client.AgentId);
|
||||
if (s != null)
|
||||
s.EventManager.TriggerIncomingInstantMessage(im);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void UndeliveredMessage(GridInstantMessage im)
|
||||
{
|
||||
if (im.dialog != (byte)InstantMessageDialog.MessageFromObject &&
|
||||
im.dialog != (byte)InstantMessageDialog.MessageFromAgent &&
|
||||
im.dialog != (byte)InstantMessageDialog.GroupNotice &&
|
||||
im.dialog != (byte)InstantMessageDialog.GroupInvitation &&
|
||||
im.dialog != (byte)InstantMessageDialog.InventoryOffered)
|
||||
if ((im.offline != 0)
|
||||
&& (!im.fromGroup || (im.fromGroup && m_ForwardOfflineGroupMessages)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
bool success = SynchronousRestObjectRequester.MakeRequest<GridInstantMessage, bool>(
|
||||
"POST", m_RestURL + "/SaveMessage/", im);
|
||||
|
||||
// It's not delivered. Make sure the scope id is saved
|
||||
// We don't need the imSessionID here anymore, overwrite it
|
||||
Scene scene = FindScene(new UUID(im.fromAgentID));
|
||||
if (scene == null)
|
||||
scene = m_SceneList[0];
|
||||
if (im.dialog == (byte)InstantMessageDialog.MessageFromAgent)
|
||||
{
|
||||
IClientAPI client = FindClient(new UUID(im.fromAgentID));
|
||||
if (client == null)
|
||||
return;
|
||||
|
||||
bool success = SynchronousRestObjectPoster.BeginPostObject<GridInstantMessage, bool>(
|
||||
"POST", m_RestURL+"/SaveMessage/?scope=" +
|
||||
scene.RegionInfo.ScopeID.ToString(), im);
|
||||
|
||||
if (im.dialog == (byte)InstantMessageDialog.MessageFromAgent)
|
||||
{
|
||||
IClientAPI client = FindClient(new UUID(im.fromAgentID));
|
||||
if (client == null)
|
||||
return;
|
||||
|
||||
client.SendInstantMessage(new GridInstantMessage(
|
||||
null, new UUID(im.toAgentID),
|
||||
"System", new UUID(im.fromAgentID),
|
||||
(byte)InstantMessageDialog.MessageFromAgent,
|
||||
"User is not logged in. "+
|
||||
(success ? "Message saved." : "Message not saved"),
|
||||
false, new Vector3()));
|
||||
client.SendInstantMessage(new GridInstantMessage(
|
||||
null, new UUID(im.toAgentID),
|
||||
"System", new UUID(im.fromAgentID),
|
||||
(byte)InstantMessageDialog.MessageFromAgent,
|
||||
"User is not logged in. " +
|
||||
(success ? "Message saved." : "Message not saved"),
|
||||
false, new Vector3()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,14 +149,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
|
||||
/// <summary>
|
||||
/// Find an item given a PATH_DELIMITOR delimited path starting from the user's root folder.
|
||||
///
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method does not handle paths that contain multiple delimitors
|
||||
///
|
||||
/// FIXME: We do not yet handle situations where folders or items have the same name. We could handle this by some
|
||||
/// XPath like expression
|
||||
///
|
||||
/// FIXME: Delimitors which occur in names themselves are not currently escapable.
|
||||
/// </summary>
|
||||
/// </remarks>
|
||||
///
|
||||
/// <param name="inventoryService">
|
||||
/// Inventory service to query
|
||||
@@ -178,32 +179,66 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
|
||||
return FindItemByPath(inventoryService, rootFolder, path);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Find an item given a PATH_DELIMITOR delimited path starting from this folder.
|
||||
///
|
||||
/// This method does not handle paths that contain multiple delimitors
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method does not handle paths that contain multiple delimiters
|
||||
///
|
||||
/// FIXME: We do not yet handle situations where folders or items have the same name. We could handle this by some
|
||||
/// XPath like expression
|
||||
///
|
||||
/// FIXME: Delimitors which occur in names themselves are not currently escapable.
|
||||
/// </summary>
|
||||
///
|
||||
/// <param name="inventoryService">
|
||||
/// Inventory service to query
|
||||
/// </param>
|
||||
/// <param name="startFolder">
|
||||
/// The folder from which the path starts
|
||||
/// </param>
|
||||
/// <param name="path">
|
||||
/// <param name="path">
|
||||
/// The path to the required item.
|
||||
/// </param>
|
||||
/// </remarks>
|
||||
///
|
||||
/// <param name="inventoryService">Inventory service to query</param>
|
||||
/// <param name="startFolder">The folder from which the path starts</param>
|
||||
/// <param name="path">The path to the required item.</param>
|
||||
/// <returns>null if the item is not found</returns>
|
||||
public static InventoryItemBase FindItemByPath(
|
||||
IInventoryService inventoryService, InventoryFolderBase startFolder, string path)
|
||||
{
|
||||
List<InventoryItemBase> foundItems = FindItemsByPath(inventoryService, startFolder, path);
|
||||
|
||||
if (foundItems.Count != 0)
|
||||
return foundItems[0];
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
public static List<InventoryItemBase> FindItemsByPath(
|
||||
IInventoryService inventoryService, UUID userId, string path)
|
||||
{
|
||||
InventoryFolderBase rootFolder = inventoryService.GetRootFolder(userId);
|
||||
|
||||
if (null == rootFolder)
|
||||
return new List<InventoryItemBase>();
|
||||
|
||||
return FindItemsByPath(inventoryService, rootFolder, path);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Find items that match a given PATH_DELIMITOR delimited path starting from this folder.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method does not handle paths that contain multiple delimiters
|
||||
///
|
||||
/// FIXME: We do not yet handle situations where folders or items have the same name. We could handle this by some
|
||||
/// XPath like expression
|
||||
///
|
||||
/// FIXME: Delimitors which occur in names themselves are not currently escapable.
|
||||
/// </remarks>
|
||||
///
|
||||
/// <param name="inventoryService">Inventory service to query</param>
|
||||
/// <param name="startFolder">The folder from which the path starts</param>
|
||||
/// <param name="path">The path to the required item.</param>
|
||||
/// <returns>The items that were found with this path. An empty list if no items were found.</returns>
|
||||
public static List<InventoryItemBase> FindItemsByPath(
|
||||
IInventoryService inventoryService, InventoryFolderBase startFolder, string path)
|
||||
{
|
||||
List<InventoryItemBase> foundItems = new List<InventoryItemBase>();
|
||||
|
||||
// If the path isn't just / then trim any starting extraneous slashes
|
||||
path = path.TrimStart(new char[] { PATH_DELIMITER });
|
||||
|
||||
@@ -215,11 +250,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
if (components.Length == 1)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "FOUND SINGLE COMPONENT [{0}]. Looking for this in [{1}] {2}",
|
||||
// "FOUND SINGLE COMPONENT [{0}]. Looking for this in [{1}] {2}",
|
||||
// components[0], startFolder.Name, startFolder.ID);
|
||||
|
||||
List<InventoryItemBase> items = inventoryService.GetFolderItems(startFolder.Owner, startFolder.ID);
|
||||
|
||||
|
||||
// m_log.DebugFormat("[INVENTORY ARCHIVE UTILS]: Found {0} items in FindItemByPath()", items.Count);
|
||||
|
||||
foreach (InventoryItemBase item in items)
|
||||
@@ -227,24 +262,23 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
// m_log.DebugFormat("[INVENTORY ARCHIVE UTILS]: Inspecting item {0} {1}", item.Name, item.ID);
|
||||
|
||||
if (item.Name == components[0])
|
||||
return item;
|
||||
foundItems.Add(item);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// m_log.DebugFormat("FOUND COMPONENTS [{0}] and [{1}]", components[0], components[1]);
|
||||
|
||||
|
||||
InventoryCollection contents = inventoryService.GetFolderContent(startFolder.Owner, startFolder.ID);
|
||||
|
||||
foreach (InventoryFolderBase folder in contents.Folders)
|
||||
{
|
||||
if (folder.Name == components[0])
|
||||
return FindItemByPath(inventoryService, folder, components[1]);
|
||||
foundItems.AddRange(FindItemsByPath(inventoryService, folder, components[1]));
|
||||
}
|
||||
}
|
||||
|
||||
// We didn't find an item or intermediate folder with the given name
|
||||
return null;
|
||||
return foundItems;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -46,6 +46,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
/// <summary>
|
||||
/// Determine whether this archive will save assets. Default is true.
|
||||
/// </summary>
|
||||
public bool SaveAssets { get; set; }
|
||||
|
||||
/// <value>
|
||||
/// Used to select all inventory nodes in a folder but not the folder itself
|
||||
/// </value>
|
||||
@@ -112,6 +117,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
m_invPath = invPath;
|
||||
m_saveStream = saveStream;
|
||||
m_assetGatherer = new UuidGatherer(m_scene.AssetService);
|
||||
|
||||
SaveAssets = true;
|
||||
}
|
||||
|
||||
protected void ReceivedAllAssets(ICollection<UUID> assetsFoundUuids, ICollection<UUID> assetsNotFoundUuids)
|
||||
@@ -139,6 +146,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
|
||||
protected void SaveInvItem(InventoryItemBase inventoryItem, string path, Dictionary<string, object> options, IUserAccountService userAccountService)
|
||||
{
|
||||
if (options.ContainsKey("verbose"))
|
||||
m_log.InfoFormat(
|
||||
"[INVENTORY ARCHIVER]: Saving item {0} {1} with asset {2}",
|
||||
inventoryItem.ID, inventoryItem.Name, inventoryItem.AssetID);
|
||||
|
||||
string filename = path + CreateArchiveItemName(inventoryItem);
|
||||
|
||||
// Record the creator of this item for user record purposes (which might go away soon)
|
||||
@@ -147,7 +159,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
string serialization = UserInventoryItemSerializer.Serialize(inventoryItem, options, userAccountService);
|
||||
m_archiveWriter.WriteFile(filename, serialization);
|
||||
|
||||
m_assetGatherer.GatherAssetUuids(inventoryItem.AssetID, (AssetType)inventoryItem.AssetType, m_assetUuids);
|
||||
AssetType itemAssetType = (AssetType)inventoryItem.AssetType;
|
||||
|
||||
// Don't chase down link asset items as they actually point to their target item IDs rather than an asset
|
||||
if (SaveAssets && itemAssetType != AssetType.Link && itemAssetType != AssetType.LinkFolder)
|
||||
m_assetGatherer.GatherAssetUuids(inventoryItem.AssetID, (AssetType)inventoryItem.AssetType, m_assetUuids);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -189,6 +205,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
/// </summary>
|
||||
public void Execute(Dictionary<string, object> options, IUserAccountService userAccountService)
|
||||
{
|
||||
if (options.ContainsKey("noassets") && (bool)options["noassets"])
|
||||
SaveAssets = false;
|
||||
|
||||
try
|
||||
{
|
||||
InventoryFolderBase inventoryFolder = null;
|
||||
@@ -235,10 +254,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
|
||||
// The path may point to an item instead
|
||||
if (inventoryFolder == null)
|
||||
{
|
||||
inventoryItem = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, rootFolder, m_invPath);
|
||||
//inventoryItem = m_userInfo.RootFolder.FindItemByPath(m_invPath);
|
||||
}
|
||||
|
||||
if (null == inventoryFolder && null == inventoryItem)
|
||||
{
|
||||
@@ -279,12 +295,23 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
|
||||
// Don't put all this profile information into the archive right now.
|
||||
//SaveUsers();
|
||||
|
||||
new AssetsRequest(
|
||||
new AssetsArchiver(m_archiveWriter),
|
||||
m_assetUuids, m_scene.AssetService,
|
||||
m_scene.UserAccountService, m_scene.RegionInfo.ScopeID,
|
||||
options, ReceivedAllAssets).Execute();
|
||||
|
||||
if (SaveAssets)
|
||||
{
|
||||
m_log.DebugFormat("[INVENTORY ARCHIVER]: Saving {0} assets for items", m_assetUuids.Count);
|
||||
|
||||
new AssetsRequest(
|
||||
new AssetsArchiver(m_archiveWriter),
|
||||
m_assetUuids, m_scene.AssetService,
|
||||
m_scene.UserAccountService, m_scene.RegionInfo.ScopeID,
|
||||
options, ReceivedAllAssets).Execute();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.DebugFormat("[INVENTORY ARCHIVER]: Not saving assets since --noassets was specified");
|
||||
|
||||
ReceivedAllAssets(new List<UUID>(), new List<UUID>());
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
@@ -381,19 +408,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
/// </summary>
|
||||
/// <param name="options"></param>
|
||||
/// <returns></returns>
|
||||
public static string CreateControlFile(Dictionary<string, object> options)
|
||||
public string CreateControlFile(Dictionary<string, object> options)
|
||||
{
|
||||
int majorVersion, minorVersion;
|
||||
|
||||
if (options.ContainsKey("profile"))
|
||||
{
|
||||
majorVersion = 1;
|
||||
minorVersion = 1;
|
||||
minorVersion = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
majorVersion = 0;
|
||||
minorVersion = 2;
|
||||
minorVersion = 3;
|
||||
}
|
||||
|
||||
m_log.InfoFormat("[INVENTORY ARCHIVER]: Creating version {0}.{1} IAR", majorVersion, minorVersion);
|
||||
@@ -405,6 +432,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
xtw.WriteStartElement("archive");
|
||||
xtw.WriteAttributeString("major_version", majorVersion.ToString());
|
||||
xtw.WriteAttributeString("minor_version", minorVersion.ToString());
|
||||
|
||||
xtw.WriteElementString("assets_included", SaveAssets.ToString());
|
||||
|
||||
xtw.WriteEndElement();
|
||||
|
||||
xtw.Flush();
|
||||
@@ -416,4 +446,4 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
return s;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,7 +122,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
|
||||
scene.AddCommand(
|
||||
this, "save iar",
|
||||
"save iar [--p|-profile=<url>] <first> <last> <inventory path> <password> [<IAR path>]",
|
||||
"save iar [--p|-profile=<url>] [--noassets] <first> <last> <inventory path> <password> [<IAR path>] [--v|-verbose]",
|
||||
"Save user inventory archive (IAR).",
|
||||
"<first> is the user's first name." + Environment.NewLine
|
||||
+ "<last> is the user's last name." + Environment.NewLine
|
||||
@@ -130,6 +130,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
+ "-p|--profile=<url> adds the url of the profile service to the saved user information." + Environment.NewLine
|
||||
+ "-c|--creators preserves information about foreign creators." + Environment.NewLine
|
||||
+ "-v|--verbose extra debug messages." + Environment.NewLine
|
||||
+ "--noassets stops assets being saved to the IAR."
|
||||
+ "<IAR path> is the filesystem path at which to save the IAR."
|
||||
+ string.Format(" If this is not given then the filename {0} in the current directory is used", DEFAULT_INV_BACKUP_FILENAME),
|
||||
HandleSaveInvConsoleCommand);
|
||||
@@ -398,6 +399,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
ops.Add("p|profile=", delegate(string v) { options["profile"] = v; });
|
||||
ops.Add("v|verbose", delegate(string v) { options["verbose"] = v; });
|
||||
ops.Add("c|creators", delegate(string v) { options["creators"] = v; });
|
||||
ops.Add("noassets", delegate(string v) { options["noassets"] = v != null; });
|
||||
|
||||
List<string> mainParams = ops.Parse(cmdparams);
|
||||
|
||||
@@ -406,7 +408,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
if (mainParams.Count < 6)
|
||||
{
|
||||
m_log.Error(
|
||||
"[INVENTORY ARCHIVER]: usage is save iar [--p|-profile=<url>] <first name> <last name> <inventory path> <user password> [<save file path>]");
|
||||
"[INVENTORY ARCHIVER]: usage is save iar [--p|-profile=<url>] [--noassets] <first name> <last name> <inventory path> <user password> [<save file path>]");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -423,16 +425,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
m_log.InfoFormat(
|
||||
"[INVENTORY ARCHIVER]: Saving archive {0} using inventory path {1} for {2} {3}",
|
||||
savePath, invPath, firstName, lastName);
|
||||
|
||||
|
||||
lock (m_pendingConsoleSaves)
|
||||
m_pendingConsoleSaves.Add(id);
|
||||
|
||||
ArchiveInventory(id, firstName, lastName, invPath, pass, savePath, options);
|
||||
}
|
||||
catch (InventoryArchiverException e)
|
||||
{
|
||||
m_log.ErrorFormat("[INVENTORY ARCHIVER]: {0}", e.Message);
|
||||
}
|
||||
|
||||
lock (m_pendingConsoleSaves)
|
||||
m_pendingConsoleSaves.Add(id);
|
||||
}
|
||||
|
||||
private void SaveInvConsoleCommandCompleted(
|
||||
|
||||
@@ -100,8 +100,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
InventoryArchiverModule archiverModule = new InventoryArchiverModule();
|
||||
Scene scene = SceneSetupHelpers.SetupScene();
|
||||
SceneSetupHelpers.SetupSceneModules(scene, archiverModule);
|
||||
Scene scene = SceneHelpers.SetupScene();
|
||||
SceneHelpers.SetupSceneModules(scene, archiverModule);
|
||||
|
||||
UserAccountHelpers.CreateUserWithInventory(scene, m_uaLL1, "hampshire");
|
||||
|
||||
@@ -109,7 +109,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
|
||||
// Create scene object asset
|
||||
UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000040");
|
||||
SceneObjectGroup object1 = SceneSetupHelpers.CreateSceneObject(1, ownerId, "Ray Gun Object", 0x50);
|
||||
SceneObjectGroup object1 = SceneHelpers.CreateSceneObject(1, ownerId, "Ray Gun Object", 0x50);
|
||||
|
||||
UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060");
|
||||
AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1);
|
||||
@@ -127,10 +127,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
scene.AddInventoryItem(item1);
|
||||
|
||||
// Create coalesced objects asset
|
||||
SceneObjectGroup cobj1 = SceneSetupHelpers.CreateSceneObject(1, m_uaLL1.PrincipalID, "Object1", 0x120);
|
||||
SceneObjectGroup cobj1 = SceneHelpers.CreateSceneObject(1, m_uaLL1.PrincipalID, "Object1", 0x120);
|
||||
cobj1.AbsolutePosition = new Vector3(15, 30, 45);
|
||||
|
||||
SceneObjectGroup cobj2 = SceneSetupHelpers.CreateSceneObject(1, m_uaLL1.PrincipalID, "Object2", 0x140);
|
||||
SceneObjectGroup cobj2 = SceneHelpers.CreateSceneObject(1, m_uaLL1.PrincipalID, "Object2", 0x140);
|
||||
cobj2.AbsolutePosition = new Vector3(25, 50, 75);
|
||||
|
||||
CoalescedSceneObjects coa = new CoalescedSceneObjects(m_uaLL1.PrincipalID, cobj1, cobj2);
|
||||
|
||||
@@ -61,14 +61,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
SerialiserModule serialiserModule = new SerialiserModule();
|
||||
m_archiverModule = new InventoryArchiverModule();
|
||||
|
||||
m_scene = SceneSetupHelpers.SetupScene();
|
||||
SceneSetupHelpers.SetupSceneModules(m_scene, serialiserModule, m_archiverModule);
|
||||
m_scene = SceneHelpers.SetupScene();
|
||||
SceneHelpers.SetupSceneModules(m_scene, serialiserModule, m_archiverModule);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestLoadCoalesecedItem()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL1, "password");
|
||||
@@ -104,7 +104,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
[Test]
|
||||
public void TestOrder()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
MemoryStream archiveReadStream = new MemoryStream(m_iarStreamBytes);
|
||||
@@ -123,13 +123,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test saving a single inventory item to a V0.1 OpenSim Inventory Archive
|
||||
/// Test saving a single inventory item to an IAR
|
||||
/// (subject to change since there is no fixed format yet).
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestSaveItemToIarV0_1()
|
||||
public void TestSaveItemToIar()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
// Create user
|
||||
@@ -141,7 +141,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
|
||||
// Create asset
|
||||
UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000040");
|
||||
SceneObjectGroup object1 = SceneSetupHelpers.CreateSceneObject(1, ownerId, "My Little Dog Object", 0x50);
|
||||
SceneObjectGroup object1 = SceneHelpers.CreateSceneObject(1, ownerId, "My Little Dog Object", 0x50);
|
||||
|
||||
UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060");
|
||||
AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1);
|
||||
@@ -211,6 +211,106 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
}
|
||||
}
|
||||
|
||||
// Assert.That(gotControlFile, Is.True, "No control file in archive");
|
||||
Assert.That(gotObject1File, Is.True, "No item1 file in archive");
|
||||
// Assert.That(gotObject2File, Is.True, "No object2 file in archive");
|
||||
|
||||
// TODO: Test presence of more files and contents of files.
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test saving a single inventory item to an IAR without its asset
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestSaveItemToIarNoAssets()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
// Create user
|
||||
string userFirstName = "Jock";
|
||||
string userLastName = "Stirrup";
|
||||
string userPassword = "troll";
|
||||
UUID userId = UUID.Parse("00000000-0000-0000-0000-000000000020");
|
||||
UserAccountHelpers.CreateUserWithInventory(m_scene, userFirstName, userLastName, userId, userPassword);
|
||||
|
||||
// Create asset
|
||||
UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000040");
|
||||
SceneObjectGroup object1 = SceneHelpers.CreateSceneObject(1, ownerId, "My Little Dog Object", 0x50);
|
||||
|
||||
UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060");
|
||||
AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1);
|
||||
m_scene.AssetService.Store(asset1);
|
||||
|
||||
// Create item
|
||||
UUID item1Id = UUID.Parse("00000000-0000-0000-0000-000000000080");
|
||||
string item1Name = "My Little Dog";
|
||||
InventoryItemBase item1 = new InventoryItemBase();
|
||||
item1.Name = item1Name;
|
||||
item1.AssetID = asset1.FullID;
|
||||
item1.ID = item1Id;
|
||||
InventoryFolderBase objsFolder
|
||||
= InventoryArchiveUtils.FindFolderByPath(m_scene.InventoryService, userId, "Objects")[0];
|
||||
item1.Folder = objsFolder.ID;
|
||||
m_scene.AddInventoryItem(item1);
|
||||
|
||||
MemoryStream archiveWriteStream = new MemoryStream();
|
||||
|
||||
Dictionary<string, Object> options = new Dictionary<string, Object>();
|
||||
options.Add("noassets", true);
|
||||
|
||||
// When we're not saving assets, archiving is being done synchronously.
|
||||
m_archiverModule.ArchiveInventory(
|
||||
Guid.NewGuid(), userFirstName, userLastName, "Objects/" + item1Name, userPassword, archiveWriteStream, options);
|
||||
|
||||
byte[] archive = archiveWriteStream.ToArray();
|
||||
MemoryStream archiveReadStream = new MemoryStream(archive);
|
||||
TarArchiveReader tar = new TarArchiveReader(archiveReadStream);
|
||||
|
||||
//bool gotControlFile = false;
|
||||
bool gotObject1File = false;
|
||||
//bool gotObject2File = false;
|
||||
string expectedObject1FileName = InventoryArchiveWriteRequest.CreateArchiveItemName(item1);
|
||||
string expectedObject1FilePath = string.Format(
|
||||
"{0}{1}",
|
||||
ArchiveConstants.INVENTORY_PATH,
|
||||
expectedObject1FileName);
|
||||
|
||||
string filePath;
|
||||
TarArchiveReader.TarEntryType tarEntryType;
|
||||
|
||||
// Console.WriteLine("Reading archive");
|
||||
|
||||
while (tar.ReadEntry(out filePath, out tarEntryType) != null)
|
||||
{
|
||||
Console.WriteLine("Got {0}", filePath);
|
||||
|
||||
// if (ArchiveConstants.CONTROL_FILE_PATH == filePath)
|
||||
// {
|
||||
// gotControlFile = true;
|
||||
// }
|
||||
|
||||
if (filePath.StartsWith(ArchiveConstants.INVENTORY_PATH) && filePath.EndsWith(".xml"))
|
||||
{
|
||||
// string fileName = filePath.Remove(0, "Objects/".Length);
|
||||
//
|
||||
// if (fileName.StartsWith(part1.Name))
|
||||
// {
|
||||
Assert.That(expectedObject1FilePath, Is.EqualTo(filePath));
|
||||
gotObject1File = true;
|
||||
// }
|
||||
// else if (fileName.StartsWith(part2.Name))
|
||||
// {
|
||||
// Assert.That(fileName, Is.EqualTo(expectedObject2FileName));
|
||||
// gotObject2File = true;
|
||||
// }
|
||||
}
|
||||
else if (filePath.StartsWith(ArchiveConstants.ASSETS_PATH))
|
||||
{
|
||||
Assert.Fail("Found asset path in TestSaveItemToIarNoAssets()");
|
||||
}
|
||||
}
|
||||
|
||||
// Assert.That(gotControlFile, Is.True, "No control file in archive");
|
||||
Assert.That(gotObject1File, Is.True, "No item1 file in archive");
|
||||
// Assert.That(gotObject2File, Is.True, "No object2 file in archive");
|
||||
@@ -225,7 +325,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
[Test]
|
||||
public void TestLoadIarCreatorAccountPresent()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL1, "meowfood");
|
||||
@@ -257,7 +357,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
[Test]
|
||||
public void TestLoadIarV0_1SameNameCreator()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaMT, "meowfood");
|
||||
@@ -290,7 +390,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
[Test]
|
||||
public void TestLoadIarV0_1AbsentCreator()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaMT, "password");
|
||||
|
||||
@@ -57,13 +57,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
[Test]
|
||||
public void TestSavePathToIarV0_1()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
InventoryArchiverModule archiverModule = new InventoryArchiverModule();
|
||||
|
||||
Scene scene = SceneSetupHelpers.SetupScene();
|
||||
SceneSetupHelpers.SetupSceneModules(scene, archiverModule);
|
||||
Scene scene = SceneHelpers.SetupScene();
|
||||
SceneHelpers.SetupSceneModules(scene, archiverModule);
|
||||
|
||||
// Create user
|
||||
string userFirstName = "Jock";
|
||||
@@ -172,16 +172,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
[Test]
|
||||
public void TestLoadIarToInventoryPaths()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
SerialiserModule serialiserModule = new SerialiserModule();
|
||||
InventoryArchiverModule archiverModule = new InventoryArchiverModule();
|
||||
|
||||
// Annoyingly, we have to set up a scene even though inventory loading has nothing to do with a scene
|
||||
Scene scene = SceneSetupHelpers.SetupScene();
|
||||
Scene scene = SceneHelpers.SetupScene();
|
||||
|
||||
SceneSetupHelpers.SetupSceneModules(scene, serialiserModule, archiverModule);
|
||||
SceneHelpers.SetupSceneModules(scene, serialiserModule, archiverModule);
|
||||
|
||||
UserAccountHelpers.CreateUserWithInventory(scene, m_uaMT, "meowfood");
|
||||
UserAccountHelpers.CreateUserWithInventory(scene, m_uaLL1, "hampshire");
|
||||
@@ -217,13 +217,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
[Test]
|
||||
public void TestLoadIarPathStartsWithSlash()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
SerialiserModule serialiserModule = new SerialiserModule();
|
||||
InventoryArchiverModule archiverModule = new InventoryArchiverModule();
|
||||
Scene scene = SceneSetupHelpers.SetupScene();
|
||||
SceneSetupHelpers.SetupSceneModules(scene, serialiserModule, archiverModule);
|
||||
Scene scene = SceneHelpers.SetupScene();
|
||||
SceneHelpers.SetupSceneModules(scene, serialiserModule, archiverModule);
|
||||
|
||||
UserAccountHelpers.CreateUserWithInventory(scene, m_uaMT, "password");
|
||||
archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/Objects", "password", m_iarStream);
|
||||
@@ -238,7 +238,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
[Test]
|
||||
public void TestLoadIarPathWithEscapedChars()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
string itemName = "You & you are a mean/man/";
|
||||
@@ -247,8 +247,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
|
||||
InventoryArchiverModule archiverModule = new InventoryArchiverModule();
|
||||
|
||||
Scene scene = SceneSetupHelpers.SetupScene();
|
||||
SceneSetupHelpers.SetupSceneModules(scene, archiverModule);
|
||||
Scene scene = SceneHelpers.SetupScene();
|
||||
SceneHelpers.SetupSceneModules(scene, archiverModule);
|
||||
|
||||
// Create user
|
||||
string userFirstName = "Jock";
|
||||
@@ -323,10 +323,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
[Test]
|
||||
public void TestNewIarPath()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
Scene scene = SceneSetupHelpers.SetupScene();
|
||||
Scene scene = SceneHelpers.SetupScene();
|
||||
UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene);
|
||||
|
||||
Dictionary <string, InventoryFolderBase> foldersCreated = new Dictionary<string, InventoryFolderBase>();
|
||||
@@ -390,10 +390,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
[Test]
|
||||
public void TestPartExistingIarPath()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
//log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
Scene scene = SceneSetupHelpers.SetupScene();
|
||||
Scene scene = SceneHelpers.SetupScene();
|
||||
UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene);
|
||||
|
||||
string folder1ExistingName = "a";
|
||||
@@ -441,10 +441,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||
[Test]
|
||||
public void TestMergeIarPath()
|
||||
{
|
||||
TestHelper.InMethod();
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
Scene scene = SceneSetupHelpers.SetupScene();
|
||||
Scene scene = SceneHelpers.SetupScene();
|
||||
UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene);
|
||||
|
||||
string folder1ExistingName = "a";
|
||||
|
||||
@@ -208,9 +208,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
|
||||
Array.Copy(copyIDBytes, 0, im.binaryBucket, 1, copyIDBytes.Length);
|
||||
|
||||
if (user != null)
|
||||
{
|
||||
user.ControllingClient.SendBulkUpdateInventory(folderCopy);
|
||||
}
|
||||
|
||||
// HACK!!
|
||||
im.imSessionID = folderID.Guid;
|
||||
@@ -240,9 +238,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
|
||||
Array.Copy(copyID.GetBytes(), 0, im.binaryBucket, 1, 16);
|
||||
|
||||
if (user != null)
|
||||
{
|
||||
user.ControllingClient.SendBulkUpdateInventory(itemCopy);
|
||||
}
|
||||
|
||||
// HACK!!
|
||||
im.imSessionID = itemID.Guid;
|
||||
@@ -280,7 +276,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer
|
||||
else
|
||||
{
|
||||
if (m_TransferModule != null)
|
||||
m_TransferModule.SendInstantMessage(im, delegate(bool success) {});
|
||||
m_TransferModule.SendInstantMessage(im, delegate(bool success) {
|
||||
// Send BulkUpdateInventory
|
||||
IInventoryService invService = scene.InventoryService;
|
||||
UUID inventoryEntityID = new UUID(im.imSessionID); // The inventory item /folder, back from it's trip
|
||||
|
||||
InventoryFolderBase folder = new InventoryFolderBase(inventoryEntityID, client.AgentId);
|
||||
folder = invService.GetFolder(folder);
|
||||
|
||||
ScenePresence fromUser = scene.GetScenePresence(new UUID(im.fromAgentID));
|
||||
|
||||
// If the user has left the scene by the time the message comes back then we can't send
|
||||
// them the update.
|
||||
if (fromUser != null)
|
||||
fromUser.ControllingClient.SendBulkUpdateInventory(folder);
|
||||
});
|
||||
}
|
||||
}
|
||||
else if (im.dialog == (byte) InstantMessageDialog.InventoryDeclined)
|
||||
|
||||
244
OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs
Normal file
244
OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs
Normal file
@@ -0,0 +1,244 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
using OpenMetaverse;
|
||||
using Mono.Addins;
|
||||
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Services.Connectors.Hypergrid;
|
||||
|
||||
using GridRegion = OpenSim.Services.Interfaces.GridRegion;
|
||||
|
||||
namespace OpenSim.Region.CoreModules.Avatar.Lure
|
||||
{
|
||||
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
|
||||
public class HGLureModule : ISharedRegionModule
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(
|
||||
MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private readonly List<Scene> m_scenes = new List<Scene>();
|
||||
|
||||
private IMessageTransferModule m_TransferModule = null;
|
||||
private bool m_Enabled = false;
|
||||
|
||||
private string m_ThisGridURL;
|
||||
|
||||
private ExpiringCache<UUID, GridInstantMessage> m_PendingLures = new ExpiringCache<UUID, GridInstantMessage>();
|
||||
|
||||
public void Initialise(IConfigSource config)
|
||||
{
|
||||
if (config.Configs["Messaging"] != null)
|
||||
{
|
||||
if (config.Configs["Messaging"].GetString("LureModule", string.Empty) == "HGLureModule")
|
||||
{
|
||||
m_Enabled = true;
|
||||
|
||||
m_ThisGridURL = config.Configs["Messaging"].GetString("Gatekeeper", string.Empty);
|
||||
m_log.DebugFormat("[LURE MODULE]: {0} enabled", Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void AddRegion(Scene scene)
|
||||
{
|
||||
if (!m_Enabled)
|
||||
return;
|
||||
|
||||
lock (m_scenes)
|
||||
{
|
||||
m_scenes.Add(scene);
|
||||
scene.EventManager.OnIncomingInstantMessage += OnIncomingInstantMessage;
|
||||
scene.EventManager.OnNewClient += OnNewClient;
|
||||
}
|
||||
}
|
||||
|
||||
public void RegionLoaded(Scene scene)
|
||||
{
|
||||
if (!m_Enabled)
|
||||
return;
|
||||
|
||||
if (m_TransferModule == null)
|
||||
{
|
||||
m_TransferModule =
|
||||
scene.RequestModuleInterface<IMessageTransferModule>();
|
||||
|
||||
if (m_TransferModule == null)
|
||||
{
|
||||
m_log.Error("[LURE MODULE]: No message transfer module, lures will not work!");
|
||||
|
||||
m_Enabled = false;
|
||||
m_scenes.Clear();
|
||||
scene.EventManager.OnNewClient -= OnNewClient;
|
||||
scene.EventManager.OnIncomingInstantMessage -= OnIncomingInstantMessage;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void RemoveRegion(Scene scene)
|
||||
{
|
||||
if (!m_Enabled)
|
||||
return;
|
||||
|
||||
lock (m_scenes)
|
||||
{
|
||||
m_scenes.Remove(scene);
|
||||
scene.EventManager.OnNewClient -= OnNewClient;
|
||||
scene.EventManager.OnIncomingInstantMessage -= OnIncomingInstantMessage;
|
||||
}
|
||||
}
|
||||
|
||||
void OnNewClient(IClientAPI client)
|
||||
{
|
||||
client.OnInstantMessage += OnInstantMessage;
|
||||
client.OnStartLure += OnStartLure;
|
||||
client.OnTeleportLureRequest += OnTeleportLureRequest;
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return "HGLureModule"; }
|
||||
}
|
||||
|
||||
public Type ReplaceableInterface
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
void OnInstantMessage(IClientAPI client, GridInstantMessage im)
|
||||
{
|
||||
}
|
||||
|
||||
void OnIncomingInstantMessage(GridInstantMessage im)
|
||||
{
|
||||
if (im.dialog == (byte)InstantMessageDialog.RequestTeleport)
|
||||
{
|
||||
UUID sessionID = new UUID(im.imSessionID);
|
||||
m_log.DebugFormat("[HG LURE MODULE]: RequestTeleport sessionID={0}, regionID={1}, message={2}", im.imSessionID, im.RegionID, im.message);
|
||||
m_PendingLures.Add(sessionID, im, 7200); // 2 hours
|
||||
|
||||
// Forward. We do this, because the IM module explicitly rejects
|
||||
// IMs of this type
|
||||
if (m_TransferModule != null)
|
||||
m_TransferModule.SendInstantMessage(im, delegate(bool success) { });
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void OnStartLure(byte lureType, string message, UUID targetid, IClientAPI client)
|
||||
{
|
||||
if (!(client.Scene is Scene))
|
||||
return;
|
||||
|
||||
Scene scene = (Scene)(client.Scene);
|
||||
ScenePresence presence = scene.GetScenePresence(client.AgentId);
|
||||
|
||||
message += "@" + m_ThisGridURL;
|
||||
|
||||
m_log.DebugFormat("[HG LURE MODULE]: TP invite with message {0}", message);
|
||||
|
||||
GridInstantMessage m = new GridInstantMessage(scene, client.AgentId,
|
||||
client.FirstName+" "+client.LastName, targetid,
|
||||
(byte)InstantMessageDialog.RequestTeleport, false,
|
||||
message, UUID.Random(), false, presence.AbsolutePosition,
|
||||
new Byte[0]);
|
||||
m.RegionID = client.Scene.RegionInfo.RegionID.Guid;
|
||||
|
||||
if (m_TransferModule != null)
|
||||
{
|
||||
m_TransferModule.SendInstantMessage(m,
|
||||
delegate(bool success) { });
|
||||
}
|
||||
}
|
||||
|
||||
public void OnTeleportLureRequest(UUID lureID, uint teleportFlags, IClientAPI client)
|
||||
{
|
||||
if (!(client.Scene is Scene))
|
||||
return;
|
||||
|
||||
// Scene scene = (Scene)(client.Scene);
|
||||
|
||||
GridInstantMessage im = null;
|
||||
if (m_PendingLures.TryGetValue(lureID, out im))
|
||||
{
|
||||
m_PendingLures.Remove(lureID);
|
||||
Lure(client, teleportFlags, im);
|
||||
}
|
||||
else
|
||||
m_log.DebugFormat("[HG LURE MODULE]: pending lure {0} not found", lureID);
|
||||
|
||||
}
|
||||
|
||||
private void Lure(IClientAPI client, uint teleportflags, GridInstantMessage im)
|
||||
{
|
||||
Scene scene = (Scene)(client.Scene);
|
||||
GridRegion region = scene.GridService.GetRegionByUUID(scene.RegionInfo.ScopeID, new UUID(im.RegionID));
|
||||
if (region != null)
|
||||
scene.RequestTeleportLocation(client, region.RegionHandle, im.Position + new Vector3(0.5f, 0.5f, 0f), Vector3.UnitX, teleportflags);
|
||||
else // we don't have that region here. Check if it's HG
|
||||
{
|
||||
string[] parts = im.message.Split(new char[] { '@' });
|
||||
if (parts.Length > 1)
|
||||
{
|
||||
string url = parts[parts.Length - 1]; // the last part
|
||||
if (url.Trim(new char[] {'/'}) != m_ThisGridURL.Trim(new char[] {'/'}))
|
||||
{
|
||||
m_log.DebugFormat("[HG LURE MODULE]: Luring agent to grid {0} region {1} position {2}", url, im.RegionID, im.Position);
|
||||
GatekeeperServiceConnector gConn = new GatekeeperServiceConnector();
|
||||
GridRegion gatekeeper = new GridRegion();
|
||||
gatekeeper.ServerURI = url;
|
||||
GridRegion finalDestination = gConn.GetHyperlinkRegion(gatekeeper, new UUID(im.RegionID));
|
||||
if (finalDestination != null)
|
||||
{
|
||||
ScenePresence sp = scene.GetScenePresence(client.AgentId);
|
||||
IEntityTransferModule transferMod = scene.RequestModuleInterface<IEntityTransferModule>();
|
||||
IEventQueue eq = sp.Scene.RequestModuleInterface<IEventQueue>();
|
||||
if (transferMod != null && sp != null && eq != null)
|
||||
transferMod.DoTeleport(sp, gatekeeper, finalDestination, im.Position + new Vector3(0.5f, 0.5f, 0f), Vector3.UnitX, teleportflags, eq);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -45,16 +45,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure
|
||||
private readonly List<Scene> m_scenes = new List<Scene>();
|
||||
|
||||
private IMessageTransferModule m_TransferModule = null;
|
||||
private bool m_Enabled = true;
|
||||
private bool m_Enabled = false;
|
||||
|
||||
public void Initialise(IConfigSource config)
|
||||
{
|
||||
if (config.Configs["Messaging"] != null)
|
||||
{
|
||||
if (config.Configs["Messaging"].GetString(
|
||||
"LureModule", "LureModule") !=
|
||||
"LureModule", "LureModule") ==
|
||||
"LureModule")
|
||||
m_Enabled = false;
|
||||
{
|
||||
m_Enabled = true;
|
||||
m_log.DebugFormat("[LURE MODULE]: {0} enabled", Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,6 +77,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure
|
||||
|
||||
public void RegionLoaded(Scene scene)
|
||||
{
|
||||
if (!m_Enabled)
|
||||
return;
|
||||
|
||||
if (m_TransferModule == null)
|
||||
{
|
||||
m_TransferModule =
|
||||
@@ -96,6 +102,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure
|
||||
|
||||
public void RemoveRegion(Scene scene)
|
||||
{
|
||||
if (!m_Enabled)
|
||||
return;
|
||||
|
||||
lock (m_scenes)
|
||||
{
|
||||
m_scenes.Remove(scene);
|
||||
|
||||
173
OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs
Normal file
173
OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs
Normal file
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Reflection;
|
||||
|
||||
using OpenMetaverse;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
using Mono.Addins;
|
||||
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Services.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.CoreModules.Avatar.Profile
|
||||
{
|
||||
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
|
||||
public class BasicProfileModule : ISharedRegionModule
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
//
|
||||
// Module vars
|
||||
//
|
||||
private List<Scene> m_Scenes = new List<Scene>();
|
||||
private bool m_Enabled = false;
|
||||
|
||||
#region ISharedRegionModule
|
||||
|
||||
public void Initialise(IConfigSource config)
|
||||
{
|
||||
if (config.Configs["Profile"] != null)
|
||||
{
|
||||
if (config.Configs["Profile"].GetString("Module", string.Empty) != "BasicProfileModule")
|
||||
return;
|
||||
}
|
||||
|
||||
m_log.DebugFormat("[PROFILE MODULE]: Basic Profile Module enabled");
|
||||
m_Enabled = true;
|
||||
|
||||
}
|
||||
|
||||
public void AddRegion(Scene scene)
|
||||
{
|
||||
if (!m_Enabled)
|
||||
return;
|
||||
|
||||
lock (m_Scenes)
|
||||
{
|
||||
if (!m_Scenes.Contains(scene))
|
||||
{
|
||||
m_Scenes.Add(scene);
|
||||
// Hook up events
|
||||
scene.EventManager.OnNewClient += OnNewClient;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void RegionLoaded(Scene scene)
|
||||
{
|
||||
if (!m_Enabled)
|
||||
return;
|
||||
}
|
||||
|
||||
public void RemoveRegion(Scene scene)
|
||||
{
|
||||
if (!m_Enabled)
|
||||
return;
|
||||
|
||||
lock (m_Scenes)
|
||||
{
|
||||
m_Scenes.Remove(scene);
|
||||
}
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return "BasicProfileModule"; }
|
||||
}
|
||||
|
||||
public Type ReplaceableInterface
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// New Client Event Handler
|
||||
private void OnNewClient(IClientAPI client)
|
||||
{
|
||||
//Profile
|
||||
client.OnRequestAvatarProperties += RequestAvatarProperties;
|
||||
}
|
||||
|
||||
public void RequestAvatarProperties(IClientAPI remoteClient, UUID avatarID)
|
||||
{
|
||||
IScene s = remoteClient.Scene;
|
||||
if (!(s is Scene))
|
||||
return;
|
||||
|
||||
// Scene scene = (Scene)s;
|
||||
|
||||
string profileUrl = String.Empty;
|
||||
string aboutText = String.Empty;
|
||||
string firstLifeAboutText = String.Empty;
|
||||
UUID image = UUID.Zero;
|
||||
UUID firstLifeImage = UUID.Zero;
|
||||
UUID partner = UUID.Zero;
|
||||
uint wantMask = 0;
|
||||
string wantText = String.Empty;
|
||||
uint skillsMask = 0;
|
||||
string skillsText = String.Empty;
|
||||
string languages = String.Empty;
|
||||
|
||||
Byte[] charterMember = Utils.StringToBytes("Avatar");
|
||||
|
||||
profileUrl = "No profile data";
|
||||
aboutText = string.Empty;
|
||||
firstLifeAboutText = string.Empty;
|
||||
image = UUID.Zero;
|
||||
firstLifeImage = UUID.Zero;
|
||||
partner = UUID.Zero;
|
||||
|
||||
remoteClient.SendAvatarProperties(avatarID, aboutText,
|
||||
Util.ToDateTime(0).ToString(
|
||||
"M/d/yyyy", CultureInfo.InvariantCulture),
|
||||
charterMember, firstLifeAboutText,
|
||||
(uint)(0 & 0xff),
|
||||
firstLifeImage, image, profileUrl, partner);
|
||||
|
||||
//Viewer expects interest data when it asks for properties.
|
||||
remoteClient.SendAvatarInterestsReply(avatarID, wantMask, wantText,
|
||||
skillsMask, skillsText, languages);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -50,13 +50,23 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
/// <summary>
|
||||
/// The maximum distance, in standard region units (256m) that an agent is allowed to transfer.
|
||||
/// </summary>
|
||||
private int m_MaxTransferDistance = 4095;
|
||||
public int MaxTransferDistance
|
||||
{
|
||||
get { return m_MaxTransferDistance; }
|
||||
set { m_MaxTransferDistance = value; }
|
||||
}
|
||||
|
||||
protected bool m_Enabled = false;
|
||||
protected Scene m_aScene;
|
||||
protected List<Scene> m_Scenes = new List<Scene>();
|
||||
protected List<UUID> m_agentsInTransit;
|
||||
private ExpiringCache<UUID, ExpiringCache<ulong, DateTime>> m_bannedRegions =
|
||||
new ExpiringCache<UUID, ExpiringCache<ulong, DateTime>>();
|
||||
|
||||
|
||||
#region ISharedRegionModule
|
||||
|
||||
public Type ReplaceableInterface
|
||||
@@ -77,13 +87,26 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
string name = moduleConfig.GetString("EntityTransferModule", "");
|
||||
if (name == Name)
|
||||
{
|
||||
m_agentsInTransit = new List<UUID>();
|
||||
m_Enabled = true;
|
||||
m_log.InfoFormat("[ENTITY TRANSFER MODULE]: {0} enabled.", Name);
|
||||
InitialiseCommon(source);
|
||||
m_log.DebugFormat("[ENTITY TRANSFER MODULE]: {0} enabled.", Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initialize config common for this module and any descendents.
|
||||
/// </summary>
|
||||
/// <param name="source"></param>
|
||||
protected virtual void InitialiseCommon(IConfigSource source)
|
||||
{
|
||||
IConfig transferConfig = source.Configs["EntityTransfer"];
|
||||
if (transferConfig != null)
|
||||
MaxTransferDistance = transferConfig.GetInt("max_distance", 4095);
|
||||
|
||||
m_agentsInTransit = new List<UUID>();
|
||||
m_Enabled = true;
|
||||
}
|
||||
|
||||
public virtual void PostInitialise()
|
||||
{
|
||||
}
|
||||
@@ -96,13 +119,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
if (m_aScene == null)
|
||||
m_aScene = scene;
|
||||
|
||||
m_Scenes.Add(scene);
|
||||
scene.RegisterModuleInterface<IEntityTransferModule>(this);
|
||||
scene.EventManager.OnNewClient += OnNewClient;
|
||||
}
|
||||
|
||||
protected virtual void OnNewClient(IClientAPI client)
|
||||
{
|
||||
client.OnTeleportHomeRequest += TeleportHomeFired;
|
||||
client.OnTeleportHomeRequest += TriggerTeleportHome;
|
||||
client.OnTeleportLandmarkRequest += RequestTeleportLandmark;
|
||||
}
|
||||
|
||||
public virtual void Close()
|
||||
@@ -111,23 +136,22 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
public virtual void RemoveRegion(Scene scene)
|
||||
{
|
||||
if (!m_Enabled)
|
||||
return;
|
||||
if (scene == m_aScene)
|
||||
m_aScene = null;
|
||||
|
||||
m_Scenes.Remove(scene);
|
||||
}
|
||||
|
||||
public virtual void RegionLoaded(Scene scene)
|
||||
{
|
||||
if (!m_Enabled)
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region Agent Teleports
|
||||
@@ -183,8 +207,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
sp.TeleportFlags = (TeleportFlags)teleportFlags;
|
||||
sp.Teleport(position);
|
||||
|
||||
foreach (SceneObjectGroup grp in sp.Attachments)
|
||||
sp.Scene.EventManager.TriggerOnScriptChangedEvent(grp.LocalId, (uint)Changed.TELEPORT);
|
||||
foreach (SceneObjectGroup grp in sp.GetAttachments())
|
||||
{
|
||||
if (grp.IsDeleted)
|
||||
sp.Scene.EventManager.TriggerOnScriptChangedEvent(grp.LocalId, (uint)Changed.TELEPORT);
|
||||
}
|
||||
}
|
||||
else // Another region possibly in another simulator
|
||||
{
|
||||
@@ -201,8 +228,18 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
sp.ControllingClient.SendTeleportFailed("Problem at destination");
|
||||
return;
|
||||
}
|
||||
m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Final destination is x={0} y={1} {2}@{3}",
|
||||
finalDestination.RegionLocX / Constants.RegionSize, finalDestination.RegionLocY / Constants.RegionSize, finalDestination.RegionID, finalDestination.ServerURI);
|
||||
|
||||
uint curX = 0, curY = 0;
|
||||
Utils.LongToUInts(sp.Scene.RegionInfo.RegionHandle, out curX, out curY);
|
||||
int curCellX = (int)(curX / Constants.RegionSize);
|
||||
int curCellY = (int)(curY / Constants.RegionSize);
|
||||
int destCellX = (int)(finalDestination.RegionLocX / Constants.RegionSize);
|
||||
int destCellY = (int)(finalDestination.RegionLocY / Constants.RegionSize);
|
||||
|
||||
// m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Source co-ords are x={0} y={1}", curRegionX, curRegionY);
|
||||
//
|
||||
// m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Final dest is x={0} y={1} {2}@{3}",
|
||||
// destRegionX, destRegionY, finalDestination.RegionID, finalDestination.ServerURI);
|
||||
|
||||
// Check that these are not the same coordinates
|
||||
if (finalDestination.RegionLocX == sp.Scene.RegionInfo.RegionLocX &&
|
||||
@@ -213,6 +250,18 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
return;
|
||||
}
|
||||
|
||||
if (Math.Abs(curCellX - destCellX) > MaxTransferDistance || Math.Abs(curCellY - destCellY) > MaxTransferDistance)
|
||||
{
|
||||
sp.ControllingClient.SendTeleportFailed(
|
||||
string.Format(
|
||||
"Can't teleport to {0} ({1},{2}) from {3} ({4},{5}), destination is more than {6} regions way",
|
||||
finalDestination.RegionName, destCellX, destCellY,
|
||||
sp.Scene.RegionInfo.RegionName, curCellX, curCellY,
|
||||
MaxTransferDistance));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// This is it
|
||||
//
|
||||
@@ -249,7 +298,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
}
|
||||
}
|
||||
|
||||
protected void DoTeleport(ScenePresence sp, GridRegion reg, GridRegion finalDestination, Vector3 position, Vector3 lookAt, uint teleportFlags, IEventQueue eq)
|
||||
public void DoTeleport(ScenePresence sp, GridRegion reg, GridRegion finalDestination, Vector3 position, Vector3 lookAt, uint teleportFlags, IEventQueue eq)
|
||||
{
|
||||
if (reg == null || finalDestination == null)
|
||||
{
|
||||
@@ -280,10 +329,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
sp.StandUp();
|
||||
|
||||
if (!sp.ValidateAttachments())
|
||||
{
|
||||
sp.ControllingClient.SendTeleportFailed("Inconsistent attachment state");
|
||||
return;
|
||||
}
|
||||
m_log.DebugFormat(
|
||||
"[ENTITY TRANSFER MODULE]: Failed validation of all attachments for teleport of {0} from {1} to {2}. Continuing.",
|
||||
sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName);
|
||||
|
||||
// if (!sp.ValidateAttachments())
|
||||
// {
|
||||
// sp.ControllingClient.SendTeleportFailed("Inconsistent attachment state");
|
||||
// return;
|
||||
// }
|
||||
|
||||
string reason;
|
||||
string version;
|
||||
@@ -446,7 +500,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
// Now let's make it officially a child agent
|
||||
sp.MakeChildAgent();
|
||||
|
||||
sp.Scene.CleanDroppedAttachments();
|
||||
// sp.Scene.CleanDroppedAttachments();
|
||||
|
||||
// Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone
|
||||
|
||||
@@ -512,11 +566,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
|
||||
protected virtual void AgentHasMovedAway(ScenePresence sp, bool logout)
|
||||
{
|
||||
foreach (SceneObjectGroup sop in sp.Attachments)
|
||||
{
|
||||
sop.Scene.DeleteSceneObject(sop, true);
|
||||
}
|
||||
sp.Attachments.Clear();
|
||||
sp.Scene.AttachmentsModule.DeleteAttachmentsFromScene(sp, true);
|
||||
}
|
||||
|
||||
protected void KillEntity(Scene scene, uint localID)
|
||||
@@ -557,9 +607,32 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
|
||||
#endregion
|
||||
|
||||
#region Landmark Teleport
|
||||
/// <summary>
|
||||
/// Tries to teleport agent to landmark.
|
||||
/// </summary>
|
||||
/// <param name="remoteClient"></param>
|
||||
/// <param name="regionHandle"></param>
|
||||
/// <param name="position"></param>
|
||||
public virtual void RequestTeleportLandmark(IClientAPI remoteClient, AssetLandmark lm)
|
||||
{
|
||||
GridRegion info = m_aScene.GridService.GetRegionByUUID(UUID.Zero, lm.RegionID);
|
||||
|
||||
if (info == null)
|
||||
{
|
||||
// can't find the region: Tell viewer and abort
|
||||
remoteClient.SendTeleportFailed("The teleport destination could not be found.");
|
||||
return;
|
||||
}
|
||||
((Scene)(remoteClient.Scene)).RequestTeleportLocation(remoteClient, info.RegionHandle, lm.Position,
|
||||
Vector3.Zero, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaLandmark));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Teleport Home
|
||||
|
||||
public void TeleportHomeFired(UUID id, IClientAPI client)
|
||||
public virtual void TriggerTeleportHome(UUID id, IClientAPI client)
|
||||
{
|
||||
TeleportHome(id, client);
|
||||
}
|
||||
@@ -888,7 +961,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
/// This Closes child agents on neighbouring regions
|
||||
/// Calls an asynchronous method to do so.. so it doesn't lag the sim.
|
||||
/// </summary>
|
||||
protected ScenePresence CrossAgentToNewRegionAsync(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying, string version)
|
||||
protected ScenePresence CrossAgentToNewRegionAsync(
|
||||
ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion,
|
||||
bool isFlying, string version)
|
||||
{
|
||||
ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize));
|
||||
|
||||
@@ -896,8 +971,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
|
||||
Scene m_scene = agent.Scene;
|
||||
|
||||
if (neighbourRegion != null && agent.ValidateAttachments())
|
||||
if (neighbourRegion != null)
|
||||
{
|
||||
if (!agent.ValidateAttachments())
|
||||
m_log.DebugFormat(
|
||||
"[ENTITY TRANSFER MODULE]: Failed validation of all attachments for region crossing of {0} from {1} to {2}. Continuing.",
|
||||
agent.Name, agent.Scene.RegionInfo.RegionName, neighbourRegion.RegionName);
|
||||
|
||||
pos = pos + (agent.Velocity);
|
||||
|
||||
SetInTransit(agent.UUID);
|
||||
@@ -1017,10 +1097,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
#endregion
|
||||
|
||||
#region Enable Child Agent
|
||||
|
||||
/// <summary>
|
||||
/// This informs a single neighbouring region about agent "avatar".
|
||||
/// Calls an asynchronous method to do so.. so it doesn't lag the sim.
|
||||
/// </summary>
|
||||
/// <param name="sp"></param>
|
||||
/// <param name="region"></param>
|
||||
public void EnableChildAgent(ScenePresence sp, GridRegion region)
|
||||
{
|
||||
m_log.DebugFormat("[ENTITY TRANSFER]: Enabling child agent in new neighbour {0}", region.RegionName);
|
||||
@@ -1082,6 +1165,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
/// This informs all neighbouring regions about agent "avatar".
|
||||
/// Calls an asynchronous method to do so.. so it doesn't lag the sim.
|
||||
/// </summary>
|
||||
/// <param name="sp"></param>
|
||||
public void EnableChildAgents(ScenePresence sp)
|
||||
{
|
||||
List<GridRegion> neighbours = new List<GridRegion>();
|
||||
@@ -1269,7 +1353,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
Utils.LongToUInts(reg.RegionHandle, out x, out y);
|
||||
x = x / Constants.RegionSize;
|
||||
y = y / Constants.RegionSize;
|
||||
m_log.Debug("[ENTITY TRANSFER MODULE]: Starting to inform client about neighbour " + x + ", " + y + "(" + endPoint.ToString() + ")");
|
||||
m_log.Debug("[ENTITY TRANSFER MODULE]: Starting to inform client about neighbour " + x + ", " + y + "(" + endPoint + ")");
|
||||
|
||||
string capsPath = reg.ServerURI + CapsUtil.GetCapsSeedPath(a.CapsPath);
|
||||
|
||||
@@ -1715,34 +1799,33 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
|
||||
protected bool CrossAttachmentsIntoNewRegion(GridRegion destination, ScenePresence sp, bool silent)
|
||||
{
|
||||
List<SceneObjectGroup> m_attachments = sp.Attachments;
|
||||
lock (m_attachments)
|
||||
List<SceneObjectGroup> m_attachments = sp.GetAttachments();
|
||||
|
||||
// Validate
|
||||
// foreach (SceneObjectGroup gobj in m_attachments)
|
||||
// {
|
||||
// if (gobj == null || gobj.IsDeleted)
|
||||
// return false;
|
||||
// }
|
||||
|
||||
foreach (SceneObjectGroup gobj in m_attachments)
|
||||
{
|
||||
// Validate
|
||||
foreach (SceneObjectGroup gobj in m_attachments)
|
||||
// If the prim group is null then something must have happened to it!
|
||||
if (gobj != null && !gobj.IsDeleted)
|
||||
{
|
||||
if (gobj == null || gobj.IsDeleted)
|
||||
return false;
|
||||
// Set the parent localID to 0 so it transfers over properly.
|
||||
gobj.RootPart.SetParentLocalId(0);
|
||||
gobj.AbsolutePosition = gobj.RootPart.AttachedPos;
|
||||
gobj.IsAttachment = false;
|
||||
//gobj.RootPart.LastOwnerID = gobj.GetFromAssetID();
|
||||
m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending attachment {0} to region {1}", gobj.UUID, destination.RegionName);
|
||||
CrossPrimGroupIntoNewRegion(destination, gobj, silent);
|
||||
}
|
||||
|
||||
foreach (SceneObjectGroup gobj in m_attachments)
|
||||
{
|
||||
// If the prim group is null then something must have happened to it!
|
||||
if (gobj != null && gobj.RootPart != null)
|
||||
{
|
||||
// Set the parent localID to 0 so it transfers over properly.
|
||||
gobj.RootPart.SetParentLocalId(0);
|
||||
gobj.AbsolutePosition = gobj.RootPart.AttachedPos;
|
||||
gobj.RootPart.IsAttachment = false;
|
||||
//gobj.RootPart.LastOwnerID = gobj.GetFromAssetID();
|
||||
m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending attachment {0} to region {1}", gobj.UUID, destination.RegionName);
|
||||
CrossPrimGroupIntoNewRegion(destination, gobj, silent);
|
||||
}
|
||||
}
|
||||
m_attachments.Clear();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
sp.ClearAttachments();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -1791,7 +1874,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
int i = 0;
|
||||
if (sp.InTransitScriptStates.Count > 0)
|
||||
{
|
||||
sp.Attachments.ForEach(delegate(SceneObjectGroup sog)
|
||||
List<SceneObjectGroup> attachments = sp.GetAttachments();
|
||||
|
||||
foreach (SceneObjectGroup sog in attachments)
|
||||
{
|
||||
if (i < sp.InTransitScriptStates.Count)
|
||||
{
|
||||
@@ -1800,8 +1885,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
sog.ResumeScripts();
|
||||
}
|
||||
else
|
||||
m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: InTransitScriptStates.Count={0} smaller than Attachments.Count={1}", sp.InTransitScriptStates.Count, sp.Attachments.Count);
|
||||
});
|
||||
m_log.ErrorFormat(
|
||||
"[ENTITY TRANSFER MODULE]: InTransitScriptStates.Count={0} smaller than Attachments.Count={1}",
|
||||
sp.InTransitScriptStates.Count, attachments.Count);
|
||||
}
|
||||
|
||||
sp.InTransitScriptStates.Clear();
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user