Compare commits
359 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a315aee803 | ||
|
|
0c931e3657 | ||
|
|
9f4d772d6a | ||
|
|
d6cf029860 | ||
|
|
083587eb32 | ||
|
|
8c8e3ad3ff | ||
|
|
91d5495e26 | ||
|
|
2030377d2c | ||
|
|
31a0f75aff | ||
|
|
c1d84ffc6c | ||
|
|
6c72381732 | ||
|
|
8c271802ac | ||
|
|
20a76fd224 | ||
|
|
4473f00e63 | ||
|
|
0b5210dd6a | ||
|
|
34d4bde585 | ||
|
|
4c20c2045c | ||
|
|
d9a8f5f16d | ||
|
|
79c2081741 | ||
|
|
eb49c356e2 | ||
|
|
717942e81b | ||
|
|
6d47c394b2 | ||
|
|
8305c5d369 | ||
|
|
9e5f5f3d80 | ||
|
|
0a277a64a7 | ||
|
|
7dd0b7ea2f | ||
|
|
cd666a3d2c | ||
|
|
681502473e | ||
|
|
0ffe293692 | ||
|
|
356e8516f0 | ||
|
|
71b11f557d | ||
|
|
26be9ed08e | ||
|
|
f43d63240d | ||
|
|
5c982c98aa | ||
|
|
63f0ec9aeb | ||
|
|
e90cfc17ca | ||
|
|
16d5ce16b6 | ||
|
|
ab4c4a362f | ||
|
|
b5971db76c | ||
|
|
0c39c9e84d | ||
|
|
0b49773ab3 | ||
|
|
820a39621e | ||
|
|
7a0f4cf8e1 | ||
|
|
2853b78f16 | ||
|
|
a3ada745bd | ||
|
|
ff0f90bc35 | ||
|
|
7b564b8b35 | ||
|
|
19a818017d | ||
|
|
7bc03a54e5 | ||
|
|
aef6a9571c | ||
|
|
0a3b2f904e | ||
|
|
023023a5fc | ||
|
|
eebcea22ba | ||
|
|
9474bdb6df | ||
|
|
4d28bac9bb | ||
|
|
de746cd987 | ||
|
|
0ef16f9f5b | ||
|
|
de0a45d9a3 | ||
|
|
a2071e5b13 | ||
|
|
1b3ae566e8 | ||
|
|
674baa39ed | ||
|
|
1cf57c83e1 | ||
|
|
e98e580900 | ||
|
|
292ab783e4 | ||
|
|
0563530bf8 | ||
|
|
2135b89c07 | ||
|
|
2b19a112d9 | ||
|
|
cd78f50632 | ||
|
|
b300db9e0a | ||
|
|
4370f0e181 | ||
|
|
48ea503c33 | ||
|
|
546eb88112 | ||
|
|
52710b48ac | ||
|
|
cc5e28c1c1 | ||
|
|
67a2d6d855 | ||
|
|
7d426debd3 | ||
|
|
4de98ca4c8 | ||
|
|
deb50cd410 | ||
|
|
b3cfc5b76e | ||
|
|
27644bcce6 | ||
|
|
903da8acbd | ||
|
|
cfdccdd71c | ||
|
|
93e65fb9d5 | ||
|
|
af117fe4d4 | ||
|
|
986f6b39ca | ||
|
|
7a8dd539fd | ||
|
|
382cda662f | ||
|
|
ede9aea45f | ||
|
|
52b8518fc2 | ||
|
|
c3d16955a7 | ||
|
|
61df0da7f9 | ||
|
|
f8b0427086 | ||
|
|
5b0d0ef1e9 | ||
|
|
7ca688f5c5 | ||
|
|
9dc1000c27 | ||
|
|
638afca5aa | ||
|
|
7e415e3f85 | ||
|
|
8c4e58995d | ||
|
|
d26ded4788 | ||
|
|
5268334c61 | ||
|
|
6ba4cbc259 | ||
|
|
ac445463e9 | ||
|
|
1e83800d32 | ||
|
|
3d94984eee | ||
|
|
fd8734b22c | ||
|
|
9b229efdc5 | ||
|
|
81daedcfe3 | ||
|
|
b819771919 | ||
|
|
2f536f92c0 | ||
|
|
0b4774c50c | ||
|
|
139b0d03b6 | ||
|
|
c13916d392 | ||
|
|
3ebb56734d | ||
|
|
235147c857 | ||
|
|
ddb74bc68d | ||
|
|
cd132966df | ||
|
|
5d4fee6eb9 | ||
|
|
cc80377325 | ||
|
|
7dce33ce69 | ||
|
|
0dd45f6ca4 | ||
|
|
ac3d88804f | ||
|
|
f1698552f9 | ||
|
|
dfeb424afd | ||
|
|
2380980975 | ||
|
|
52ec854c42 | ||
|
|
4dbfcc26a2 | ||
|
|
a262d2492f | ||
|
|
e5b7e2fd40 | ||
|
|
7505f23f80 | ||
|
|
7562e63ae6 | ||
|
|
7987a6da95 | ||
|
|
fcd60c6b74 | ||
|
|
1e88bf78f1 | ||
|
|
a819890137 | ||
|
|
5c85a98f6a | ||
|
|
e58daf052d | ||
|
|
0a0e285919 | ||
|
|
c693bd51a0 | ||
|
|
808ace0696 | ||
|
|
9730a862db | ||
|
|
754d6036ea | ||
|
|
476d893630 | ||
|
|
0a6374d37a | ||
|
|
0337f2e2a0 | ||
|
|
7be35d5a9a | ||
|
|
8ab2d42143 | ||
|
|
dc8ce9ec5d | ||
|
|
7171913400 | ||
|
|
0cf5c0837b | ||
|
|
1edfe05c16 | ||
|
|
bba4577d88 | ||
|
|
5c305494ae | ||
|
|
4b2b0d4a05 | ||
|
|
61848ebe0d | ||
|
|
f48431345b | ||
|
|
9c4597a00f | ||
|
|
b528150d16 | ||
|
|
4a99619bc0 | ||
|
|
5bd27b7b22 | ||
|
|
8ea97cc608 | ||
|
|
1850b778e2 | ||
|
|
5cd33f5e21 | ||
|
|
cd3d5379d6 | ||
|
|
58021b5300 | ||
|
|
3b141e5eee | ||
|
|
08bc6622dd | ||
|
|
c253539c04 | ||
|
|
f3b45be9c0 | ||
|
|
59c19110e4 | ||
|
|
7c03fba3fc | ||
|
|
2593a446ac | ||
|
|
011c1279f5 | ||
|
|
25133cbdf6 | ||
|
|
06ed824711 | ||
|
|
63aa448608 | ||
|
|
4afb773399 | ||
|
|
dafe65ad81 | ||
|
|
b107a8ec2a | ||
|
|
e31d7fe424 | ||
|
|
cc9888f28b | ||
|
|
fef3baf107 | ||
|
|
123322569d | ||
|
|
8c0d8e72aa | ||
|
|
1e69845869 | ||
|
|
1bc0d0fac6 | ||
|
|
f7b5d17aa2 | ||
|
|
85170f5d5d | ||
|
|
66863fdd34 | ||
|
|
6b0553ed7c | ||
|
|
57cffcd1ec | ||
|
|
78739067d1 | ||
|
|
310c2403b0 | ||
|
|
a88381ba82 | ||
|
|
1fa0c2f9b0 | ||
|
|
1069390b3e | ||
|
|
3068cc3618 | ||
|
|
b5a69833f8 | ||
|
|
8b5bacc78b | ||
|
|
8f7f03e7fd | ||
|
|
80bea38c07 | ||
|
|
9742491a63 | ||
|
|
acad65a832 | ||
|
|
b527901556 | ||
|
|
3c9654d5d6 | ||
|
|
4be42b3f75 | ||
|
|
6a994f8c9c | ||
|
|
f9e6e32ce2 | ||
|
|
6bbf4fdc0f | ||
|
|
10aee2f0ec | ||
|
|
0ed6149463 | ||
|
|
a64be59c3b | ||
|
|
b720454950 | ||
|
|
dd3dc5cd91 | ||
|
|
9cd94ac6ec | ||
|
|
2cc49d7d9a | ||
|
|
69e11af475 | ||
|
|
aa6915f1ba | ||
|
|
b36ff0fd24 | ||
|
|
a16c9206b4 | ||
|
|
b5b2541d1a | ||
|
|
1baadac59a | ||
|
|
88ef35cb23 | ||
|
|
05dff4987b | ||
|
|
e1e0f20c7f | ||
|
|
70d559d1af | ||
|
|
6c92b48143 | ||
|
|
127626edd8 | ||
|
|
aba26c098d | ||
|
|
9f19405490 | ||
|
|
871f1d0ae7 | ||
|
|
057b78bfbe | ||
|
|
d4fc07aae1 | ||
|
|
750e8ec3da | ||
|
|
15142093ad | ||
|
|
f050f0fc0b | ||
|
|
a3c79b399e | ||
|
|
424735efee | ||
|
|
d5dfbc3844 | ||
|
|
c3127d1323 | ||
|
|
03c98c3b8f | ||
|
|
24e02afeac | ||
|
|
8d5606e09b | ||
|
|
bd3d119a03 | ||
|
|
cf2405385d | ||
|
|
a6eba09dac | ||
|
|
b2ca7c0927 | ||
|
|
dd6c236253 | ||
|
|
b2ff680cca | ||
|
|
23a9a7daa7 | ||
|
|
19fde57fca | ||
|
|
a556930456 | ||
|
|
1a008b237b | ||
|
|
d6456b9ea8 | ||
|
|
5980d57b7a | ||
|
|
7c409eff53 | ||
|
|
614ea5a48a | ||
|
|
8905f34e18 | ||
|
|
380f2a1719 | ||
|
|
1c66e08964 | ||
|
|
af564291f2 | ||
|
|
250eed5141 | ||
|
|
a2c9b3d83d | ||
|
|
3a047b2bdb | ||
|
|
f8deca7f2d | ||
|
|
63a6bc93e4 | ||
|
|
50c340ef35 | ||
|
|
41e7e613a2 | ||
|
|
4d1ab38068 | ||
|
|
47c412ca1e | ||
|
|
acb0a5b6c1 | ||
|
|
1b8716a99a | ||
|
|
9edbb4f77a | ||
|
|
753f11273f | ||
|
|
435aefe1bf | ||
|
|
e5286b7b7c | ||
|
|
aa4637db47 | ||
|
|
73c201449f | ||
|
|
36be226dc8 | ||
|
|
ea5d1d0ff0 | ||
|
|
299cc2d12d | ||
|
|
4ecd3fbff1 | ||
|
|
1b32d5c6a4 | ||
|
|
c404760731 | ||
|
|
7d4e224620 | ||
|
|
986ded5a72 | ||
|
|
8340bd7e20 | ||
|
|
9d59fc0587 | ||
|
|
22e1298e97 | ||
|
|
1a29ddf328 | ||
|
|
8a2c3a0267 | ||
|
|
ea65d4f5ce | ||
|
|
eb65f5072d | ||
|
|
aad13a4c76 | ||
|
|
233127c696 | ||
|
|
b7fcd6871e | ||
|
|
c06cd3b2b9 | ||
|
|
31ac7571f4 | ||
|
|
2a7a5c4c90 | ||
|
|
d8ad649957 | ||
|
|
a1f232af2b | ||
|
|
14bddb6af9 | ||
|
|
f93635fe85 | ||
|
|
3a635507cc | ||
|
|
0506ccb51a | ||
|
|
4bce90d0ab | ||
|
|
4d93ab06c9 | ||
|
|
e2c807a0d0 | ||
|
|
23a9a98d5d | ||
|
|
32ba06a55c | ||
|
|
64c42a729a | ||
|
|
b342fb9c0a | ||
|
|
3f70f54fa6 | ||
|
|
c4ce7b8162 | ||
|
|
4c9226be7b | ||
|
|
58f2c9e224 | ||
|
|
8ba0cc470a | ||
|
|
2a654974c9 | ||
|
|
b72753dc81 | ||
|
|
2ecfa29eb6 | ||
|
|
3678b8f1f7 | ||
|
|
29a62abc6d | ||
|
|
31ef2f9a2e | ||
|
|
21e3f8e53a | ||
|
|
579aa9c6a0 | ||
|
|
8b374daae9 | ||
|
|
31d1b3310d | ||
|
|
d1711519a0 | ||
|
|
71fa970990 | ||
|
|
6fa4f88d39 | ||
|
|
9ff3d9221b | ||
|
|
3920e56dd4 | ||
|
|
6700f1edd9 | ||
|
|
e6d1182dec | ||
|
|
a3316f1eac | ||
|
|
5f281716a9 | ||
|
|
f90c3d0633 | ||
|
|
633d4f3e6e | ||
|
|
43bbdbe760 | ||
|
|
494e5867a3 | ||
|
|
270f0d5ae3 | ||
|
|
d079ee9ef1 | ||
|
|
cd46bf6fad | ||
|
|
bb419044ef | ||
|
|
549fdc8b11 | ||
|
|
550d1fea96 | ||
|
|
94f49e859b | ||
|
|
c2586b0ea9 | ||
|
|
2905288545 | ||
|
|
353170589b | ||
|
|
ee78c4d2a8 | ||
|
|
084df4b7ef | ||
|
|
53ffc7ff8c | ||
|
|
d8d048cfa1 | ||
|
|
a4e1d29e3c | ||
|
|
8c4dd6b330 | ||
|
|
f1612997a6 | ||
|
|
c574c80011 | ||
|
|
9f76bc4fff | ||
|
|
79f3de6ba8 |
21
.gitignore
vendored
21
.gitignore
vendored
@@ -1,6 +1,5 @@
|
||||
.project
|
||||
.settings
|
||||
.gitignore
|
||||
*.csproj
|
||||
*.csproj.user
|
||||
*.build
|
||||
@@ -11,7 +10,6 @@
|
||||
*.pidb
|
||||
*.dll.build
|
||||
*.dll
|
||||
*.log
|
||||
*.VisualState.xml
|
||||
*/*/obj
|
||||
*/*/*/obj
|
||||
@@ -25,7 +23,6 @@
|
||||
*/*/*/*/*/bin
|
||||
*/*/*/*/*/*/bin
|
||||
*/*/*/*/*/*/*/bin
|
||||
addon-modules/
|
||||
bin/Debug/*.dll
|
||||
bin/*.dll.mdb
|
||||
bin/*.db
|
||||
@@ -73,20 +70,4 @@ TAGS
|
||||
Makefile.local
|
||||
bin/.version
|
||||
compile.bat
|
||||
addon-modules
|
||||
OpenSim/Data/Tests/test-results/
|
||||
OpenSim/Framework/Serialization/Tests/test-results/
|
||||
OpenSim/Framework/Servers/Tests/test-results/
|
||||
OpenSim/Framework/Tests/test-results/
|
||||
OpenSim/Region/ClientStack/Linden/Caps/test-results/
|
||||
OpenSim/Region/ClientStack/Linden/UDP/Tests/test-results/
|
||||
OpenSim/Region/CoreModules/test-results/
|
||||
OpenSim/Region/Framework/test-results/
|
||||
OpenSim/Region/OptionalModules/test-results/
|
||||
OpenSim/Region/Physics/BulletDotNETPlugin/
|
||||
OpenSim/Region/Physics/Manager/test-results/
|
||||
OpenSim/Region/Physics/OdePlugin/Tests/test-results/
|
||||
OpenSim/Region/ScriptEngine/test-results/
|
||||
OpenSim/Tests/Common/test-results/
|
||||
OpenSim/Tests/test-results/
|
||||
test-results/
|
||||
|
||||
|
||||
@@ -117,12 +117,10 @@
|
||||
</exec>
|
||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.clientstack.lindencaps.tests)==0}" />
|
||||
|
||||
<!--
|
||||
<exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.region.clientstack.lindenudp.tests">
|
||||
<arg value="./bin/OpenSim.Region.ClientStack.LindenUDP.Tests.dll" />
|
||||
</exec>
|
||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.clientstack.lindenudp.tests)==0}" />
|
||||
-->
|
||||
|
||||
<exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.region.scriptengine.tests">
|
||||
<arg value="./bin/OpenSim.Region.ScriptEngine.Tests.dll" />
|
||||
@@ -341,7 +339,7 @@
|
||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.tests)==0}" />
|
||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.framework.tests)==0}" />
|
||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.framework.servers.tests)==0}" />
|
||||
<!-- <fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.clientstack.lindenudp.tests)==0}" /> -->
|
||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.clientstack.lindenudp.tests)==0}" />
|
||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.scriptengine.tests)==0}" />
|
||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.coremodules.tests)==0}" />
|
||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.optionalmodules.tests)==0}" />
|
||||
|
||||
@@ -12,7 +12,7 @@ Steps:
|
||||
=== Building on Linux ===
|
||||
|
||||
Prereqs:
|
||||
* Mono >= 2.4.3
|
||||
* Mono >= 2.4.2
|
||||
* Nant >= 0.85
|
||||
* On some Linux distributions you may need to install additional packages.
|
||||
See http://opensimulator.org/wiki/Dependencies for more information.
|
||||
|
||||
@@ -5,7 +5,7 @@ for your effort!)
|
||||
These folks represent the current core team for OpenSim, and are the
|
||||
people that make the day to day of OpenSim happen.
|
||||
|
||||
* justincc (OSVW Consulting, justincc.org)
|
||||
* justincc
|
||||
* chi11ken (Genkii)
|
||||
* dahlia
|
||||
* Melanie Thielker
|
||||
@@ -14,9 +14,7 @@ people that make the day to day of OpenSim happen.
|
||||
* Marck
|
||||
* Mic Bowman (Intel)
|
||||
* BlueWall (James Hughes)
|
||||
* Nebadon Izumi (Michael Cerquoni, OSgrid)
|
||||
* Snoopy Pfeffer
|
||||
* Richard Adams (Intel)
|
||||
|
||||
= Core Developers Following the White Rabbit =
|
||||
Core developers who have temporarily (we hope) gone chasing the white rabbit.
|
||||
@@ -83,7 +81,6 @@ what it is today.
|
||||
* Gerhard
|
||||
* Godfrey
|
||||
* Grumly57
|
||||
* GuduleLapointe
|
||||
* Ewe Loon
|
||||
* Fly-Man
|
||||
* Flyte Xevious
|
||||
@@ -104,7 +101,6 @@ what it is today.
|
||||
* lulurun
|
||||
* M.Igarashi
|
||||
* maimedleech
|
||||
* Mana Janus
|
||||
* Mic Bowman
|
||||
* Michelle Argus
|
||||
* Michael Cortez (The Flotsam Project, http://osflotsam.org/)
|
||||
@@ -123,7 +119,6 @@ what it is today.
|
||||
* openlifegrid.com
|
||||
* Oren Hurvitz (Kitely)
|
||||
* otakup0pe
|
||||
* Pixel Tomsen
|
||||
* ralphos
|
||||
* RemedyTomm
|
||||
* Revolution
|
||||
@@ -136,7 +131,6 @@ what it is today.
|
||||
* Salahzar Stenvaag
|
||||
* sempuki
|
||||
* SignpostMarv
|
||||
* SpotOn3D
|
||||
* Strawberry Fride
|
||||
* tglion
|
||||
* tlaukkan/Tommil (Tommi S. E. Laukkanen, Bubble Cloud)
|
||||
|
||||
@@ -30,7 +30,6 @@ using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using log4net;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.RegionLoader.Filesystem;
|
||||
using OpenSim.Framework.RegionLoader.Web;
|
||||
@@ -153,20 +152,9 @@ namespace OpenSim.ApplicationPlugins.LoadRegions
|
||||
/// <returns>True if we're sane, false if we're insane</returns>
|
||||
private bool CheckRegionsForSanity(RegionInfo[] regions)
|
||||
{
|
||||
if (regions.Length == 0)
|
||||
if (regions.Length <= 1)
|
||||
return true;
|
||||
|
||||
foreach (RegionInfo region in regions)
|
||||
{
|
||||
if (region.RegionID == UUID.Zero)
|
||||
{
|
||||
m_log.ErrorFormat(
|
||||
"[LOAD REGIONS PLUGIN]: Region {0} has invalid UUID {1}",
|
||||
region.RegionName, region.RegionID);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < regions.Length - 1; i++)
|
||||
{
|
||||
for (int j = i + 1; j < regions.Length; j++)
|
||||
@@ -198,5 +186,35 @@ namespace OpenSim.ApplicationPlugins.LoadRegions
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void LoadRegionFromConfig(OpenSimBase openSim, ulong regionhandle)
|
||||
{
|
||||
m_log.Info("[LOADREGIONS]: Load Regions addin being initialised");
|
||||
|
||||
IRegionLoader regionLoader;
|
||||
if (openSim.ConfigSource.Source.Configs["Startup"].GetString("region_info_source", "filesystem") == "filesystem")
|
||||
{
|
||||
m_log.Info("[LOADREGIONS]: Loading Region Info from filesystem");
|
||||
regionLoader = new RegionLoaderFileSystem();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.Info("[LOADREGIONS]: Loading Region Info from web");
|
||||
regionLoader = new RegionLoaderWebServer();
|
||||
}
|
||||
|
||||
regionLoader.SetIniConfigSource(openSim.ConfigSource.Source);
|
||||
RegionInfo[] regionsToLoad = regionLoader.LoadRegions();
|
||||
for (int i = 0; i < regionsToLoad.Length; i++)
|
||||
{
|
||||
if (regionhandle == regionsToLoad[i].RegionHandle)
|
||||
{
|
||||
IScene scene;
|
||||
m_log.Debug("[LOADREGIONS]: Creating Region: " + regionsToLoad[i].RegionName + " (ThreadID: " +
|
||||
Thread.CurrentThread.ManagedThreadId.ToString() + ")");
|
||||
openSim.CreateRegion(regionsToLoad[i], true, out scene);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -148,7 +148,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory.Tests
|
||||
|
||||
Rest.main.SceneManager.ForEachScene(delegate(Scene s)
|
||||
{
|
||||
s.ForEachRootScenePresence(delegate(ScenePresence sp)
|
||||
s.ForEachScenePresence(delegate(ScenePresence sp)
|
||||
{
|
||||
if (sp.Firstname == names[0] && sp.Lastname == names[1])
|
||||
{
|
||||
|
||||
@@ -51,11 +51,10 @@ namespace OpenSim.Framework.Capabilities
|
||||
/// supplied BaseHttpServer.
|
||||
/// </summary>
|
||||
/// <param name="httpListener">base HTTP server</param>
|
||||
/// <param name="httpListenerHostname">host name of the HTTP
|
||||
/// server</param>
|
||||
/// <param name="httpListenerHostname">host name of the HTTP server</param>
|
||||
/// <param name="httpListenerPort">HTTP port</param>
|
||||
public CapsHandlers(BaseHttpServer httpListener, string httpListenerHostname, uint httpListenerPort)
|
||||
: this (httpListener,httpListenerHostname,httpListenerPort, false)
|
||||
: this(httpListener,httpListenerHostname,httpListenerPort, false)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -88,44 +87,52 @@ namespace OpenSim.Framework.Capabilities
|
||||
/// handler to be removed</param>
|
||||
public void Remove(string capsName)
|
||||
{
|
||||
m_httpListener.RemoveStreamHandler("POST", m_capsHandlers[capsName].Path);
|
||||
m_httpListener.RemoveStreamHandler("GET", m_capsHandlers[capsName].Path);
|
||||
m_capsHandlers.Remove(capsName);
|
||||
lock (m_capsHandlers)
|
||||
{
|
||||
m_httpListener.RemoveStreamHandler("POST", m_capsHandlers[capsName].Path);
|
||||
m_httpListener.RemoveStreamHandler("GET", m_capsHandlers[capsName].Path);
|
||||
m_capsHandlers.Remove(capsName);
|
||||
}
|
||||
}
|
||||
|
||||
public bool ContainsCap(string cap)
|
||||
{
|
||||
return m_capsHandlers.ContainsKey(cap);
|
||||
lock (m_capsHandlers)
|
||||
return m_capsHandlers.ContainsKey(cap);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The indexer allows us to treat the CapsHandlers object
|
||||
/// in an intuitive dictionary like way.
|
||||
/// </summary>
|
||||
/// <Remarks>
|
||||
/// <remarks>
|
||||
/// The indexer will throw an exception when you try to
|
||||
/// retrieve a cap handler for a cap that is not contained in
|
||||
/// CapsHandlers.
|
||||
/// </Remarks>
|
||||
/// </remarks>
|
||||
public IRequestHandler this[string idx]
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_capsHandlers[idx];
|
||||
lock (m_capsHandlers)
|
||||
return m_capsHandlers[idx];
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
if (m_capsHandlers.ContainsKey(idx))
|
||||
lock (m_capsHandlers)
|
||||
{
|
||||
m_httpListener.RemoveStreamHandler("POST", m_capsHandlers[idx].Path);
|
||||
m_capsHandlers.Remove(idx);
|
||||
if (m_capsHandlers.ContainsKey(idx))
|
||||
{
|
||||
m_httpListener.RemoveStreamHandler("POST", m_capsHandlers[idx].Path);
|
||||
m_capsHandlers.Remove(idx);
|
||||
}
|
||||
|
||||
if (null == value) return;
|
||||
|
||||
m_capsHandlers[idx] = value;
|
||||
m_httpListener.AddStreamHandler(value);
|
||||
}
|
||||
|
||||
if (null == value) return;
|
||||
|
||||
m_capsHandlers[idx] = value;
|
||||
m_httpListener.AddStreamHandler(value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,9 +144,12 @@ namespace OpenSim.Framework.Capabilities
|
||||
{
|
||||
get
|
||||
{
|
||||
string[] __keys = new string[m_capsHandlers.Keys.Count];
|
||||
m_capsHandlers.Keys.CopyTo(__keys, 0);
|
||||
return __keys;
|
||||
lock (m_capsHandlers)
|
||||
{
|
||||
string[] __keys = new string[m_capsHandlers.Keys.Count];
|
||||
m_capsHandlers.Keys.CopyTo(__keys, 0);
|
||||
return __keys;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,25 +157,29 @@ namespace OpenSim.Framework.Capabilities
|
||||
/// Return an LLSD-serializable Hashtable describing the
|
||||
/// capabilities and their handler details.
|
||||
/// </summary>
|
||||
public Hashtable CapsDetails
|
||||
/// <param name="excludeSeed">If true, then exclude the seed cap.</param>
|
||||
public Hashtable GetCapsDetails(bool excludeSeed)
|
||||
{
|
||||
get
|
||||
{
|
||||
Hashtable caps = new Hashtable();
|
||||
string protocol = "http://";
|
||||
|
||||
if (m_useSSL)
|
||||
protocol = "https://";
|
||||
Hashtable caps = new Hashtable();
|
||||
string protocol = "http://";
|
||||
|
||||
if (m_useSSL)
|
||||
protocol = "https://";
|
||||
|
||||
string baseUrl = protocol + m_httpListenerHostName + ":" + m_httpListenerPort.ToString();
|
||||
string baseUrl = protocol + m_httpListenerHostName + ":" + m_httpListenerPort.ToString();
|
||||
|
||||
lock (m_capsHandlers)
|
||||
{
|
||||
foreach (string capsName in m_capsHandlers.Keys)
|
||||
{
|
||||
// skip SEED cap
|
||||
if ("SEED" == capsName) continue;
|
||||
if (excludeSeed && "SEED" == capsName)
|
||||
continue;
|
||||
|
||||
caps[capsName] = baseUrl + m_capsHandlers[capsName].Path;
|
||||
}
|
||||
return caps;
|
||||
}
|
||||
|
||||
return caps;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -111,6 +111,10 @@ namespace OpenSim.Capabilities.Handlers
|
||||
m_log.Warn("[GETTEXTURE]: Failed to parse a texture_id from GetTexture request: " + httpRequest.Url);
|
||||
}
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[GETTEXTURE]: For texture {0} sending back response {1}, data length {2}",
|
||||
// textureID, httpResponse.StatusCode, httpResponse.ContentLength);
|
||||
|
||||
httpResponse.Send();
|
||||
return null;
|
||||
}
|
||||
@@ -210,7 +214,7 @@ namespace OpenSim.Capabilities.Handlers
|
||||
private void WriteTextureData(OSHttpRequest request, OSHttpResponse response, AssetBase texture, string format)
|
||||
{
|
||||
string range = request.Headers.GetOne("Range");
|
||||
//m_log.DebugFormat("[GETTEXTURE]: Range {0}", range);
|
||||
|
||||
if (!String.IsNullOrEmpty(range)) // JP2's only
|
||||
{
|
||||
// Range request
|
||||
@@ -222,23 +226,27 @@ namespace OpenSim.Capabilities.Handlers
|
||||
if (start >= texture.Data.Length)
|
||||
{
|
||||
response.StatusCode = (int)System.Net.HttpStatusCode.RequestedRangeNotSatisfiable;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
end = Utils.Clamp(end, 0, texture.Data.Length - 1);
|
||||
start = Utils.Clamp(start, 0, end);
|
||||
int len = end - start + 1;
|
||||
|
||||
end = Utils.Clamp(end, 0, texture.Data.Length - 1);
|
||||
start = Utils.Clamp(start, 0, end);
|
||||
int len = end - start + 1;
|
||||
//m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID);
|
||||
|
||||
//m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID);
|
||||
|
||||
if (len < texture.Data.Length)
|
||||
// Always return PartialContent, even if the range covered the entire data length
|
||||
// We were accidentally sending back 404 before in this situation
|
||||
// https://issues.apache.org/bugzilla/show_bug.cgi?id=51878 supports sending 206 even if the
|
||||
// entire range is requested, and viewer 3.2.2 (and very probably earlier) seems fine with this.
|
||||
response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent;
|
||||
|
||||
response.ContentLength = len;
|
||||
response.ContentType = texture.Metadata.ContentType;
|
||||
response.AddHeader("Content-Range", String.Format("bytes {0}-{1}/{2}", start, end, texture.Data.Length));
|
||||
|
||||
response.Body.Write(texture.Data, start, len);
|
||||
response.ContentLength = len;
|
||||
response.ContentType = texture.Metadata.ContentType;
|
||||
response.AddHeader("Content-Range", String.Format("bytes {0}-{1}/{2}", start, end, texture.Data.Length));
|
||||
|
||||
response.Body.Write(texture.Data, start, len);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -257,6 +265,10 @@ namespace OpenSim.Capabilities.Handlers
|
||||
response.ContentType = "image/" + format;
|
||||
response.Body.Write(texture.Data, 0, texture.Data.Length);
|
||||
}
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[GETTEXTURE]: For texture {0} requested range {1} responded {2} with content length {3} (actual {4})",
|
||||
// texture.FullID, range, response.StatusCode, response.ContentLength, texture.Data.Length);
|
||||
}
|
||||
|
||||
private bool TryParseRange(string header, out int start, out int end)
|
||||
@@ -275,7 +287,6 @@ namespace OpenSim.Capabilities.Handlers
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private byte[] ConvertTextureData(AssetBase texture, string format)
|
||||
{
|
||||
m_log.DebugFormat("[GETTEXTURE]: Converting texture {0} to {1}", texture.ID, format);
|
||||
@@ -350,7 +361,5 @@ namespace OpenSim.Capabilities.Handlers
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
* 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.Specialized;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Reflection;
|
||||
using System.IO;
|
||||
using System.Web;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
using OpenMetaverse;
|
||||
using OpenMetaverse.StructuredData;
|
||||
using OpenMetaverse.Imaging;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Capabilities;
|
||||
using OpenSim.Framework.Servers;
|
||||
using OpenSim.Framework.Servers.HttpServer;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using Caps = OpenSim.Framework.Capabilities.Caps;
|
||||
|
||||
namespace OpenSim.Capabilities.Handlers
|
||||
{
|
||||
public class UploadBakedTextureHandler
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private Caps m_HostCapsObj;
|
||||
private IAssetService m_assetService;
|
||||
private bool m_persistBakedTextures;
|
||||
|
||||
public UploadBakedTextureHandler(Caps caps, IAssetService assetService, bool persistBakedTextures)
|
||||
{
|
||||
m_HostCapsObj = caps;
|
||||
m_assetService = assetService;
|
||||
m_persistBakedTextures = persistBakedTextures;
|
||||
}
|
||||
|
||||
/// <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
|
||||
{
|
||||
string capsBase = "/CAPS/" + m_HostCapsObj.CapsObjectPath;
|
||||
string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000");
|
||||
|
||||
BakedTextureUploader uploader =
|
||||
new BakedTextureUploader(capsBase + uploaderPath, m_HostCapsObj.HttpListener);
|
||||
uploader.OnUpLoad += BakedTextureUploaded;
|
||||
|
||||
m_HostCapsObj.HttpListener.AddStreamHandler(
|
||||
new BinaryStreamHandler("POST", capsBase + uploaderPath,
|
||||
uploader.uploaderCaps));
|
||||
|
||||
string protocol = "http://";
|
||||
|
||||
if (m_HostCapsObj.SSLCaps)
|
||||
protocol = "https://";
|
||||
|
||||
string uploaderURL = protocol + m_HostCapsObj.HostName + ":" +
|
||||
m_HostCapsObj.Port.ToString() + capsBase + uploaderPath;
|
||||
|
||||
LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse();
|
||||
uploadResponse.uploader = uploaderURL;
|
||||
uploadResponse.state = "upload";
|
||||
|
||||
return LLSDHelpers.SerialiseLLSDReply(uploadResponse);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Error("[UPLOAD BAKED TEXTURE HANDLER]: " + e.ToString());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when a baked texture has been successfully uploaded by a client.
|
||||
/// </summary>
|
||||
/// <param name="assetID"></param>
|
||||
/// <param name="data"></param>
|
||||
private void BakedTextureUploaded(UUID assetID, byte[] data)
|
||||
{
|
||||
// m_log.WarnFormat("[CAPS]: Received baked texture {0}", assetID.ToString());
|
||||
|
||||
AssetBase asset;
|
||||
asset = new AssetBase(assetID, "Baked Texture", (sbyte)AssetType.Texture, m_HostCapsObj.AgentID.ToString());
|
||||
asset.Data = data;
|
||||
asset.Temporary = true;
|
||||
asset.Local = !m_persistBakedTextures; // Local assets aren't persisted, non-local are
|
||||
m_assetService.Store(asset);
|
||||
}
|
||||
}
|
||||
|
||||
class BakedTextureUploader
|
||||
{
|
||||
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
public event Action<UUID, byte[]> OnUpLoad;
|
||||
|
||||
private string uploaderPath = String.Empty;
|
||||
private UUID newAssetID;
|
||||
private IHttpServer httpListener;
|
||||
|
||||
public BakedTextureUploader(string path, IHttpServer httpServer)
|
||||
{
|
||||
newAssetID = UUID.Random();
|
||||
uploaderPath = path;
|
||||
httpListener = httpServer;
|
||||
// m_log.InfoFormat("[CAPS] baked texture upload starting for {0}",newAssetID);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle raw uploaded baked texture data.
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <param name="path"></param>
|
||||
/// <param name="param"></param>
|
||||
/// <returns></returns>
|
||||
public string uploaderCaps(byte[] data, string path, string param)
|
||||
{
|
||||
Action<UUID, byte[]> handlerUpLoad = OnUpLoad;
|
||||
|
||||
// Don't do this asynchronously, otherwise it's possible for the client to send set appearance information
|
||||
// on another thread which might send out avatar updates before the asset has been put into the asset
|
||||
// service.
|
||||
if (handlerUpLoad != null)
|
||||
handlerUpLoad(newAssetID, data);
|
||||
|
||||
string res = String.Empty;
|
||||
LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete();
|
||||
uploadComplete.new_asset = newAssetID.ToString();
|
||||
uploadComplete.new_inventory_item = UUID.Zero;
|
||||
uploadComplete.state = "complete";
|
||||
|
||||
res = LLSDHelpers.SerialiseLLSDReply(uploadComplete);
|
||||
|
||||
httpListener.RemoveStreamHandler("POST", uploaderPath);
|
||||
|
||||
// m_log.DebugFormat("[BAKED TEXTURE UPLOADER]: baked texture upload completed for {0}", newAssetID);
|
||||
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -208,7 +208,86 @@ namespace OpenSim.Capabilities.Handlers
|
||||
containingFolder.Owner = agentID;
|
||||
containingFolder = m_InventoryService.GetFolder(containingFolder);
|
||||
if (containingFolder != null)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[WEB FETCH INV DESC HANDLER]: Retrieved folder {0} {1} for agent id {2}",
|
||||
// containingFolder.Name, containingFolder.ID, agentID);
|
||||
|
||||
version = containingFolder.Version;
|
||||
//
|
||||
// if (fetchItems)
|
||||
// {
|
||||
// List<InventoryItemBase> linkedItemsToAdd = new List<InventoryItemBase>();
|
||||
//
|
||||
// foreach (InventoryItemBase item in contents.Items)
|
||||
// {
|
||||
// if (item.AssetType == (int)AssetType.Link)
|
||||
// {
|
||||
// InventoryItemBase linkedItem = m_InventoryService.GetItem(new InventoryItemBase(item.AssetID));
|
||||
//
|
||||
// // Take care of genuinely broken links where the target doesn't exist
|
||||
// // HACK: Also, don't follow up links that just point to other links. In theory this is legitimate,
|
||||
// // but no viewer has been observed to set these up and this is the lazy way of avoiding cycles
|
||||
// // rather than having to keep track of every folder requested in the recursion.
|
||||
// if (linkedItem != null && linkedItem.AssetType != (int)AssetType.Link)
|
||||
// linkedItemsToAdd.Insert(0, linkedItem);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// foreach (InventoryItemBase linkedItem in linkedItemsToAdd)
|
||||
// {
|
||||
// m_log.DebugFormat(
|
||||
// "[WEB FETCH INV DESC HANDLER]: Inserted linked item {0} for link in folder {1} for agent {2}",
|
||||
// linkedItem.Name, folderID, agentID);
|
||||
//
|
||||
// contents.Items.Add(linkedItem);
|
||||
// }
|
||||
//
|
||||
// // If the folder requested contains links, then we need to send those folders first, otherwise the links
|
||||
// // will be broken in the viewer.
|
||||
// HashSet<UUID> linkedItemFolderIdsToSend = new HashSet<UUID>();
|
||||
// foreach (InventoryItemBase item in contents.Items)
|
||||
// {
|
||||
// if (item.AssetType == (int)AssetType.Link)
|
||||
// {
|
||||
// InventoryItemBase linkedItem = m_InventoryService.GetItem(new InventoryItemBase(item.AssetID));
|
||||
//
|
||||
// // Take care of genuinely broken links where the target doesn't exist
|
||||
// // HACK: Also, don't follow up links that just point to other links. In theory this is legitimate,
|
||||
// // but no viewer has been observed to set these up and this is the lazy way of avoiding cycles
|
||||
// // rather than having to keep track of every folder requested in the recursion.
|
||||
// if (linkedItem != null && linkedItem.AssetType != (int)AssetType.Link)
|
||||
// {
|
||||
// // We don't need to send the folder if source and destination of the link are in the same
|
||||
// // folder.
|
||||
// if (linkedItem.Folder != containingFolder.ID)
|
||||
// linkedItemFolderIdsToSend.Add(linkedItem.Folder);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// foreach (UUID linkedItemFolderId in linkedItemFolderIdsToSend)
|
||||
// {
|
||||
// m_log.DebugFormat(
|
||||
// "[WEB FETCH INV DESC HANDLER]: Recursively fetching folder {0} linked by item in folder {1} for agent {2}",
|
||||
// linkedItemFolderId, folderID, agentID);
|
||||
//
|
||||
// int dummyVersion;
|
||||
// InventoryCollection linkedCollection
|
||||
// = Fetch(
|
||||
// agentID, linkedItemFolderId, ownerID, fetchFolders, fetchItems, sortOrder, out dummyVersion);
|
||||
//
|
||||
// InventoryFolderBase linkedFolder = new InventoryFolderBase(linkedItemFolderId);
|
||||
// linkedFolder.Owner = agentID;
|
||||
// linkedFolder = m_InventoryService.GetFolder(linkedFolder);
|
||||
//
|
||||
//// contents.Folders.AddRange(linkedCollection.Folders);
|
||||
//
|
||||
// contents.Folders.Add(linkedFolder);
|
||||
// contents.Items.AddRange(linkedCollection.Items);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace OpenSim.Data
|
||||
{
|
||||
public abstract AssetBase GetAsset(UUID uuid);
|
||||
|
||||
public abstract bool StoreAsset(AssetBase asset);
|
||||
public abstract void StoreAsset(AssetBase asset);
|
||||
public abstract bool ExistsAsset(UUID uuid);
|
||||
|
||||
public abstract List<AssetMetadata> FetchAssetMetadataSet(int start, int count);
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace OpenSim.Data
|
||||
public interface IAssetDataPlugin : IPlugin
|
||||
{
|
||||
AssetBase GetAsset(UUID uuid);
|
||||
bool StoreAsset(AssetBase asset);
|
||||
void StoreAsset(AssetBase asset);
|
||||
bool ExistsAsset(UUID uuid);
|
||||
List<AssetMetadata> FetchAssetMetadataSet(int start, int count);
|
||||
void Initialise(string connect);
|
||||
|
||||
@@ -37,10 +37,30 @@ namespace OpenSim.Data
|
||||
public UUID RegionID;
|
||||
public UUID ScopeID;
|
||||
public string RegionName;
|
||||
|
||||
/// <summary>
|
||||
/// The position in meters of this region.
|
||||
/// </summary>
|
||||
public int posX;
|
||||
|
||||
/// <summary>
|
||||
/// The position in meters of this region.
|
||||
/// </summary>
|
||||
public int posY;
|
||||
|
||||
public int sizeX;
|
||||
public int sizeY;
|
||||
|
||||
/// <summary>
|
||||
/// Return the x-coordinate of this region.
|
||||
/// </summary>
|
||||
public int coordX { get { return posX / (int)Constants.RegionSize; } }
|
||||
|
||||
/// <summary>
|
||||
/// Return the y-coordinate of this region.
|
||||
/// </summary>
|
||||
public int coordY { get { return posY / (int)Constants.RegionSize; } }
|
||||
|
||||
public Dictionary<string, object> Data;
|
||||
}
|
||||
|
||||
|
||||
@@ -50,6 +50,5 @@ namespace OpenSim.Data
|
||||
bool Store(UserAccountData data);
|
||||
bool Delete(string field, string val);
|
||||
UserAccountData[] GetUsers(UUID scopeID, string query);
|
||||
UserAccountData[] GetUsersWhere(UUID scopeID, string where);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,7 +143,7 @@ namespace OpenSim.Data.MSSQL
|
||||
/// Create asset in m_database
|
||||
/// </summary>
|
||||
/// <param name="asset">the asset</param>
|
||||
override public bool StoreAsset(AssetBase asset)
|
||||
override public void StoreAsset(AssetBase asset)
|
||||
{
|
||||
|
||||
string sql =
|
||||
@@ -192,12 +192,10 @@ namespace OpenSim.Data.MSSQL
|
||||
try
|
||||
{
|
||||
command.ExecuteNonQuery();
|
||||
return true;
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
m_log.Error("[ASSET DB]: Error storing item :" + e.Message);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace OpenSim.Data.MSSQL
|
||||
public class MSSQLAvatarData : MSSQLGenericTableHandler<AvatarBaseData>,
|
||||
IAvatarData
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
public MSSQLAvatarData(string connectionString, string realm) :
|
||||
base(connectionString, realm, "Avatar")
|
||||
|
||||
@@ -40,8 +40,8 @@ namespace OpenSim.Data.MSSQL
|
||||
{
|
||||
public class MSSQLGenericTableHandler<T> where T : class, new()
|
||||
{
|
||||
private static readonly ILog m_log =
|
||||
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
// private static readonly ILog m_log =
|
||||
// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
protected string m_ConnectionString;
|
||||
protected MSSQLManager m_database; //used for parameter type translation
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace OpenSim.Data.MSSQL
|
||||
public class MSSQLGridUserData : MSSQLGenericTableHandler<GridUserData>,
|
||||
IGridUserData
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
public MSSQLGridUserData(string connectionString, string realm) :
|
||||
base(connectionString, realm, "GridUserStore")
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace OpenSim.Data.MSSQL
|
||||
/// </summary>
|
||||
public class MSSQLManager
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
/// <summary>
|
||||
/// Connection string for ADO.net
|
||||
@@ -180,8 +180,6 @@ namespace OpenSim.Data.MSSQL
|
||||
return parameter;
|
||||
}
|
||||
|
||||
private static readonly Dictionary<string, string> emptyDictionary = new Dictionary<string, string>();
|
||||
|
||||
/// <summary>
|
||||
/// Checks if we need to do some migrations to the database
|
||||
/// </summary>
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace OpenSim.Data.MSSQL
|
||||
public class MSSQLPresenceData : MSSQLGenericTableHandler<PresenceData>,
|
||||
IPresenceData
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
public MSSQLPresenceData(string connectionString, string realm) :
|
||||
base(connectionString, realm, "Presence")
|
||||
|
||||
@@ -242,10 +242,5 @@ namespace OpenSim.Data.MSSQL
|
||||
return DoQuery(cmd);
|
||||
}
|
||||
}
|
||||
|
||||
public UserAccountData[] GetUsersWhere(UUID scopeID, string where)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,8 +40,8 @@ namespace OpenSim.Data.MSSQL
|
||||
{
|
||||
public class MSSQLXInventoryData : IXInventoryData
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(
|
||||
MethodBase.GetCurrentMethod().DeclaringType);
|
||||
// private static readonly ILog m_log = LogManager.GetLogger(
|
||||
// MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private MSSQLGenericTableHandler<XInventoryFolder> m_Folders;
|
||||
private MSSQLItemHandler m_Items;
|
||||
|
||||
@@ -155,7 +155,7 @@ namespace OpenSim.Data.MySQL
|
||||
/// </summary>
|
||||
/// <param name="asset">Asset UUID to create</param>
|
||||
/// <remarks>On failure : Throw an exception and attempt to reconnect to database</remarks>
|
||||
override public bool StoreAsset(AssetBase asset)
|
||||
override public void StoreAsset(AssetBase asset)
|
||||
{
|
||||
lock (m_dbLock)
|
||||
{
|
||||
@@ -203,14 +203,12 @@ namespace OpenSim.Data.MySQL
|
||||
cmd.Parameters.AddWithValue("?data", asset.Data);
|
||||
cmd.ExecuteNonQuery();
|
||||
cmd.Dispose();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat("[ASSET DB]: MySQL failure creating asset {0} with name \"{1}\". Error: {2}",
|
||||
asset.FullID, asset.Name, e.Message);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ namespace OpenSim.Data.MySQL
|
||||
Initialise(connectionString);
|
||||
}
|
||||
|
||||
public virtual void Initialise(string connectionString)
|
||||
public void Initialise(string connectionString)
|
||||
{
|
||||
m_connectionString = connectionString;
|
||||
|
||||
@@ -113,7 +113,7 @@ namespace OpenSim.Data.MySQL
|
||||
|
||||
public void Dispose() {}
|
||||
|
||||
public virtual void StoreObject(SceneObjectGroup obj, UUID regionUUID)
|
||||
public void StoreObject(SceneObjectGroup obj, UUID regionUUID)
|
||||
{
|
||||
uint flags = obj.RootPart.GetEffectiveObjectFlags();
|
||||
|
||||
@@ -241,7 +241,7 @@ namespace OpenSim.Data.MySQL
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void RemoveObject(UUID obj, UUID regionUUID)
|
||||
public void RemoveObject(UUID obj, UUID regionUUID)
|
||||
{
|
||||
// m_log.DebugFormat("[REGION DB]: Deleting scene object {0} from {1} in database", obj, regionUUID);
|
||||
|
||||
@@ -390,7 +390,7 @@ namespace OpenSim.Data.MySQL
|
||||
}
|
||||
}
|
||||
|
||||
public virtual List<SceneObjectGroup> LoadObjects(UUID regionID)
|
||||
public List<SceneObjectGroup> LoadObjects(UUID regionID)
|
||||
{
|
||||
const int ROWS_PER_QUERY = 5000;
|
||||
|
||||
@@ -559,7 +559,7 @@ namespace OpenSim.Data.MySQL
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void StoreTerrain(double[,] ter, UUID regionID)
|
||||
public void StoreTerrain(double[,] ter, UUID regionID)
|
||||
{
|
||||
m_log.Info("[REGION DB]: Storing terrain");
|
||||
|
||||
@@ -588,7 +588,7 @@ namespace OpenSim.Data.MySQL
|
||||
}
|
||||
}
|
||||
|
||||
public virtual double[,] LoadTerrain(UUID regionID)
|
||||
public double[,] LoadTerrain(UUID regionID)
|
||||
{
|
||||
double[,] terrain = null;
|
||||
|
||||
@@ -638,7 +638,7 @@ namespace OpenSim.Data.MySQL
|
||||
return terrain;
|
||||
}
|
||||
|
||||
public virtual void RemoveLandObject(UUID globalID)
|
||||
public void RemoveLandObject(UUID globalID)
|
||||
{
|
||||
lock (m_dbLock)
|
||||
{
|
||||
@@ -657,7 +657,7 @@ namespace OpenSim.Data.MySQL
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void StoreLandObject(ILandObject parcel)
|
||||
public void StoreLandObject(ILandObject parcel)
|
||||
{
|
||||
lock (m_dbLock)
|
||||
{
|
||||
@@ -714,7 +714,7 @@ namespace OpenSim.Data.MySQL
|
||||
}
|
||||
}
|
||||
|
||||
public virtual RegionLightShareData LoadRegionWindlightSettings(UUID regionUUID)
|
||||
public RegionLightShareData LoadRegionWindlightSettings(UUID regionUUID)
|
||||
{
|
||||
RegionLightShareData nWP = new RegionLightShareData();
|
||||
nWP.OnSave += StoreRegionWindlightSettings;
|
||||
@@ -736,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
|
||||
@@ -811,7 +811,7 @@ namespace OpenSim.Data.MySQL
|
||||
return nWP;
|
||||
}
|
||||
|
||||
public virtual RegionSettings LoadRegionSettings(UUID regionUUID)
|
||||
public RegionSettings LoadRegionSettings(UUID regionUUID)
|
||||
{
|
||||
RegionSettings rs = null;
|
||||
|
||||
@@ -849,7 +849,7 @@ namespace OpenSim.Data.MySQL
|
||||
return rs;
|
||||
}
|
||||
|
||||
public virtual void StoreRegionWindlightSettings(RegionLightShareData wl)
|
||||
public void StoreRegionWindlightSettings(RegionLightShareData wl)
|
||||
{
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
@@ -952,7 +952,7 @@ namespace OpenSim.Data.MySQL
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void RemoveRegionWindlightSettings(UUID regionID)
|
||||
public void RemoveRegionWindlightSettings(UUID regionID)
|
||||
{
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
@@ -967,7 +967,7 @@ namespace OpenSim.Data.MySQL
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void StoreRegionSettings(RegionSettings rs)
|
||||
public void StoreRegionSettings(RegionSettings rs)
|
||||
{
|
||||
lock (m_dbLock)
|
||||
{
|
||||
@@ -994,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, block_search, casino) values (?RegionUUID, ?BlockTerraform, " +
|
||||
"loaded_creation_id, map_tile_ID) values (?RegionUUID, ?BlockTerraform, " +
|
||||
"?BlockFly, ?AllowDamage, ?RestrictPushing, " +
|
||||
"?AllowLandResell, ?AllowLandJoinDivide, " +
|
||||
"?BlockShowInSearch, ?AgentLimit, ?ObjectBonus, " +
|
||||
@@ -1009,7 +1009,7 @@ namespace OpenSim.Data.MySQL
|
||||
"?SunPosition, ?Covenant, ?Sandbox, " +
|
||||
"?SunVectorX, ?SunVectorY, ?SunVectorZ, " +
|
||||
"?LoadedCreationDateTime, ?LoadedCreationID, " +
|
||||
"?TerrainImageID, ?block_search, ?casino)";
|
||||
"?TerrainImageID)";
|
||||
|
||||
FillRegionSettingsCommand(cmd, rs);
|
||||
|
||||
@@ -1019,7 +1019,7 @@ namespace OpenSim.Data.MySQL
|
||||
}
|
||||
}
|
||||
|
||||
public virtual List<LandData> LoadLandObjects(UUID regionUUID)
|
||||
public List<LandData> LoadLandObjects(UUID regionUUID)
|
||||
{
|
||||
List<LandData> landData = new List<LandData>();
|
||||
|
||||
@@ -1297,9 +1297,6 @@ 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;
|
||||
}
|
||||
|
||||
@@ -1629,8 +1626,6 @@ 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);
|
||||
|
||||
}
|
||||
|
||||
@@ -1789,7 +1784,7 @@ namespace OpenSim.Data.MySQL
|
||||
cmd.Parameters.AddWithValue("Media", null == s.Media ? null : s.Media.ToXml());
|
||||
}
|
||||
|
||||
public virtual void StorePrimInventory(UUID primID, ICollection<TaskInventoryItem> items)
|
||||
public void StorePrimInventory(UUID primID, ICollection<TaskInventoryItem> items)
|
||||
{
|
||||
lock (m_dbLock)
|
||||
{
|
||||
|
||||
@@ -46,21 +46,17 @@ namespace OpenSim.Data.MySQL
|
||||
{
|
||||
string[] words = query.Split(new char[] {' '});
|
||||
|
||||
bool valid = false;
|
||||
|
||||
for (int i = 0 ; i < words.Length ; i++)
|
||||
{
|
||||
if (words[i].Length > 2)
|
||||
valid = true;
|
||||
// if (words[i].Length < 3)
|
||||
// {
|
||||
// if (i != words.Length - 1)
|
||||
// Array.Copy(words, i + 1, words, i, words.Length - i - 1);
|
||||
// Array.Resize(ref words, words.Length - 1);
|
||||
// }
|
||||
if (words[i].Length < 3)
|
||||
{
|
||||
if (i != words.Length - 1)
|
||||
Array.Copy(words, i + 1, words, i, words.Length - i - 1);
|
||||
Array.Resize(ref words, words.Length - 1);
|
||||
}
|
||||
}
|
||||
|
||||
if ((!valid) || words.Length == 0)
|
||||
if (words.Length == 0)
|
||||
return new UserAccountData[0];
|
||||
|
||||
if (words.Length > 2)
|
||||
@@ -70,34 +66,19 @@ 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) and active=1", m_Realm);
|
||||
cmd.Parameters.AddWithValue("?search", words[0] + "%");
|
||||
cmd.CommandText = String.Format("select * from {0} where (ScopeID=?ScopeID or ScopeID='00000000-0000-0000-0000-000000000000') and (FirstName like ?search or LastName like ?search)", m_Realm);
|
||||
cmd.Parameters.AddWithValue("?search", "%" + words[0] + "%");
|
||||
cmd.Parameters.AddWithValue("?ScopeID", scopeID.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
cmd.CommandText = String.Format("select * from {0} where (ScopeID=?ScopeID or ScopeID='00000000-0000-0000-0000-000000000000') and (FirstName like ?searchFirst and LastName like ?searchLast) and active=1", m_Realm);
|
||||
cmd.Parameters.AddWithValue("?searchFirst", words[0] + "%");
|
||||
cmd.Parameters.AddWithValue("?searchLast", words[1] + "%");
|
||||
cmd.CommandText = String.Format("select * from {0} where (ScopeID=?ScopeID or ScopeID='00000000-0000-0000-0000-000000000000') and (FirstName like ?searchFirst or LastName like ?searchLast)", m_Realm);
|
||||
cmd.Parameters.AddWithValue("?searchFirst", "%" + words[0] + "%");
|
||||
cmd.Parameters.AddWithValue("?searchLast", "%" + words[1] + "%");
|
||||
cmd.Parameters.AddWithValue("?ScopeID", scopeID.ToString());
|
||||
}
|
||||
|
||||
return DoQuery(cmd);
|
||||
}
|
||||
|
||||
public UserAccountData[] GetUsersWhere(UUID scopeID, string where)
|
||||
{
|
||||
MySqlCommand cmd = new MySqlCommand();
|
||||
|
||||
if (scopeID != UUID.Zero)
|
||||
{
|
||||
where = "(ScopeID=?ScopeID or ScopeID='00000000-0000-0000-0000-000000000000') and (" + where + ")";
|
||||
cmd.Parameters.AddWithValue("?ScopeID", scopeID.ToString());
|
||||
}
|
||||
|
||||
cmd.CommandText = String.Format("select * from {0} where " + where, m_Realm);
|
||||
|
||||
return DoQuery(cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -717,7 +717,7 @@ ALTER TABLE regionsettings ADD COLUMN loaded_creation_datetime int unsigned NOT
|
||||
|
||||
COMMIT;
|
||||
|
||||
:VERSION 32 #---------------------
|
||||
:VERSION 32
|
||||
|
||||
BEGIN;
|
||||
CREATE TABLE `regionwindlight` (
|
||||
|
||||
@@ -193,10 +193,5 @@ namespace OpenSim.Data.Null
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public UserAccountData[] GetUsersWhere(UUID scopeID, string where)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,7 +128,7 @@ namespace OpenSim.Data.SQLite
|
||||
/// Create an asset
|
||||
/// </summary>
|
||||
/// <param name="asset">Asset Base</param>
|
||||
override public bool StoreAsset(AssetBase asset)
|
||||
override public void StoreAsset(AssetBase asset)
|
||||
{
|
||||
//m_log.Info("[ASSET DB]: Creating Asset " + asset.FullID.ToString());
|
||||
if (ExistsAsset(asset.FullID))
|
||||
@@ -150,7 +150,6 @@ namespace OpenSim.Data.SQLite
|
||||
cmd.Parameters.Add(new SqliteParameter(":Data", asset.Data));
|
||||
|
||||
cmd.ExecuteNonQuery();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -171,7 +170,6 @@ namespace OpenSim.Data.SQLite
|
||||
cmd.Parameters.Add(new SqliteParameter(":Data", asset.Data));
|
||||
|
||||
cmd.ExecuteNonQuery();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,10 +81,5 @@ namespace OpenSim.Data.SQLite
|
||||
|
||||
return DoQuery(cmd);
|
||||
}
|
||||
|
||||
public UserAccountData[] GetUsersWhere(UUID scopeID, string where)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -297,6 +297,7 @@ namespace OpenSim.Data.Tests
|
||||
pbshap.ProfileEnd = ushort.MaxValue;
|
||||
pbshap.ProfileHollow = ushort.MaxValue;
|
||||
Vector3 scale = new Vector3(random.Next(),random.Next(),random.Next());
|
||||
byte updatef = (byte) random.Next(127);
|
||||
|
||||
RegionInfo regionInfo = new RegionInfo();
|
||||
regionInfo.RegionID = region3;
|
||||
@@ -335,6 +336,7 @@ namespace OpenSim.Data.Tests
|
||||
sop.LinkNum = linknum;
|
||||
sop.ClickAction = clickaction;
|
||||
sop.Scale = scale;
|
||||
sop.UpdateFlag = updatef;
|
||||
|
||||
//Tests if local part accepted the parameters:
|
||||
Assert.That(regionh,Is.EqualTo(sop.RegionHandle), "Assert.That(regionh,Is.EqualTo(sop.RegionHandle))");
|
||||
@@ -367,6 +369,7 @@ namespace OpenSim.Data.Tests
|
||||
Assert.That(linknum,Is.EqualTo(sop.LinkNum), "Assert.That(linknum,Is.EqualTo(sop.LinkNum))");
|
||||
Assert.That(clickaction,Is.EqualTo(sop.ClickAction), "Assert.That(clickaction,Is.EqualTo(sop.ClickAction))");
|
||||
Assert.That(scale,Is.EqualTo(sop.Scale), "Assert.That(scale,Is.EqualTo(sop.Scale))");
|
||||
Assert.That(updatef,Is.EqualTo(sop.UpdateFlag), "Assert.That(updatef,Is.EqualTo(sop.UpdateFlag))");
|
||||
|
||||
// This is necessary or object will not be inserted in DB
|
||||
sop.Flags = PrimFlags.None;
|
||||
@@ -466,6 +469,7 @@ namespace OpenSim.Data.Tests
|
||||
PrimitiveBaseShape pbshap = new PrimitiveBaseShape();
|
||||
pbshap = PrimitiveBaseShape.Default;
|
||||
Vector3 scale = new Vector3(random.Next(),random.Next(),random.Next());
|
||||
byte updatef = (byte) random.Next(127);
|
||||
|
||||
// Updates the region with new values
|
||||
SceneObjectGroup sog2 = FindSOG("Adam West", region3);
|
||||
@@ -495,6 +499,7 @@ namespace OpenSim.Data.Tests
|
||||
sog2.RootPart.LinkNum = linknum;
|
||||
sog2.RootPart.ClickAction = clickaction;
|
||||
sog2.RootPart.Scale = scale;
|
||||
sog2.RootPart.UpdateFlag = updatef;
|
||||
|
||||
db.StoreObject(sog2, region3);
|
||||
List<SceneObjectGroup> sogs = db.LoadObjects(region3);
|
||||
|
||||
@@ -311,7 +311,7 @@ namespace OpenSim.Framework
|
||||
if (args.ContainsKey("packed_appearance") && (args["packed_appearance"].Type == OSDType.Map))
|
||||
{
|
||||
Appearance.Unpack((OSDMap)args["packed_appearance"]);
|
||||
m_log.InfoFormat("[AGENTCIRCUITDATA] unpacked appearance");
|
||||
// m_log.InfoFormat("[AGENTCIRCUITDATA] unpacked appearance");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -60,8 +60,6 @@ namespace OpenSim.Framework
|
||||
/// </summary>
|
||||
private AssetMetadata m_metadata;
|
||||
|
||||
private int m_uploadAttempts;
|
||||
|
||||
// This is needed for .NET serialization!!!
|
||||
// Do NOT "Optimize" away!
|
||||
public AssetBase()
|
||||
@@ -200,12 +198,6 @@ namespace OpenSim.Framework
|
||||
set { m_metadata.Type = value; }
|
||||
}
|
||||
|
||||
public int UploadAttempts
|
||||
{
|
||||
get { return m_uploadAttempts; }
|
||||
set { m_uploadAttempts = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is this a region only asset, or does this exist on the asset server also
|
||||
/// </summary>
|
||||
|
||||
@@ -53,6 +53,7 @@ namespace OpenSim.Framework
|
||||
protected AvatarWearable[] m_wearables;
|
||||
protected Dictionary<int, List<AvatarAttachment>> m_attachments;
|
||||
protected float m_avatarHeight = 0;
|
||||
protected float m_hipOffset = 0;
|
||||
|
||||
public virtual int Serial
|
||||
{
|
||||
@@ -88,6 +89,11 @@ namespace OpenSim.Framework
|
||||
set { m_avatarHeight = value; }
|
||||
}
|
||||
|
||||
public virtual float HipOffset
|
||||
{
|
||||
get { return m_hipOffset; }
|
||||
}
|
||||
|
||||
public AvatarAppearance()
|
||||
{
|
||||
// m_log.WarnFormat("[AVATAR APPEARANCE]: create empty appearance");
|
||||
@@ -178,6 +184,7 @@ namespace OpenSim.Framework
|
||||
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>>();
|
||||
@@ -240,21 +247,6 @@ namespace OpenSim.Framework
|
||||
// }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invalidate all of the baked textures in the appearance, useful
|
||||
/// if you know that none are valid
|
||||
/// </summary>
|
||||
public virtual void ResetBakedTextures()
|
||||
{
|
||||
SetDefaultTexture();
|
||||
|
||||
//for (int i = 0; i < BAKE_INDICES.Length; i++)
|
||||
// {
|
||||
// int idx = BAKE_INDICES[i];
|
||||
// m_texture.FaceTextures[idx].TextureID = UUID.Zero;
|
||||
// }
|
||||
}
|
||||
|
||||
protected virtual void SetDefaultTexture()
|
||||
{
|
||||
m_texture = new Primitive.TextureEntry(new UUID(AppearanceManager.DEFAULT_AVATAR_TEXTURE));
|
||||
@@ -340,18 +332,20 @@ namespace OpenSim.Framework
|
||||
|
||||
public virtual void SetHeight()
|
||||
{
|
||||
// Start with shortest possible female avatar height
|
||||
m_avatarHeight = 1.14597f;
|
||||
// Add offset for male avatars
|
||||
if (m_visualparams[(int)VPElement.SHAPE_MALE] != 0)
|
||||
m_avatarHeight += 0.0848f;
|
||||
// Add offsets for visual params
|
||||
m_avatarHeight += 0.516945f * (float)m_visualparams[(int)VPElement.SHAPE_HEIGHT] / 255.0f
|
||||
+ 0.08117f * (float)m_visualparams[(int)VPElement.SHAPE_HEAD_SIZE] / 255.0f
|
||||
+ 0.3836f * (float)m_visualparams[(int)VPElement.SHAPE_LEG_LENGTH] / 255.0f
|
||||
+ 0.07f * (float)m_visualparams[(int)VPElement.SHOES_PLATFORM_HEIGHT] / 255.0f
|
||||
+ 0.08f * (float)m_visualparams[(int)VPElement.SHOES_HEEL_HEIGHT] / 255.0f
|
||||
+ 0.076f * (float)m_visualparams[(int)VPElement.SHAPE_NECK_LENGTH] / 255.0f;
|
||||
m_avatarHeight = 1.23077f // Shortest possible avatar height
|
||||
+ 0.516945f * (float)m_visualparams[(int)VPElement.SHAPE_HEIGHT] / 255.0f // Body height
|
||||
+ 0.072514f * (float)m_visualparams[(int)VPElement.SHAPE_HEAD_SIZE] / 255.0f // Head size
|
||||
+ 0.3836f * (float)m_visualparams[(int)VPElement.SHAPE_LEG_LENGTH] / 255.0f // Leg length
|
||||
+ 0.08f * (float)m_visualparams[(int)VPElement.SHOES_PLATFORM_HEIGHT] / 255.0f // Shoe platform height
|
||||
+ 0.07f * (float)m_visualparams[(int)VPElement.SHOES_HEEL_HEIGHT] / 255.0f // Shoe heel height
|
||||
+ 0.076f * (float)m_visualparams[(int)VPElement.SHAPE_NECK_LENGTH] / 255.0f; // Neck length
|
||||
|
||||
m_hipOffset = (((1.23077f // Half of avatar
|
||||
+ 0.516945f * (float)m_visualparams[(int)VPElement.SHAPE_HEIGHT] / 255.0f // Body height
|
||||
+ 0.3836f * (float)m_visualparams[(int)VPElement.SHAPE_LEG_LENGTH] / 255.0f // Leg length
|
||||
+ 0.08f * (float)m_visualparams[(int)VPElement.SHOES_PLATFORM_HEIGHT] / 255.0f // Shoe platform height
|
||||
+ 0.07f * (float)m_visualparams[(int)VPElement.SHOES_HEEL_HEIGHT] / 255.0f // Shoe heel height
|
||||
) / 2) - m_avatarHeight / 2) * 0.31f - 0.0425f;
|
||||
}
|
||||
|
||||
public virtual void SetWearable(int wearableId, AvatarWearable wearable)
|
||||
@@ -398,18 +392,19 @@ namespace OpenSim.Framework
|
||||
/// </remarks>
|
||||
public List<AvatarAttachment> GetAttachments()
|
||||
{
|
||||
|
||||
List<AvatarAttachment> alist = new List<AvatarAttachment>();
|
||||
|
||||
lock (m_attachments)
|
||||
{
|
||||
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)
|
||||
{
|
||||
@@ -538,6 +533,7 @@ namespace OpenSim.Framework
|
||||
return kvp.Key;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -582,6 +578,7 @@ namespace OpenSim.Framework
|
||||
|
||||
data["serial"] = OSD.FromInteger(m_serial);
|
||||
data["height"] = OSD.FromReal(m_avatarHeight);
|
||||
data["hipoffset"] = OSD.FromReal(m_hipOffset);
|
||||
|
||||
// Wearables
|
||||
OSDArray wears = new OSDArray(AvatarWearable.MAX_WEARABLES);
|
||||
@@ -604,14 +601,12 @@ namespace OpenSim.Framework
|
||||
OSDBinary visualparams = new OSDBinary(m_visualparams);
|
||||
data["visualparams"] = visualparams;
|
||||
|
||||
lock (m_attachments)
|
||||
{
|
||||
// Attachments
|
||||
OSDArray attachs = new OSDArray(m_attachments.Count);
|
||||
foreach (AvatarAttachment attach in GetAttachments())
|
||||
attachs.Add(attach.Pack());
|
||||
data["attachments"] = attachs;
|
||||
}
|
||||
// Attachments
|
||||
List<AvatarAttachment> attachments = GetAttachments();
|
||||
OSDArray attachs = new OSDArray(attachments.Count);
|
||||
foreach (AvatarAttachment attach in GetAttachments())
|
||||
attachs.Add(attach.Pack());
|
||||
data["attachments"] = attachs;
|
||||
|
||||
return data;
|
||||
}
|
||||
@@ -626,6 +621,8 @@ namespace OpenSim.Framework
|
||||
m_serial = data["serial"].AsInteger();
|
||||
if ((data != null) && (data["height"] != null))
|
||||
m_avatarHeight = (float)data["height"].AsReal();
|
||||
if ((data != null) && (data["hipoffset"] != null))
|
||||
m_hipOffset = (float)data["hipoffset"].AsReal();
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
@@ -335,7 +335,7 @@ namespace OpenSim.Framework
|
||||
|
||||
public virtual OSDMap Pack()
|
||||
{
|
||||
m_log.InfoFormat("[CHILDAGENTDATAUPDATE] Pack data");
|
||||
// m_log.InfoFormat("[CHILDAGENTDATAUPDATE] Pack data");
|
||||
|
||||
OSDMap args = new OSDMap();
|
||||
args["message_type"] = OSD.FromString("AgentData");
|
||||
|
||||
@@ -363,7 +363,7 @@ namespace OpenSim.Framework.Communications
|
||||
_request = (HttpWebRequest) WebRequest.Create(buildUri());
|
||||
_request.KeepAlive = false;
|
||||
_request.ContentType = "application/xml";
|
||||
_request.Timeout = 30000;
|
||||
_request.Timeout = 900000;
|
||||
_request.Method = RequestMethod;
|
||||
_asyncException = null;
|
||||
_request.ContentLength = src.Length;
|
||||
|
||||
@@ -565,7 +565,7 @@ namespace OpenSim.Framework.Console
|
||||
/// </summary>
|
||||
public class CommandConsole : ConsoleBase, ICommandConsole
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
public ICommands Commands { get; private set; }
|
||||
|
||||
|
||||
@@ -58,30 +58,6 @@ namespace OpenSim.Framework
|
||||
set { m_EstateName = value; }
|
||||
}
|
||||
|
||||
private bool m_AllowLandmark = true;
|
||||
|
||||
public bool AllowLandmark
|
||||
{
|
||||
get { return m_AllowLandmark; }
|
||||
set { m_AllowLandmark = value; }
|
||||
}
|
||||
|
||||
private bool m_AllowParcelChanges = true;
|
||||
|
||||
public bool AllowParcelChanges
|
||||
{
|
||||
get { return m_AllowParcelChanges; }
|
||||
set { m_AllowParcelChanges = value; }
|
||||
}
|
||||
|
||||
private bool m_AllowSetHome = true;
|
||||
|
||||
public bool AllowSetHome
|
||||
{
|
||||
get { return m_AllowSetHome; }
|
||||
set { m_AllowSetHome = value; }
|
||||
}
|
||||
|
||||
private uint m_ParentEstateID = 1;
|
||||
|
||||
public uint ParentEstateID
|
||||
@@ -362,30 +338,11 @@ namespace OpenSim.Framework
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool IsBanned(UUID avatarID, int userFlags)
|
||||
public bool IsBanned(UUID avatarID)
|
||||
{
|
||||
foreach (EstateBan ban in l_EstateBans)
|
||||
if (ban.BannedUserID == avatarID)
|
||||
return true;
|
||||
|
||||
if (!IsEstateManager(avatarID) && !HasAccess(avatarID))
|
||||
{
|
||||
if (DenyMinors)
|
||||
{
|
||||
if ((userFlags & 32) == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (DenyAnonymous)
|
||||
{
|
||||
if ((userFlags & 4) == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -393,7 +350,7 @@ namespace OpenSim.Framework
|
||||
{
|
||||
if (ban == null)
|
||||
return;
|
||||
if (!IsBanned(ban.BannedUserID, 32)) //Ignore age-based bans
|
||||
if (!IsBanned(ban.BannedUserID))
|
||||
l_EstateBans.Add(ban);
|
||||
}
|
||||
|
||||
@@ -416,14 +373,5 @@ namespace OpenSim.Framework
|
||||
|
||||
return l_EstateAccess.Contains(user);
|
||||
}
|
||||
|
||||
public void SetFromFlags(ulong regionFlags)
|
||||
{
|
||||
ResetHomeOnTeleport = ((regionFlags & (ulong)RegionFlags.ResetHomeOnTeleport) == (ulong)RegionFlags.ResetHomeOnTeleport);
|
||||
BlockDwell = ((regionFlags & (ulong)RegionFlags.BlockDwell) == (ulong)RegionFlags.BlockDwell);
|
||||
AllowLandmark = ((regionFlags & (ulong)RegionFlags.AllowLandmark) == (ulong)RegionFlags.AllowLandmark);
|
||||
AllowParcelChanges = ((regionFlags & (ulong)RegionFlags.AllowParcelChanges) == (ulong)RegionFlags.AllowParcelChanges);
|
||||
AllowSetHome = ((regionFlags & (ulong)RegionFlags.AllowSetHome) == (ulong)RegionFlags.AllowSetHome);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
|
||||
namespace OpenSim.Framework
|
||||
{
|
||||
public interface ICallingCardModule
|
||||
{
|
||||
UUID CreateCallingCard(UUID userID, UUID creatorID, UUID folderID);
|
||||
}
|
||||
}
|
||||
@@ -53,7 +53,8 @@ namespace OpenSim.Framework
|
||||
|
||||
public delegate ISceneEntity RezSingleAttachmentFromInv(IClientAPI remoteClient, UUID itemID, uint AttachmentPt);
|
||||
|
||||
public delegate void RezMultipleAttachmentsFromInv(IClientAPI remoteClient, List<KeyValuePair<UUID, uint>> rezlist );
|
||||
public delegate void RezMultipleAttachmentsFromInv(IClientAPI remoteClient, RezMultipleAttachmentsFromInvPacket.HeaderDataBlock header,
|
||||
RezMultipleAttachmentsFromInvPacket.ObjectDataBlock[] objects);
|
||||
|
||||
public delegate void ObjectAttach(
|
||||
IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, bool silent);
|
||||
@@ -264,9 +265,6 @@ namespace OpenSim.Framework
|
||||
public delegate void MoveInventoryItem(
|
||||
IClientAPI remoteClient, List<InventoryItemBase> items);
|
||||
|
||||
public delegate void MoveItemsAndLeaveCopy(
|
||||
IClientAPI remoteClient, List<InventoryItemBase> items, UUID destFolder);
|
||||
|
||||
public delegate void RemoveInventoryItem(
|
||||
IClientAPI remoteClient, List<UUID> itemIDs);
|
||||
|
||||
@@ -440,7 +438,6 @@ namespace OpenSim.Framework
|
||||
public delegate void ClassifiedInfoRequest(UUID classifiedID, IClientAPI client);
|
||||
public delegate void ClassifiedInfoUpdate(UUID classifiedID, uint category, string name, string description, UUID parcelID, uint parentEstate, UUID snapshotID, Vector3 globalPos, byte classifiedFlags, int price, IClientAPI client);
|
||||
public delegate void ClassifiedDelete(UUID classifiedID, IClientAPI client);
|
||||
public delegate void ClassifiedGodDelete(UUID classifiedID, UUID queryID, IClientAPI client);
|
||||
|
||||
public delegate void EventNotificationAddRequest(uint EventID, IClientAPI client);
|
||||
public delegate void EventNotificationRemoveRequest(uint EventID, IClientAPI client);
|
||||
@@ -463,9 +460,9 @@ namespace OpenSim.Framework
|
||||
|
||||
public delegate void AgentFOV(IClientAPI client, float verticalAngle);
|
||||
|
||||
public delegate void MuteListEntryUpdate(IClientAPI client, UUID MuteID, string Name, int type, uint flags);
|
||||
public delegate void MuteListEntryUpdate(IClientAPI client, UUID MuteID, string Name, int Flags,UUID AgentID);
|
||||
|
||||
public delegate void MuteListEntryRemove(IClientAPI client, UUID MuteID, string Name);
|
||||
public delegate void MuteListEntryRemove(IClientAPI client, UUID MuteID, string Name, UUID AgentID);
|
||||
|
||||
public delegate void AvatarInterestReply(IClientAPI client,UUID target, uint wantmask, string wanttext, uint skillsmask, string skillstext, string languages);
|
||||
|
||||
@@ -706,6 +703,12 @@ namespace OpenSim.Framework
|
||||
|
||||
UUID AgentId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The scene agent for this client. This will only be set if the client has an agent in a scene (i.e. if it
|
||||
/// is connected).
|
||||
/// </summary>
|
||||
ISceneAgent SceneAgent { get; }
|
||||
|
||||
UUID SessionId { get; }
|
||||
|
||||
UUID SecureSessionId { get; }
|
||||
@@ -849,7 +852,6 @@ namespace OpenSim.Framework
|
||||
event RequestTaskInventory OnRequestTaskInventory;
|
||||
event UpdateInventoryItem OnUpdateInventoryItem;
|
||||
event CopyInventoryItem OnCopyInventoryItem;
|
||||
event MoveItemsAndLeaveCopy OnMoveItemsAndLeaveCopy;
|
||||
event MoveInventoryItem OnMoveInventoryItem;
|
||||
event RemoveInventoryFolder OnRemoveInventoryFolder;
|
||||
event RemoveInventoryItem OnRemoveInventoryItem;
|
||||
@@ -968,7 +970,7 @@ namespace OpenSim.Framework
|
||||
event ClassifiedInfoRequest OnClassifiedInfoRequest;
|
||||
event ClassifiedInfoUpdate OnClassifiedInfoUpdate;
|
||||
event ClassifiedDelete OnClassifiedDelete;
|
||||
event ClassifiedGodDelete OnClassifiedGodDelete;
|
||||
event ClassifiedDelete OnClassifiedGodDelete;
|
||||
|
||||
event EventNotificationAddRequest OnEventNotificationAddRequest;
|
||||
event EventNotificationRemoveRequest OnEventNotificationRemoveRequest;
|
||||
@@ -1020,7 +1022,6 @@ namespace OpenSim.Framework
|
||||
void InPacket(object NewPack);
|
||||
void ProcessInPacket(Packet NewPack);
|
||||
void Close();
|
||||
void Close(bool sendStop);
|
||||
void Kick(string message);
|
||||
|
||||
/// <summary>
|
||||
@@ -1052,7 +1053,7 @@ namespace OpenSim.Framework
|
||||
/// </summary>
|
||||
/// <param name="regionHandle"></param>
|
||||
/// <param name="localID"></param>
|
||||
void SendKillObject(ulong regionHandle, List<uint> localID);
|
||||
void SendKillObject(ulong regionHandle, uint localID);
|
||||
|
||||
void SendAnimations(UUID[] animID, int[] seqs, UUID sourceAgentId, UUID[] objectIDs);
|
||||
void SendRegionHandshake(RegionInfo regionInfo, RegionHandshakeArgs args);
|
||||
|
||||
@@ -40,7 +40,6 @@ namespace OpenSim.Framework
|
||||
bool AmountCovered(IClientAPI client, int amount);
|
||||
void ApplyCharge(UUID agentID, int amount, string text);
|
||||
void ApplyUploadCharge(UUID agentID, int amount, string text);
|
||||
void MoveMoney(UUID fromUser, UUID toUser, int amount, string text);
|
||||
|
||||
int UploadCharge { get; }
|
||||
int GroupCreationCharge { get; }
|
||||
|
||||
@@ -68,12 +68,14 @@ namespace OpenSim.Framework
|
||||
event restart OnRestart;
|
||||
|
||||
/// <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.
|
||||
/// Add a new client and create a presence for it. All clients except initial login clients will 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);
|
||||
/// <returns>
|
||||
/// The scene agent if the new client was added or if an agent that already existed.</returns>
|
||||
ISceneAgent AddNewClient(IClientAPI client, PresenceType type);
|
||||
|
||||
/// <summary>
|
||||
/// Remove the given client from the scene.
|
||||
@@ -87,27 +89,30 @@ namespace OpenSim.Framework
|
||||
|
||||
string GetSimulatorVersion();
|
||||
|
||||
/// <summary>
|
||||
/// Is the agent denoted by the given agentID a child presence in this scene?
|
||||
/// </summary>
|
||||
///
|
||||
/// Used by ClientView when a 'kick everyone' or 'estate message' occurs
|
||||
///
|
||||
/// <param name="avatarID">AvatarID to lookup</param>
|
||||
/// <returns>true if the presence is a child agent, false if the presence is a root exception</returns>
|
||||
/// <exception cref="System.NullReferenceException">
|
||||
/// Thrown if the agent does not exist.
|
||||
/// </exception>
|
||||
bool PresenceChildStatus(UUID agentId);
|
||||
|
||||
bool TryGetScenePresence(UUID agentID, out object scenePresence);
|
||||
|
||||
T RequestModuleInterface<T>();
|
||||
T[] RequestModuleInterfaces<T>();
|
||||
|
||||
/// <summary>
|
||||
/// Register an interface to a region module. This allows module methods to be called directly as
|
||||
/// well as via events. If there is already a module registered for this interface, it is not replaced
|
||||
/// (is this the best behaviour?)
|
||||
/// </summary>
|
||||
/// <param name="mod"></param>
|
||||
void RegisterModuleInterface<M>(M mod);
|
||||
|
||||
void StackModuleInterface<M>(M mod);
|
||||
|
||||
/// <summary>
|
||||
/// For the given interface, retrieve the region module which implements it.
|
||||
/// </summary>
|
||||
/// <returns>null if there is no registered module implementing that interface</returns>
|
||||
T RequestModuleInterface<T>();
|
||||
|
||||
/// <summary>
|
||||
/// For the given interface, retrieve an array of region modules that implement it.
|
||||
/// </summary>
|
||||
/// <returns>an empty array if there are no registered modules implementing that interface</returns>
|
||||
T[] RequestModuleInterfaces<T>();
|
||||
|
||||
// void AddCommand(object module, string command, string shorthelp, string longhelp, CommandDelegate callback);
|
||||
|
||||
ISceneObject DeserializeObject(string representation);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
@@ -26,46 +26,50 @@
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Runtime.Remoting.Lifetime;
|
||||
using System.Threading;
|
||||
using System.Reflection;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Region.ScriptEngine.Interfaces;
|
||||
using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
|
||||
using integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
|
||||
using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
|
||||
using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
|
||||
using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
|
||||
using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
|
||||
using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
|
||||
using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
|
||||
using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
|
||||
|
||||
namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
|
||||
namespace OpenSim.Framework
|
||||
{
|
||||
public partial class ScriptBaseClass : MarshalByRefObject
|
||||
/// <summary>
|
||||
/// An agent in the scene.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Interface is a work in progress. Please feel free to add other required properties and methods.
|
||||
/// </remarks>
|
||||
public interface ISceneAgent : ISceneEntity
|
||||
{
|
||||
public ICM_Api m_CM_Functions;
|
||||
/// <value>
|
||||
/// The client controlling this presence
|
||||
/// </value>
|
||||
IClientAPI ControllingClient { get; }
|
||||
|
||||
public void ApiTypeCM(IScriptApi api)
|
||||
{
|
||||
if (!(api is ICM_Api))
|
||||
return;
|
||||
/// <summary>
|
||||
/// What type of presence is this? User, NPC, etc.
|
||||
/// </summary>
|
||||
PresenceType PresenceType { get; }
|
||||
|
||||
m_CM_Functions = (ICM_Api)api;
|
||||
}
|
||||
/// <summary>
|
||||
/// If true, then the agent has no avatar in the scene.
|
||||
/// The agent exists to relay data from a region that neighbours the current position of the user's avatar.
|
||||
/// Occasionally data is relayed, such as which a user clicks an item in a neighbouring region.
|
||||
/// </summary>
|
||||
bool IsChildAgent { get; }
|
||||
|
||||
public string cmDetectedCountry(int num)
|
||||
{
|
||||
return m_CM_Functions.cmDetectedCountry(num);
|
||||
}
|
||||
/// <summary>
|
||||
/// Avatar appearance data.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
// Because appearance setting is in a module, we actually need
|
||||
// to give it access to our appearance directly, otherwise we
|
||||
// get a synchronization issue.
|
||||
/// </remarks>
|
||||
AvatarAppearance Appearance { get; set; }
|
||||
|
||||
public string cmGetAgentCountry(key key)
|
||||
{
|
||||
return m_CM_Functions.cmGetAgentCountry(key);
|
||||
}
|
||||
/// <summary>
|
||||
/// Send initial scene data to the client controlling this agent
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This includes scene object data and the appearance data of other avatars.
|
||||
/// </remarks>
|
||||
void SendInitialDataToMe();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -34,6 +34,7 @@ namespace OpenSim.Framework
|
||||
string Name { get; set; }
|
||||
UUID UUID { get; }
|
||||
uint LocalId { get; }
|
||||
|
||||
Vector3 AbsolutePosition { get; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,12 @@ namespace OpenSim.Framework
|
||||
public interface ISceneObject
|
||||
{
|
||||
UUID UUID { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The owner of this object.
|
||||
/// </summary>
|
||||
UUID OwnerID { get; set; }
|
||||
|
||||
ISceneObject CloneForNewScene();
|
||||
string ToXml2();
|
||||
string ExtraToXmlString();
|
||||
|
||||
@@ -60,7 +60,7 @@ namespace OpenSim.Framework
|
||||
|
||||
private uint _flags = (uint) ParcelFlags.AllowFly | (uint) ParcelFlags.AllowLandmark |
|
||||
(uint) ParcelFlags.AllowAPrimitiveEntry |
|
||||
(uint) ParcelFlags.AllowDeedToGroup |
|
||||
(uint) ParcelFlags.AllowDeedToGroup | (uint) ParcelFlags.AllowTerraform |
|
||||
(uint) ParcelFlags.CreateObjects | (uint) ParcelFlags.AllowOtherScripts |
|
||||
(uint) ParcelFlags.SoundLocal;
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
namespace OpenSim.Framework
|
||||
{
|
||||
public enum ParcelMediaCommandEnum : int
|
||||
public enum ParcelMediaCommandEnum
|
||||
{
|
||||
Stop = 0,
|
||||
Pause = 1,
|
||||
|
||||
@@ -244,22 +244,13 @@ namespace OpenSim.Framework
|
||||
// The Mono addin manager (in Mono.Addins.dll version 0.2.0.0)
|
||||
// occasionally seems to corrupt its addin cache
|
||||
// Hence, as a temporary solution we'll remove it before each startup
|
||||
|
||||
string customDir = Environment.GetEnvironmentVariable ("MONO_ADDINS_REGISTRY");
|
||||
string v0 = "addin-db-000";
|
||||
string v1 = "addin-db-001";
|
||||
if (customDir != null && customDir != String.Empty)
|
||||
{
|
||||
v0 = Path.Combine(customDir, v0);
|
||||
v1 = Path.Combine(customDir, v1);
|
||||
}
|
||||
try
|
||||
{
|
||||
if (Directory.Exists(v0))
|
||||
Directory.Delete(v0, true);
|
||||
if (Directory.Exists("addin-db-000"))
|
||||
Directory.Delete("addin-db-000", true);
|
||||
|
||||
if (Directory.Exists(v1))
|
||||
Directory.Delete(v1, true);
|
||||
if (Directory.Exists("addin-db-001"))
|
||||
Directory.Delete("addin-db-001", true);
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
|
||||
@@ -720,12 +720,7 @@ namespace OpenSim.Framework
|
||||
return _lightColorR;
|
||||
}
|
||||
set {
|
||||
if (value < 0)
|
||||
_lightColorR = 0;
|
||||
else if (value > 1.0f)
|
||||
_lightColorR = 1.0f;
|
||||
else
|
||||
_lightColorR = value;
|
||||
_lightColorR = value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -734,12 +729,7 @@ namespace OpenSim.Framework
|
||||
return _lightColorG;
|
||||
}
|
||||
set {
|
||||
if (value < 0)
|
||||
_lightColorG = 0;
|
||||
else if (value > 1.0f)
|
||||
_lightColorG = 1.0f;
|
||||
else
|
||||
_lightColorG = value;
|
||||
_lightColorG = value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -748,12 +738,7 @@ namespace OpenSim.Framework
|
||||
return _lightColorB;
|
||||
}
|
||||
set {
|
||||
if (value < 0)
|
||||
_lightColorB = 0;
|
||||
else if (value > 1.0f)
|
||||
_lightColorB = 1.0f;
|
||||
else
|
||||
_lightColorB = value;
|
||||
_lightColorB = value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -762,12 +747,7 @@ namespace OpenSim.Framework
|
||||
return _lightColorA;
|
||||
}
|
||||
set {
|
||||
if (value < 0)
|
||||
_lightColorA = 0;
|
||||
else if (value > 1.0f)
|
||||
_lightColorA = 1.0f;
|
||||
else
|
||||
_lightColorA = value;
|
||||
_lightColorA = value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1430,7 +1410,7 @@ namespace OpenSim.Framework
|
||||
prim.Textures = this.Textures;
|
||||
|
||||
prim.Properties = new Primitive.ObjectProperties();
|
||||
prim.Properties.Name = "Object";
|
||||
prim.Properties.Name = "Primitive";
|
||||
prim.Properties.Description = "";
|
||||
prim.Properties.CreatorID = UUID.Zero;
|
||||
prim.Properties.GroupID = UUID.Zero;
|
||||
|
||||
@@ -40,7 +40,6 @@ using OpenMetaverse.StructuredData;
|
||||
|
||||
namespace OpenSim.Framework
|
||||
{
|
||||
[Serializable]
|
||||
public class RegionLightShareData : ICloneable
|
||||
{
|
||||
public bool valid = false;
|
||||
@@ -103,7 +102,6 @@ namespace OpenSim.Framework
|
||||
|
||||
public bool commFailTF = false;
|
||||
public ConfigurationMember configMember;
|
||||
public string DataStore = String.Empty;
|
||||
public string RegionFile = String.Empty;
|
||||
public bool isSandbox = false;
|
||||
public bool Persistent = true;
|
||||
@@ -508,10 +506,6 @@ namespace OpenSim.Framework
|
||||
m_regionLocX = Convert.ToUInt32(locationElements[0]);
|
||||
m_regionLocY = Convert.ToUInt32(locationElements[1]);
|
||||
|
||||
|
||||
// Datastore (is this implemented? Omitted from example!)
|
||||
DataStore = config.GetString("Datastore", String.Empty);
|
||||
|
||||
// Internal IP
|
||||
IPAddress address;
|
||||
|
||||
@@ -610,9 +604,6 @@ namespace OpenSim.Framework
|
||||
string location = String.Format("{0},{1}", m_regionLocX, m_regionLocY);
|
||||
config.Set("Location", location);
|
||||
|
||||
if (DataStore != String.Empty)
|
||||
config.Set("Datastore", DataStore);
|
||||
|
||||
config.Set("InternalAddress", m_internalEndPoint.Address.ToString());
|
||||
config.Set("InternalPort", m_internalEndPoint.Port);
|
||||
|
||||
@@ -798,9 +789,6 @@ namespace OpenSim.Framework
|
||||
case "sim_location_y":
|
||||
m_regionLocY = (uint) configuration_result;
|
||||
break;
|
||||
case "datastore":
|
||||
DataStore = (string) configuration_result;
|
||||
break;
|
||||
case "internal_ip_address":
|
||||
IPAddress address = (IPAddress) configuration_result;
|
||||
m_internalEndPoint = new IPEndPoint(address, 0);
|
||||
@@ -951,11 +939,6 @@ namespace OpenSim.Framework
|
||||
return regionInfo;
|
||||
}
|
||||
|
||||
public int getInternalEndPointPort()
|
||||
{
|
||||
return m_internalEndPoint.Port;
|
||||
}
|
||||
|
||||
public Dictionary<string, object> ToKeyValuePairs()
|
||||
{
|
||||
Dictionary<string, object> kvp = new Dictionary<string, object>();
|
||||
@@ -974,4 +957,4 @@ namespace OpenSim.Framework
|
||||
return kvp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -48,13 +48,11 @@ namespace OpenSim.Framework.RegionLoader.Filesystem
|
||||
public RegionInfo[] LoadRegions()
|
||||
{
|
||||
string regionConfigPath = Path.Combine(Util.configDir(), "Regions");
|
||||
bool allowRegionless = false;
|
||||
|
||||
try
|
||||
{
|
||||
IConfig startupConfig = (IConfig)m_configSource.Configs["Startup"];
|
||||
regionConfigPath = startupConfig.GetString("regionload_regionsdir", regionConfigPath).Trim();
|
||||
allowRegionless = startupConfig.GetBoolean("allow_regionless", false);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
@@ -70,7 +68,7 @@ namespace OpenSim.Framework.RegionLoader.Filesystem
|
||||
string[] iniFiles = Directory.GetFiles(regionConfigPath, "*.ini");
|
||||
|
||||
// Create an empty Regions.ini if there are no existing config files.
|
||||
if (!allowRegionless && configFiles.Length == 0 && iniFiles.Length == 0)
|
||||
if (configFiles.Length == 0 && iniFiles.Length == 0)
|
||||
{
|
||||
new RegionInfo("DEFAULT REGION CONFIG", Path.Combine(regionConfigPath, "Regions.ini"), false, m_configSource);
|
||||
iniFiles = Directory.GetFiles(regionConfigPath, "*.ini");
|
||||
|
||||
@@ -48,9 +48,6 @@ namespace OpenSim.Framework.RegionLoader.Web
|
||||
|
||||
public RegionInfo[] LoadRegions()
|
||||
{
|
||||
int tries = 3;
|
||||
int wait = 2000;
|
||||
|
||||
if (m_configSource == null)
|
||||
{
|
||||
m_log.Error("[WEBLOADER]: Unable to load configuration source!");
|
||||
@@ -60,8 +57,6 @@ namespace OpenSim.Framework.RegionLoader.Web
|
||||
{
|
||||
IConfig startupConfig = (IConfig) m_configSource.Configs["Startup"];
|
||||
string url = startupConfig.GetString("regionload_webserver_url", String.Empty).Trim();
|
||||
bool allowRegionless = startupConfig.GetBoolean("allow_regionless", false);
|
||||
|
||||
if (url == String.Empty)
|
||||
{
|
||||
m_log.Error("[WEBLOADER]: Unable to load webserver URL - URL was empty.");
|
||||
@@ -69,72 +64,37 @@ namespace OpenSim.Framework.RegionLoader.Web
|
||||
}
|
||||
else
|
||||
{
|
||||
while(tries > 0)
|
||||
{
|
||||
RegionInfo[] regionInfos = new RegionInfo[] {};
|
||||
int regionCount = 0;
|
||||
HttpWebRequest webRequest = (HttpWebRequest) WebRequest.Create(url);
|
||||
webRequest.Timeout = 30000; //30 Second Timeout
|
||||
m_log.DebugFormat("[WEBLOADER]: Sending download request to {0}", url);
|
||||
|
||||
try
|
||||
{
|
||||
HttpWebResponse webResponse = (HttpWebResponse) webRequest.GetResponse();
|
||||
m_log.Debug("[WEBLOADER]: Downloading region information...");
|
||||
StreamReader reader = new StreamReader(webResponse.GetResponseStream());
|
||||
string xmlSource = String.Empty;
|
||||
string tempStr = reader.ReadLine();
|
||||
while (tempStr != null)
|
||||
{
|
||||
xmlSource = xmlSource + tempStr;
|
||||
tempStr = reader.ReadLine();
|
||||
}
|
||||
m_log.Debug("[WEBLOADER]: Done downloading region information from server. Total Bytes: " +
|
||||
xmlSource.Length);
|
||||
XmlDocument xmlDoc = new XmlDocument();
|
||||
xmlDoc.LoadXml(xmlSource);
|
||||
if (xmlDoc.FirstChild.Name == "Regions")
|
||||
{
|
||||
regionCount = xmlDoc.FirstChild.ChildNodes.Count;
|
||||
|
||||
if (regionCount > 0)
|
||||
{
|
||||
regionInfos = new RegionInfo[regionCount];
|
||||
int i;
|
||||
for (i = 0; i < xmlDoc.FirstChild.ChildNodes.Count; i++)
|
||||
{
|
||||
m_log.Debug(xmlDoc.FirstChild.ChildNodes[i].OuterXml);
|
||||
regionInfos[i] =
|
||||
new RegionInfo("REGION CONFIG #" + (i + 1), xmlDoc.FirstChild.ChildNodes[i],false,m_configSource);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (WebException ex)
|
||||
{
|
||||
if (((HttpWebResponse)ex.Response).StatusCode == HttpStatusCode.NotFound)
|
||||
{
|
||||
if (!allowRegionless)
|
||||
throw ex;
|
||||
}
|
||||
else
|
||||
throw ex;
|
||||
}
|
||||
|
||||
if (regionCount > 0 | allowRegionless)
|
||||
return regionInfos;
|
||||
|
||||
m_log.Debug("[WEBLOADER]: Request yielded no regions.");
|
||||
tries--;
|
||||
if (tries > 0)
|
||||
HttpWebRequest webRequest = (HttpWebRequest) WebRequest.Create(url);
|
||||
webRequest.Timeout = 30000; //30 Second Timeout
|
||||
m_log.DebugFormat("[WEBLOADER]: Sending download request to {0}", url);
|
||||
HttpWebResponse webResponse = (HttpWebResponse) webRequest.GetResponse();
|
||||
m_log.Debug("[WEBLOADER]: Downloading region information...");
|
||||
StreamReader reader = new StreamReader(webResponse.GetResponseStream());
|
||||
string xmlSource = String.Empty;
|
||||
string tempStr = reader.ReadLine();
|
||||
while (tempStr != null)
|
||||
{
|
||||
xmlSource = xmlSource + tempStr;
|
||||
tempStr = reader.ReadLine();
|
||||
}
|
||||
m_log.Debug("[WEBLOADER]: Done downloading region information from server. Total Bytes: " +
|
||||
xmlSource.Length);
|
||||
XmlDocument xmlDoc = new XmlDocument();
|
||||
xmlDoc.LoadXml(xmlSource);
|
||||
if (xmlDoc.FirstChild.Name == "Regions")
|
||||
{
|
||||
RegionInfo[] regionInfos = new RegionInfo[xmlDoc.FirstChild.ChildNodes.Count];
|
||||
int i;
|
||||
for (i = 0; i < xmlDoc.FirstChild.ChildNodes.Count; i++)
|
||||
{
|
||||
m_log.Debug("[WEBLOADER]: Retrying");
|
||||
System.Threading.Thread.Sleep(wait);
|
||||
m_log.Debug(xmlDoc.FirstChild.ChildNodes[i].OuterXml);
|
||||
regionInfos[i] =
|
||||
new RegionInfo("REGION CONFIG #" + (i + 1), xmlDoc.FirstChild.ChildNodes[i],false,m_configSource);
|
||||
}
|
||||
}
|
||||
|
||||
m_log.Error("[WEBLOADER]: No region configs were available.");
|
||||
return null;
|
||||
return regionInfos;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -397,18 +397,5 @@ 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; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -244,16 +244,16 @@ namespace OpenSim.Framework.Servers
|
||||
protected string GetThreadsReport()
|
||||
{
|
||||
// This should be a constant field.
|
||||
string reportFormat = "{0,6} {1,35} {2,16} {3,13} {4,10} {5,30}";
|
||||
string reportFormat = "{0,6} {1,35} {2,16} {3,10} {4,30}";
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
Watchdog.ThreadWatchdogInfo[] threads = Watchdog.GetThreads();
|
||||
|
||||
sb.Append(threads.Length + " threads are being tracked:" + Environment.NewLine);
|
||||
|
||||
int timeNow = Util.EnvironmentTickCount();
|
||||
int timeNow = Environment.TickCount & Int32.MaxValue;
|
||||
|
||||
sb.AppendFormat(reportFormat, "ID", "NAME", "LAST UPDATE (MS)", "LIFETIME (MS)", "PRIORITY", "STATE");
|
||||
sb.AppendFormat(reportFormat, "ID", "NAME", "LAST UPDATE (MS)", "PRIORITY", "STATE");
|
||||
sb.Append(Environment.NewLine);
|
||||
|
||||
foreach (Watchdog.ThreadWatchdogInfo twi in threads)
|
||||
@@ -262,12 +262,8 @@ namespace OpenSim.Framework.Servers
|
||||
|
||||
sb.AppendFormat(
|
||||
reportFormat,
|
||||
t.ManagedThreadId,
|
||||
t.Name,
|
||||
timeNow - twi.LastTick,
|
||||
timeNow - twi.FirstTick,
|
||||
t.Priority,
|
||||
t.ThreadState);
|
||||
//t.ManagedThreadId, t.Name, string.Format("{0} ms", timeNow - twi.LastTick), t.Priority, t.ThreadState);
|
||||
t.ManagedThreadId, t.Name, timeNow - twi.LastTick, t.Priority, t.ThreadState);
|
||||
|
||||
sb.Append(Environment.NewLine);
|
||||
}
|
||||
@@ -304,7 +300,7 @@ namespace OpenSim.Framework.Servers
|
||||
|
||||
EnhanceVersionInformation();
|
||||
|
||||
m_log.Info("[STARTUP]: Careminster version: " + m_version + Environment.NewLine);
|
||||
m_log.Info("[STARTUP]: OpenSimulator version: " + m_version + Environment.NewLine);
|
||||
// clr version potentially is more confusing than helpful, since it doesn't tell us if we're running under Mono/MS .NET and
|
||||
// the clr version number doesn't match the project version number under Mono.
|
||||
//m_log.Info("[STARTUP]: Virtual machine runtime version: " + Environment.Version + Environment.NewLine);
|
||||
|
||||
@@ -79,6 +79,11 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
|
||||
private PollServiceRequestManager m_PollServiceManager;
|
||||
|
||||
/// <summary>
|
||||
/// Control the printing of certain debug messages.
|
||||
/// </summary>
|
||||
public int DebugLevel { get; set; }
|
||||
|
||||
public uint SSLPort
|
||||
{
|
||||
get { return m_sslport; }
|
||||
@@ -442,17 +447,18 @@ 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);
|
||||
|
||||
if (TryGetStreamHandler(handlerKey, out requestHandler))
|
||||
{
|
||||
//m_log.Debug("[BASE HTTP SERVER]: Found Stream Handler");
|
||||
if (DebugLevel >= 1)
|
||||
m_log.DebugFormat(
|
||||
"[BASE HTTP SERVER]: Found stream handler for {0} {1}",
|
||||
request.HttpMethod, request.Url.PathAndQuery);
|
||||
|
||||
// Okay, so this is bad, but should be considered temporary until everything is IStreamHandler.
|
||||
byte[] buffer = null;
|
||||
|
||||
response.ContentType = requestHandler.ContentType; // Lets do this defaulting before in case handler has varying content type.
|
||||
|
||||
|
||||
if (requestHandler is IStreamedRequestHandler)
|
||||
{
|
||||
IStreamedRequestHandler streamedRequestHandler = requestHandler as IStreamedRequestHandler;
|
||||
@@ -480,7 +486,6 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
string[] querystringkeys = request.QueryString.AllKeys;
|
||||
string[] rHeaders = request.Headers.AllKeys;
|
||||
|
||||
|
||||
foreach (string queryname in querystringkeys)
|
||||
{
|
||||
keysvals.Add(queryname, request.QueryString[queryname]);
|
||||
@@ -556,6 +561,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
{
|
||||
m_log.Warn("[BASE HTTP SERVER]: XmlRpcRequest issue: " + e.Message);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -566,7 +572,11 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
if (strAccept.Contains("application/llsd+xml") ||
|
||||
strAccept.Contains("application/llsd+json"))
|
||||
{
|
||||
//m_log.Info("[Debug BASE HTTP SERVER]: Found an application/llsd+xml accept header");
|
||||
if (DebugLevel >= 1)
|
||||
m_log.DebugFormat(
|
||||
"[BASE HTTP SERVER]: Found application/llsd+xml accept header handler for {0} {1}",
|
||||
request.HttpMethod, request.Url.PathAndQuery);
|
||||
|
||||
HandleLLSDRequests(request, response);
|
||||
return;
|
||||
}
|
||||
@@ -577,15 +587,24 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
{
|
||||
case null:
|
||||
case "text/html":
|
||||
// m_log.DebugFormat(
|
||||
// "[BASE HTTP SERVER]: Found a text/html content type for request {0}", request.RawUrl);
|
||||
|
||||
if (DebugLevel >= 1)
|
||||
m_log.DebugFormat(
|
||||
"[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}",
|
||||
request.ContentType, request.HttpMethod, request.Url.PathAndQuery);
|
||||
|
||||
HandleHTTPRequest(request, response);
|
||||
return;
|
||||
|
||||
case "application/llsd+xml":
|
||||
case "application/xml+llsd":
|
||||
case "application/llsd+json":
|
||||
//m_log.Info("[Debug BASE HTTP SERVER]: found a application/llsd+xml content type");
|
||||
|
||||
if (DebugLevel >= 1)
|
||||
m_log.DebugFormat(
|
||||
"[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}",
|
||||
request.ContentType, request.HttpMethod, request.Url.PathAndQuery);
|
||||
|
||||
HandleLLSDRequests(request, response);
|
||||
return;
|
||||
|
||||
@@ -602,7 +621,11 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
//m_log.Info("[Debug BASE HTTP SERVER]: Checking for LLSD Handler");
|
||||
if (DoWeHaveALLSDHandler(request.RawUrl))
|
||||
{
|
||||
//m_log.Info("[Debug BASE HTTP SERVER]: Found LLSD Handler");
|
||||
if (DebugLevel >= 1)
|
||||
m_log.DebugFormat(
|
||||
"[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}",
|
||||
request.ContentType, request.HttpMethod, request.Url.PathAndQuery);
|
||||
|
||||
HandleLLSDRequests(request, response);
|
||||
return;
|
||||
}
|
||||
@@ -610,12 +633,20 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
// m_log.DebugFormat("[BASE HTTP SERVER]: Checking for HTTP Handler for request {0}", request.RawUrl);
|
||||
if (DoWeHaveAHTTPHandler(request.RawUrl))
|
||||
{
|
||||
// m_log.DebugFormat("[BASE HTTP SERVER]: Found HTTP Handler for request {0}", request.RawUrl);
|
||||
if (DebugLevel >= 1)
|
||||
m_log.DebugFormat(
|
||||
"[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}",
|
||||
request.ContentType, request.HttpMethod, request.Url.PathAndQuery);
|
||||
|
||||
HandleHTTPRequest(request, response);
|
||||
return;
|
||||
}
|
||||
|
||||
//m_log.Info("[Debug BASE HTTP SERVER]: Generic XMLRPC");
|
||||
if (DebugLevel >= 1)
|
||||
m_log.DebugFormat(
|
||||
"[BASE HTTP SERVER]: Assuming a generic XMLRPC request for {0} {1}",
|
||||
request.HttpMethod, request.Url.PathAndQuery);
|
||||
|
||||
// generic login request.
|
||||
HandleXmlRpcRequests(request, response);
|
||||
|
||||
@@ -872,7 +903,9 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
byte[] buf = Encoding.UTF8.GetBytes("Not found");
|
||||
response.KeepAlive = false;
|
||||
|
||||
m_log.ErrorFormat("[BASE HTTP SERVER]: Handler not found for http request {0}", request.RawUrl);
|
||||
m_log.ErrorFormat(
|
||||
"[BASE HTTP SERVER]: Handler not found for http request {0} {1}",
|
||||
request.HttpMethod, request.Url.PathAndQuery);
|
||||
|
||||
response.SendChunked = false;
|
||||
response.ContentLength64 = buf.Length;
|
||||
@@ -978,7 +1011,6 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
|
||||
if (llsdRequest != null)// && m_defaultLlsdHandler != null)
|
||||
{
|
||||
|
||||
LLSDMethod llsdhandler = null;
|
||||
|
||||
if (TryGetLLSDHandler(request.RawUrl, out llsdhandler) && !LegacyLLSDLoginLibOMV)
|
||||
@@ -1002,13 +1034,14 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
llsdResponse = GenerateNoLLSDHandlerResponse();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
llsdResponse = GenerateNoLLSDHandlerResponse();
|
||||
}
|
||||
|
||||
byte[] buffer = new byte[0];
|
||||
|
||||
if (llsdResponse.ToString() == "shutdown404!")
|
||||
{
|
||||
response.ContentType = "text/plain";
|
||||
@@ -1510,34 +1543,11 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
|
||||
internal void DoHTTPGruntWork(Hashtable responsedata, OSHttpResponse response)
|
||||
{
|
||||
int responsecode;
|
||||
string responseString;
|
||||
string contentType;
|
||||
//m_log.Info("[BASE HTTP SERVER]: Doing HTTP Grunt work with response");
|
||||
int responsecode = (int)responsedata["int_response_code"];
|
||||
string responseString = (string)responsedata["str_response_string"];
|
||||
string contentType = (string)responsedata["content_type"];
|
||||
|
||||
if (responsedata == null)
|
||||
{
|
||||
responsecode = 500;
|
||||
responseString = "No response could be obtained";
|
||||
contentType = "text/plain";
|
||||
responsedata = new Hashtable();
|
||||
}
|
||||
else
|
||||
{
|
||||
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"))
|
||||
{
|
||||
|
||||
@@ -44,6 +44,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
private uint m_WorkerThreadCount = 0;
|
||||
private Thread[] m_workerThreads;
|
||||
private PollServiceWorkerThread[] m_PollServiceWorkerThreads;
|
||||
private Thread m_watcherThread;
|
||||
private bool m_running = true;
|
||||
|
||||
public PollServiceRequestManager(BaseHttpServer pSrv, uint pWorkerThreadCount, int pTimeout)
|
||||
@@ -68,12 +69,13 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
int.MaxValue);
|
||||
}
|
||||
|
||||
Watchdog.StartThread(
|
||||
this.ThreadStart,
|
||||
"PollServiceWatcherThread",
|
||||
ThreadPriority.Normal,
|
||||
false,
|
||||
1000 * 60 * 10);
|
||||
m_watcherThread
|
||||
= Watchdog.StartThread(
|
||||
this.ThreadStart,
|
||||
"PollServiceWatcherThread",
|
||||
ThreadPriority.Normal,
|
||||
false,
|
||||
1000 * 60 * 10);
|
||||
}
|
||||
|
||||
internal void ReQueueEvent(PollServiceHttpRequest req)
|
||||
|
||||
@@ -29,11 +29,11 @@ namespace OpenSim
|
||||
{
|
||||
public class VersionInfo
|
||||
{
|
||||
private const string VERSION_NUMBER = "0.7.3CM";
|
||||
private const Flavour VERSION_FLAVOUR = Flavour.Dev;
|
||||
private const string VERSION_NUMBER = "0.7.2";
|
||||
private const Flavour VERSION_FLAVOUR = Flavour.Post_Fixes;
|
||||
|
||||
public enum Flavour
|
||||
{
|
||||
{
|
||||
Unknown,
|
||||
Dev,
|
||||
RC1,
|
||||
@@ -49,7 +49,7 @@ namespace OpenSim
|
||||
|
||||
public static string GetVersionString(string versionNumber, Flavour flavour)
|
||||
{
|
||||
string versionString = "Careminster " + versionNumber + " " + flavour;
|
||||
string versionString = "OpenSim " + versionNumber + " " + flavour;
|
||||
return versionString.PadRight(VERSIONINFO_VERSION_LENGTH);
|
||||
}
|
||||
|
||||
|
||||
@@ -27,13 +27,9 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Reflection;
|
||||
using System.Xml;
|
||||
using System.Diagnostics;
|
||||
using System.Xml.Schema;
|
||||
using System.Xml.Serialization;
|
||||
using log4net;
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace OpenSim.Framework
|
||||
@@ -49,155 +45,6 @@ namespace OpenSim.Framework
|
||||
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private static XmlSerializer tiiSerializer = new XmlSerializer(typeof (TaskInventoryItem));
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private Thread LockedByThread;
|
||||
private string WriterStack;
|
||||
|
||||
private Dictionary<Thread, string> ReadLockers =
|
||||
new Dictionary<Thread, string>();
|
||||
|
||||
/// <value>
|
||||
/// An advanced lock for inventory data
|
||||
/// </value>
|
||||
private System.Threading.ReaderWriterLockSlim m_itemLock = new System.Threading.ReaderWriterLockSlim();
|
||||
|
||||
/// <summary>
|
||||
/// Are we readlocked by the calling thread?
|
||||
/// </summary>
|
||||
public bool IsReadLockedByMe()
|
||||
{
|
||||
if (m_itemLock.RecursiveReadCount > 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Lock our inventory list for reading (many can read, one can write)
|
||||
/// </summary>
|
||||
public void LockItemsForRead(bool locked)
|
||||
{
|
||||
if (locked)
|
||||
{
|
||||
if (m_itemLock.IsWriteLockHeld && LockedByThread != null)
|
||||
{
|
||||
if (!LockedByThread.IsAlive)
|
||||
{
|
||||
//Locked by dead thread, reset.
|
||||
m_itemLock = new System.Threading.ReaderWriterLockSlim();
|
||||
}
|
||||
}
|
||||
|
||||
if (m_itemLock.RecursiveReadCount > 0)
|
||||
{
|
||||
m_log.Error("[TaskInventoryDictionary] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
|
||||
try
|
||||
{
|
||||
StackTrace stackTrace = new StackTrace(); // get call stack
|
||||
StackFrame[] stackFrames = stackTrace.GetFrames(); // get method calls (frames)
|
||||
|
||||
// write call stack method names
|
||||
foreach (StackFrame stackFrame in stackFrames)
|
||||
{
|
||||
m_log.Error("[SceneObjectGroup.m_parts] "+(stackFrame.GetMethod().Name)); // write method name
|
||||
}
|
||||
}
|
||||
catch
|
||||
{}
|
||||
m_itemLock.ExitReadLock();
|
||||
}
|
||||
if (m_itemLock.RecursiveWriteCount > 0)
|
||||
{
|
||||
m_log.Error("[TaskInventoryDictionary] Recursive write lock requested. This should not happen and means something needs to be fixed.");
|
||||
m_itemLock.ExitWriteLock();
|
||||
}
|
||||
|
||||
while (!m_itemLock.TryEnterReadLock(60000))
|
||||
{
|
||||
m_log.Error("Thread lock detected while trying to aquire READ lock in TaskInventoryDictionary. Locked by thread " + LockedByThread.Name + ". I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
|
||||
if (m_itemLock.IsWriteLockHeld)
|
||||
{
|
||||
m_itemLock = new System.Threading.ReaderWriterLockSlim();
|
||||
System.Console.WriteLine("------------------------------------------");
|
||||
System.Console.WriteLine("My call stack:\n" + Environment.StackTrace);
|
||||
System.Console.WriteLine("------------------------------------------");
|
||||
System.Console.WriteLine("Locker's call stack:\n" + WriterStack);
|
||||
System.Console.WriteLine("------------------------------------------");
|
||||
LockedByThread = null;
|
||||
ReadLockers.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_itemLock.RecursiveReadCount>0)
|
||||
{
|
||||
m_itemLock.ExitReadLock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Lock our inventory list for writing (many can read, one can write)
|
||||
/// </summary>
|
||||
public void LockItemsForWrite(bool locked)
|
||||
{
|
||||
if (locked)
|
||||
{
|
||||
//Enter a write lock, wait indefinately for one to open.
|
||||
if (m_itemLock.RecursiveReadCount > 0)
|
||||
{
|
||||
m_log.Error("[TaskInventoryDictionary] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
|
||||
m_itemLock.ExitReadLock();
|
||||
}
|
||||
if (m_itemLock.RecursiveWriteCount > 0)
|
||||
{
|
||||
m_log.Error("[TaskInventoryDictionary] Recursive write lock requested. This should not happen and means something needs to be fixed.");
|
||||
m_itemLock.ExitWriteLock();
|
||||
}
|
||||
while (!m_itemLock.TryEnterWriteLock(60000))
|
||||
{
|
||||
if (m_itemLock.IsWriteLockHeld)
|
||||
{
|
||||
m_log.Error("Thread lock detected while trying to aquire WRITE lock in TaskInventoryDictionary. Locked by thread " + LockedByThread.Name + ". I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
|
||||
System.Console.WriteLine("------------------------------------------");
|
||||
System.Console.WriteLine("My call stack:\n" + Environment.StackTrace);
|
||||
System.Console.WriteLine("------------------------------------------");
|
||||
System.Console.WriteLine("Locker's call stack:\n" + WriterStack);
|
||||
System.Console.WriteLine("------------------------------------------");
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.Error("Thread lock detected while trying to aquire WRITE lock in TaskInventoryDictionary. Locked by a reader. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
|
||||
System.Console.WriteLine("------------------------------------------");
|
||||
System.Console.WriteLine("My call stack:\n" + Environment.StackTrace);
|
||||
System.Console.WriteLine("------------------------------------------");
|
||||
foreach (KeyValuePair<Thread, string> kvp in ReadLockers)
|
||||
{
|
||||
System.Console.WriteLine("Locker name {0} call stack:\n" + kvp.Value, kvp.Key.Name);
|
||||
System.Console.WriteLine("------------------------------------------");
|
||||
}
|
||||
}
|
||||
m_itemLock = new System.Threading.ReaderWriterLockSlim();
|
||||
ReadLockers.Clear();
|
||||
}
|
||||
|
||||
LockedByThread = Thread.CurrentThread;
|
||||
WriterStack = Environment.StackTrace;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_itemLock.RecursiveWriteCount > 0)
|
||||
{
|
||||
m_itemLock.ExitWriteLock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region ICloneable Members
|
||||
|
||||
@@ -205,13 +52,14 @@ namespace OpenSim.Framework
|
||||
{
|
||||
TaskInventoryDictionary clone = new TaskInventoryDictionary();
|
||||
|
||||
m_itemLock.EnterReadLock();
|
||||
foreach (UUID uuid in Keys)
|
||||
lock (this)
|
||||
{
|
||||
clone.Add(uuid, (TaskInventoryItem) this[uuid].Clone());
|
||||
foreach (UUID uuid in Keys)
|
||||
{
|
||||
clone.Add(uuid, (TaskInventoryItem) this[uuid].Clone());
|
||||
}
|
||||
}
|
||||
m_itemLock.ExitReadLock();
|
||||
|
||||
|
||||
return clone;
|
||||
}
|
||||
|
||||
|
||||
@@ -121,12 +121,9 @@ namespace OpenSim.Framework
|
||||
private UUID _permsGranter;
|
||||
private int _permsMask;
|
||||
private int _type = 0;
|
||||
private UUID _oldID = UUID.Zero;
|
||||
private UUID _oldID;
|
||||
|
||||
private bool _ownerChanged = false;
|
||||
|
||||
// This used ONLY during copy. It can't be relied on at other times!
|
||||
private bool _scriptRunning = true;
|
||||
|
||||
public UUID AssetID {
|
||||
get {
|
||||
@@ -390,15 +387,6 @@ namespace OpenSim.Framework
|
||||
}
|
||||
}
|
||||
|
||||
public bool ScriptRunning {
|
||||
get {
|
||||
return _scriptRunning;
|
||||
}
|
||||
set {
|
||||
_scriptRunning = value;
|
||||
}
|
||||
}
|
||||
|
||||
// See ICloneable
|
||||
|
||||
#region ICloneable Members
|
||||
@@ -416,8 +404,7 @@ namespace OpenSim.Framework
|
||||
/// <param name="partID">The new part ID to which this item belongs</param>
|
||||
public void ResetIDs(UUID partID)
|
||||
{
|
||||
if (_oldID == UUID.Zero)
|
||||
_oldID = ItemID;
|
||||
OldItemID = ItemID;
|
||||
ItemID = UUID.Random();
|
||||
ParentPartID = partID;
|
||||
ParentID = partID;
|
||||
|
||||
@@ -217,12 +217,12 @@ namespace OpenSim.Framework.Tests
|
||||
BannedHostNameMask = string.Empty,
|
||||
BannedUserID = bannedUserId}
|
||||
);
|
||||
Assert.IsTrue(es.IsBanned(bannedUserId, 32), "User Should be banned but is not.");
|
||||
Assert.IsFalse(es.IsBanned(UUID.Zero, 32), "User Should not be banned but is.");
|
||||
Assert.IsTrue(es.IsBanned(bannedUserId), "User Should be banned but is not.");
|
||||
Assert.IsFalse(es.IsBanned(UUID.Zero), "User Should not be banned but is.");
|
||||
|
||||
es.RemoveBan(bannedUserId);
|
||||
|
||||
Assert.IsFalse(es.IsBanned(bannedUserId, 32), "User Should not be banned but is.");
|
||||
Assert.IsFalse(es.IsBanned(bannedUserId), "User Should not be banned but is.");
|
||||
|
||||
es.AddEstateManager(UUID.Zero);
|
||||
|
||||
|
||||
@@ -58,10 +58,12 @@ namespace OpenSim.Framework
|
||||
/// <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.
|
||||
/// RegressionTest is used by regression tests. It fires the call synchronously and does not catch any exceptions.
|
||||
/// </remarks>
|
||||
public enum FireAndForgetMethod
|
||||
{
|
||||
None,
|
||||
RegressionTest,
|
||||
UnsafeQueueUserWorkItem,
|
||||
QueueUserWorkItem,
|
||||
BeginInvoke,
|
||||
@@ -431,25 +433,19 @@ namespace OpenSim.Framework
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <returns></returns>
|
||||
|
||||
public static string Md5Hash(string data)
|
||||
{
|
||||
return Md5Hash(data, Encoding.Default);
|
||||
}
|
||||
|
||||
public static string Md5Hash(string data, Encoding encoding)
|
||||
{
|
||||
byte[] dataMd5 = ComputeMD5Hash(data, encoding);
|
||||
byte[] dataMd5 = ComputeMD5Hash(data);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < dataMd5.Length; i++)
|
||||
sb.AppendFormat("{0:x2}", dataMd5[i]);
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static byte[] ComputeMD5Hash(string data, Encoding encoding)
|
||||
private static byte[] ComputeMD5Hash(string data)
|
||||
{
|
||||
MD5 md5 = MD5.Create();
|
||||
return md5.ComputeHash(encoding.GetBytes(data));
|
||||
return md5.ComputeHash(Encoding.Default.GetBytes(data));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -457,12 +453,6 @@ namespace OpenSim.Framework
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <returns></returns>
|
||||
|
||||
public static string SHA1Hash(string data, Encoding enc)
|
||||
{
|
||||
return SHA1Hash(enc.GetBytes(data));
|
||||
}
|
||||
|
||||
public static string SHA1Hash(string data)
|
||||
{
|
||||
return SHA1Hash(Encoding.Default.GetBytes(data));
|
||||
@@ -1067,19 +1057,19 @@ namespace OpenSim.Framework
|
||||
{
|
||||
string os = String.Empty;
|
||||
|
||||
// if (Environment.OSVersion.Platform != PlatformID.Unix)
|
||||
// {
|
||||
// os = Environment.OSVersion.ToString();
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// os = ReadEtcIssue();
|
||||
// }
|
||||
//
|
||||
// if (os.Length > 45)
|
||||
// {
|
||||
// os = os.Substring(0, 45);
|
||||
// }
|
||||
if (Environment.OSVersion.Platform != PlatformID.Unix)
|
||||
{
|
||||
os = Environment.OSVersion.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
os = ReadEtcIssue();
|
||||
}
|
||||
|
||||
if (os.Length > 45)
|
||||
{
|
||||
os = os.Substring(0, 45);
|
||||
}
|
||||
|
||||
return os;
|
||||
}
|
||||
@@ -1212,7 +1202,7 @@ namespace OpenSim.Framework
|
||||
|
||||
public static Guid GetHashGuid(string data, string salt)
|
||||
{
|
||||
byte[] hash = ComputeMD5Hash(data + salt, Encoding.Default);
|
||||
byte[] hash = ComputeMD5Hash(data + salt);
|
||||
|
||||
//string s = BitConverter.ToString(hash);
|
||||
|
||||
@@ -1556,27 +1546,38 @@ 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();
|
||||
WaitCallback realCallback;
|
||||
|
||||
try
|
||||
if (FireAndForgetMethod == FireAndForgetMethod.RegressionTest)
|
||||
{
|
||||
// If we're running regression tests, then we want any exceptions to rise up to the test code.
|
||||
realCallback = o => { Culture.SetCurrentCulture(); callback(o); };
|
||||
}
|
||||
else
|
||||
{
|
||||
// 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.
|
||||
realCallback = o =>
|
||||
{
|
||||
callback(o);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat(
|
||||
"[UTIL]: Continuing after async_call_method thread terminated with exception {0}{1}",
|
||||
e.Message, e.StackTrace);
|
||||
}
|
||||
};
|
||||
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.RegressionTest:
|
||||
case FireAndForgetMethod.None:
|
||||
realCallback.Invoke(obj);
|
||||
break;
|
||||
@@ -1663,13 +1664,14 @@ namespace OpenSim.Framework
|
||||
/// </summary>
|
||||
public static void PrintCallStack()
|
||||
{
|
||||
StackTrace stackTrace = new StackTrace(); // get call stack
|
||||
StackTrace stackTrace = new StackTrace(true); // get call stack
|
||||
StackFrame[] stackFrames = stackTrace.GetFrames(); // get method calls (frames)
|
||||
|
||||
// write call stack method names
|
||||
foreach (StackFrame stackFrame in stackFrames)
|
||||
{
|
||||
m_log.Debug(stackFrame.GetMethod().DeclaringType + "." + stackFrame.GetMethod().Name); // write method name
|
||||
MethodBase mb = stackFrame.GetMethod();
|
||||
m_log.DebugFormat("{0}.{1}:{2}", mb.DeclaringType, mb.Name, stackFrame.GetFileLineNumber()); // write method name
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -52,13 +52,10 @@ namespace OpenSim.Framework
|
||||
/// <summary>
|
||||
/// Approximate tick when this thread was started.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Not terribly good since this quickly wraps around.
|
||||
/// </remarks>
|
||||
public int FirstTick { get; private set; }
|
||||
public int StartTick { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// First time this heartbeat update was invoked
|
||||
/// Last time this heartbeat update was invoked
|
||||
/// </summary>
|
||||
public int LastTick { get; set; }
|
||||
|
||||
@@ -76,8 +73,8 @@ namespace OpenSim.Framework
|
||||
{
|
||||
Thread = thread;
|
||||
Timeout = timeout;
|
||||
FirstTick = Environment.TickCount & Int32.MaxValue;
|
||||
LastTick = FirstTick;
|
||||
StartTick = Environment.TickCount & Int32.MaxValue;
|
||||
LastTick = StartTick;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,7 +237,7 @@ namespace OpenSim.Framework
|
||||
|
||||
lock (m_threads)
|
||||
{
|
||||
int now = Environment.TickCount;
|
||||
int now = Environment.TickCount & Int32.MaxValue;
|
||||
|
||||
foreach (ThreadWatchdogInfo threadInfo in m_threads.Values)
|
||||
{
|
||||
@@ -266,4 +263,4 @@ namespace OpenSim.Framework
|
||||
m_watchdogTimer.Start();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -243,7 +243,6 @@ namespace OpenSim.Framework
|
||||
catch (Exception ex)
|
||||
{
|
||||
errorMessage = ex.Message;
|
||||
m_log.Debug("[WEB UTIL]: Exception making request: " + ex.ToString());
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -295,10 +294,10 @@ namespace OpenSim.Framework
|
||||
return result;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
catch
|
||||
{
|
||||
// don't need to treat this as an error... we're just guessing anyway
|
||||
m_log.DebugFormat("[WEB UTIL] couldn't decode <{0}>: {1}",response,e.Message);
|
||||
// m_log.DebugFormat("[WEB UTIL] couldn't decode <{0}>: {1}",response,e.Message);
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -310,7 +309,7 @@ namespace OpenSim.Framework
|
||||
/// </summary>
|
||||
public static OSDMap PostToService(string url, NameValueCollection data)
|
||||
{
|
||||
return ServiceFormRequest(url,data, 20000);
|
||||
return ServiceFormRequest(url,data,10000);
|
||||
}
|
||||
|
||||
public static OSDMap ServiceFormRequest(string url, NameValueCollection data, int timeout)
|
||||
@@ -923,19 +922,12 @@ namespace OpenSim.Framework
|
||||
/// <exception cref="System.Net.WebException">Thrown if we encounter a network issue while posting
|
||||
/// the request. You'll want to make sure you deal with this as they're not uncommon</exception>
|
||||
public static TResponse MakeRequest<TRequest, TResponse>(string verb, string requestUrl, TRequest obj)
|
||||
{
|
||||
return MakeRequest<TRequest, TResponse>(verb, requestUrl, obj, 0);
|
||||
}
|
||||
|
||||
public static TResponse MakeRequest<TRequest, TResponse>(string verb, string requestUrl, TRequest obj, int pTimeout)
|
||||
{
|
||||
Type type = typeof(TRequest);
|
||||
TResponse deserial = default(TResponse);
|
||||
|
||||
WebRequest request = WebRequest.Create(requestUrl);
|
||||
request.Method = verb;
|
||||
if (pTimeout != 0)
|
||||
request.Timeout = pTimeout * 1000;
|
||||
|
||||
if ((verb == "POST") || (verb == "PUT"))
|
||||
{
|
||||
|
||||
@@ -31,7 +31,6 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Timers;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
@@ -58,16 +57,6 @@ namespace OpenSim
|
||||
protected string m_consoleType = "local";
|
||||
protected uint m_consolePort = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Prompt to use for simulator command line.
|
||||
/// </summary>
|
||||
private string m_consolePrompt;
|
||||
|
||||
/// <summary>
|
||||
/// Regex for parsing out special characters in the prompt.
|
||||
/// </summary>
|
||||
private Regex m_consolePromptRegex = new Regex(@"([^\\])\\(\w)", RegexOptions.Compiled);
|
||||
|
||||
private string m_timedScript = "disabled";
|
||||
private Timer m_scriptTimer;
|
||||
|
||||
@@ -96,9 +85,7 @@ namespace OpenSim
|
||||
|
||||
if (networkConfig != null)
|
||||
m_consolePort = (uint)networkConfig.GetInt("console_port", 0);
|
||||
|
||||
m_timedScript = startupConfig.GetString("timer_Script", "disabled");
|
||||
|
||||
if (m_logFileAppender != null)
|
||||
{
|
||||
if (m_logFileAppender is log4net.Appender.FileAppender)
|
||||
@@ -121,7 +108,6 @@ namespace OpenSim
|
||||
Util.FireAndForgetMethod = asyncCallMethod;
|
||||
|
||||
stpMaxThreads = startupConfig.GetInt("MaxPoolThreads", 15);
|
||||
m_consolePrompt = startupConfig.GetString("ConsolePrompt", @"Region (\R) ");
|
||||
}
|
||||
|
||||
if (Util.FireAndForgetMethod == FireAndForgetMethod.SmartThreadPool)
|
||||
@@ -242,8 +228,16 @@ namespace OpenSim
|
||||
+ "If an avatar name is given then only packets from that avatar are logged",
|
||||
Debug);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "debug http",
|
||||
"debug http <level>",
|
||||
"Turn on inbound http request debugging for everything except the event queue (see debug eq).",
|
||||
"If level >= 2 then the handler used to service the request is logged.\n"
|
||||
+ "If level >= 1 then incoming HTTP requests are logged.\n"
|
||||
+ "If level <= 0 then no extra http logging is done.\n",
|
||||
Debug);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "debug scene",
|
||||
"debug scene <cripting> <collisions> <physics>",
|
||||
"debug scene <scripting> <collisions> <physics>",
|
||||
"Turn on scene debugging", Debug);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "change region",
|
||||
@@ -337,7 +331,7 @@ namespace OpenSim
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "backup",
|
||||
"backup",
|
||||
"Persist objects to the database now", RunCommand);
|
||||
"Persist currently unsaved object changes immediately instead of waiting for the normal persistence call.", RunCommand);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "create region",
|
||||
"create region [\"region name\"] <region_file.ini>",
|
||||
@@ -470,7 +464,7 @@ namespace OpenSim
|
||||
if (alert != null)
|
||||
presence.ControllingClient.Kick(alert);
|
||||
else
|
||||
presence.ControllingClient.Kick("\nYou have been logged out by an administrator.\n");
|
||||
presence.ControllingClient.Kick("\nThe OpenSim manager kicked you out.\n");
|
||||
|
||||
// ...and close on our side
|
||||
presence.Scene.IncomingCloseAgent(presence.UUID);
|
||||
@@ -788,6 +782,7 @@ namespace OpenSim
|
||||
break;
|
||||
|
||||
case "backup":
|
||||
MainConsole.Instance.Output("Triggering save of pending object updates to persistent store");
|
||||
m_sceneManager.BackupCurrentScene();
|
||||
break;
|
||||
|
||||
@@ -798,7 +793,7 @@ namespace OpenSim
|
||||
if (m_sceneManager.TryGetScene(regRemoveName, out removeScene))
|
||||
RemoveRegion(removeScene, false);
|
||||
else
|
||||
MainConsole.Instance.Output("no region with that name");
|
||||
MainConsole.Instance.Output("No region with that name");
|
||||
break;
|
||||
|
||||
case "delete-region":
|
||||
@@ -845,22 +840,7 @@ namespace OpenSim
|
||||
|
||||
string regionName = (m_sceneManager.CurrentScene == null ? "root" : m_sceneManager.CurrentScene.RegionInfo.RegionName);
|
||||
MainConsole.Instance.Output(String.Format("Currently selected region is {0}", regionName));
|
||||
|
||||
// m_log.DebugFormat("Original prompt is {0}", m_consolePrompt);
|
||||
string prompt = m_consolePrompt;
|
||||
|
||||
// Replace "\R" with the region name
|
||||
// Replace "\\" with "\"
|
||||
prompt = m_consolePromptRegex.Replace(prompt, m =>
|
||||
{
|
||||
// m_log.DebugFormat("Matched {0}", m.Groups[2].Value);
|
||||
if (m.Groups[2].Value == "R")
|
||||
return m.Groups[1].Value + regionName;
|
||||
else
|
||||
return m.Groups[0].Value;
|
||||
});
|
||||
|
||||
m_console.DefaultPrompt = prompt;
|
||||
m_console.DefaultPrompt = String.Format("Region ({0}) ", regionName);
|
||||
m_console.ConsoleScene = m_sceneManager.CurrentScene;
|
||||
}
|
||||
|
||||
@@ -886,15 +866,32 @@ namespace OpenSim
|
||||
if (int.TryParse(args[2], out newDebug))
|
||||
{
|
||||
m_sceneManager.SetDebugPacketLevelOnCurrentScene(newDebug, name);
|
||||
// We provide user information elsewhere if any clients had their debug level set.
|
||||
// MainConsole.Instance.OutputFormat("Debug packet level set to {0}", newDebug);
|
||||
}
|
||||
else
|
||||
{
|
||||
MainConsole.Instance.Output("packet debug should be 0..255");
|
||||
MainConsole.Instance.Output("Usage: debug packet 0..255");
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case "http":
|
||||
if (args.Length == 3)
|
||||
{
|
||||
int newDebug;
|
||||
if (int.TryParse(args[2], out newDebug))
|
||||
{
|
||||
MainServer.Instance.DebugLevel = newDebug;
|
||||
MainConsole.Instance.OutputFormat("Debug http level set to {0}", newDebug);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
MainConsole.Instance.Output("Usage: debug http 0..2");
|
||||
break;
|
||||
|
||||
case "scene":
|
||||
if (args.Length == 5)
|
||||
{
|
||||
@@ -917,13 +914,13 @@ namespace OpenSim
|
||||
}
|
||||
else
|
||||
{
|
||||
MainConsole.Instance.Output("debug scene <scripting> <collisions> <physics> (where inside <> is true/false)");
|
||||
MainConsole.Instance.Output("Usage: debug scene <scripting> <collisions> <physics> (where inside <> is true/false)");
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
MainConsole.Instance.Output("Unknown debug");
|
||||
MainConsole.Instance.Output("Unknown debug command");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1049,6 +1046,24 @@ namespace OpenSim
|
||||
MainConsole.Instance.Output(handlers.ToString());
|
||||
break;
|
||||
|
||||
case "pending-objects":
|
||||
System.Text.StringBuilder pending = new System.Text.StringBuilder("Pending objects:\n");
|
||||
m_sceneManager.ForEachScene(
|
||||
delegate(Scene scene)
|
||||
{
|
||||
scene.ForEachScenePresence(
|
||||
delegate(ScenePresence sp)
|
||||
{
|
||||
pending.AppendFormat("{0}: {1} {2} pending\n",
|
||||
scene.RegionInfo.RegionName, sp.Name, sp.SceneViewer.GetPendingObjectsCount());
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
MainConsole.Instance.Output(pending.ToString());
|
||||
break;
|
||||
|
||||
case "modules":
|
||||
MainConsole.Instance.Output("The currently loaded shared modules are:");
|
||||
foreach (IRegionModule module in m_moduleLoader.GetLoadedSharedModules)
|
||||
@@ -1056,19 +1071,6 @@ namespace OpenSim
|
||||
MainConsole.Instance.Output("Shared Module: " + module.Name);
|
||||
}
|
||||
|
||||
m_sceneManager.ForEachScene(
|
||||
delegate(Scene scene)
|
||||
{
|
||||
m_log.Error("The currently loaded modules in " + scene.RegionInfo.RegionName + " are:");
|
||||
foreach (IRegionModule module in scene.Modules.Values)
|
||||
{
|
||||
if (!module.IsSharedModule)
|
||||
{
|
||||
m_log.Error("Region Module: " + module.Name);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
MainConsole.Instance.Output("");
|
||||
break;
|
||||
|
||||
@@ -1181,7 +1183,7 @@ namespace OpenSim
|
||||
MainConsole.Instance.Output(String.Format("loadOffsets <X,Y,Z> = <{0},{1},{2}>",loadOffset.X,loadOffset.Y,loadOffset.Z));
|
||||
}
|
||||
}
|
||||
m_sceneManager.LoadCurrentSceneFromXml(cmdparams[0], generateNewIDS, loadOffset);
|
||||
m_sceneManager.LoadCurrentSceneFromXml(cmdparams[2], generateNewIDS, loadOffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -46,7 +46,7 @@ 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.Server.Base;
|
||||
using OpenSim.Services.Base;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using OpenSim.Services.UserAccountService;
|
||||
@@ -92,10 +92,6 @@ namespace OpenSim
|
||||
|
||||
protected List<IApplicationPlugin> m_plugins = new List<IApplicationPlugin>();
|
||||
|
||||
private List<string> m_permsModules;
|
||||
|
||||
private bool m_securePermissionsLoading = true;
|
||||
|
||||
/// <value>
|
||||
/// The config information passed into the OpenSimulator region server.
|
||||
/// </value>
|
||||
@@ -193,11 +189,6 @@ namespace OpenSim
|
||||
CreatePIDFile(pidFile);
|
||||
|
||||
userStatsURI = startupConfig.GetString("Stats_URI", String.Empty);
|
||||
|
||||
m_securePermissionsLoading = startupConfig.GetBoolean("SecurePermissionsLoading", true);
|
||||
|
||||
string permissionModules = startupConfig.GetString("permissionmodules", "DefaultPermissionsModule");
|
||||
m_permsModules = new List<string>(permissionModules.Split(','));
|
||||
}
|
||||
|
||||
// Load the simulation data service
|
||||
@@ -226,12 +217,6 @@ namespace OpenSim
|
||||
m_moduleLoader = new ModuleLoader(m_config.Source);
|
||||
|
||||
LoadPlugins();
|
||||
|
||||
if (m_plugins.Count == 0) // We failed to load any modules. Mono Addins glitch!
|
||||
{
|
||||
Environment.Exit(1);
|
||||
}
|
||||
|
||||
foreach (IApplicationPlugin plugin in m_plugins)
|
||||
{
|
||||
plugin.PostInitialise();
|
||||
@@ -379,41 +364,7 @@ namespace OpenSim
|
||||
}
|
||||
else m_log.Error("[REGIONMODULES]: The new RegionModulesController is missing...");
|
||||
|
||||
if (m_securePermissionsLoading)
|
||||
{
|
||||
foreach (string s in m_permsModules)
|
||||
{
|
||||
if (!scene.RegionModules.ContainsKey(s))
|
||||
{
|
||||
bool found = false;
|
||||
foreach (IRegionModule m in modules)
|
||||
{
|
||||
if (m.Name == s)
|
||||
{
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
{
|
||||
m_log.Fatal("[MODULES]: Required module " + s + " not found.");
|
||||
Environment.Exit(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
scene.SetModuleInterfaces();
|
||||
// First Step of bootreport sequence
|
||||
if (scene.SnmpService != null)
|
||||
{
|
||||
scene.SnmpService.ColdStart(1,scene);
|
||||
scene.SnmpService.LinkDown(scene);
|
||||
}
|
||||
|
||||
if (scene.SnmpService != null)
|
||||
{
|
||||
scene.SnmpService.BootInfo("Loading prins", scene);
|
||||
}
|
||||
|
||||
while (regionInfo.EstateSettings.EstateOwner == UUID.Zero && MainConsole.Instance != null)
|
||||
SetUpEstateOwner(scene);
|
||||
@@ -424,10 +375,6 @@ namespace OpenSim
|
||||
// TODO : Try setting resource for region xstats here on scene
|
||||
MainServer.Instance.AddStreamHandler(new Region.Framework.Scenes.RegionStatsHandler(regionInfo));
|
||||
|
||||
if (scene.SnmpService != null)
|
||||
{
|
||||
scene.SnmpService.BootInfo("Grid Registration in progress", scene);
|
||||
}
|
||||
try
|
||||
{
|
||||
scene.RegisterRegionWithGrid();
|
||||
@@ -438,20 +385,11 @@ namespace OpenSim
|
||||
"[STARTUP]: Registration of region with grid failed, aborting startup due to {0} {1}",
|
||||
e.Message, e.StackTrace);
|
||||
|
||||
if (scene.SnmpService != null)
|
||||
{
|
||||
scene.SnmpService.Critical("Grid registration failed. Startup aborted.", scene);
|
||||
}
|
||||
// Carrying on now causes a lot of confusion down the
|
||||
// line - we need to get the user's attention
|
||||
Environment.Exit(1);
|
||||
}
|
||||
|
||||
if (scene.SnmpService != null)
|
||||
{
|
||||
scene.SnmpService.BootInfo("Grid Registration done", scene);
|
||||
}
|
||||
|
||||
scene.loadAllLandObjectsFromStorage(regionInfo.originRegionID);
|
||||
scene.EventManager.TriggerParcelPrimCountUpdate();
|
||||
|
||||
@@ -459,11 +397,6 @@ namespace OpenSim
|
||||
// scripting engines.
|
||||
scene.CreateScriptInstances();
|
||||
|
||||
if (scene.SnmpService != null)
|
||||
{
|
||||
scene.SnmpService.BootInfo("ScriptEngine started", scene);
|
||||
}
|
||||
|
||||
m_sceneManager.Add(scene);
|
||||
|
||||
if (m_autoCreateClientStack)
|
||||
@@ -472,10 +405,6 @@ namespace OpenSim
|
||||
clientServer.Start();
|
||||
}
|
||||
|
||||
if (scene.SnmpService != null)
|
||||
{
|
||||
scene.SnmpService.BootInfo("Initializing region modules", scene);
|
||||
}
|
||||
if (do_post_init)
|
||||
{
|
||||
foreach (IRegionModule module in modules)
|
||||
@@ -487,14 +416,7 @@ namespace OpenSim
|
||||
|
||||
mscene = scene;
|
||||
|
||||
if (scene.SnmpService != null)
|
||||
{
|
||||
scene.SnmpService.BootInfo("The region is operational", scene);
|
||||
scene.SnmpService.LinkUp(scene);
|
||||
}
|
||||
|
||||
scene.StartTimer();
|
||||
scene.StartTimerWatchdog();
|
||||
|
||||
scene.StartScripts();
|
||||
|
||||
@@ -571,11 +493,6 @@ namespace OpenSim
|
||||
private void ShutdownRegion(Scene scene)
|
||||
{
|
||||
m_log.DebugFormat("[SHUTDOWN]: Shutting down region {0}", scene.RegionInfo.RegionName);
|
||||
if (scene.SnmpService != null)
|
||||
{
|
||||
scene.SnmpService.BootInfo("The region is shutting down", scene);
|
||||
scene.SnmpService.LinkDown(scene);
|
||||
}
|
||||
IRegionModulesController controller;
|
||||
if (ApplicationRegistry.TryGet<IRegionModulesController>(out controller))
|
||||
{
|
||||
@@ -1019,7 +936,7 @@ namespace OpenSim
|
||||
= MainConsole.Instance.CmdPrompt(
|
||||
string.Format(
|
||||
"Do you wish to join region {0} to an existing estate (yes/no)?", regInfo.RegionName),
|
||||
"no",
|
||||
"yes",
|
||||
new List<string>() { "yes", "no" });
|
||||
|
||||
if (response == "no")
|
||||
@@ -1035,15 +952,12 @@ namespace OpenSim
|
||||
= MainConsole.Instance.CmdPrompt(
|
||||
string.Format(
|
||||
"Name of estate to join. Existing estate names are ({0})", string.Join(", ", estateNames.ToArray())),
|
||||
"None");
|
||||
|
||||
if (response == "None")
|
||||
continue;
|
||||
estateNames[0]);
|
||||
|
||||
List<int> estateIDs = EstateDataService.GetEstates(response);
|
||||
if (estateIDs.Count < 1)
|
||||
{
|
||||
MainConsole.Instance.Output("The name you have entered matches no known estate. Please try again.");
|
||||
MainConsole.Instance.Output("The name you have entered matches no known estate. Please try again.");
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -56,8 +56,6 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
string assetName, string description, UUID assetID, UUID inventoryItem, UUID parentFolder,
|
||||
byte[] data, string inventoryType, string assetType);
|
||||
|
||||
public delegate void UploadedBakedTexture(UUID assetID, byte[] data);
|
||||
|
||||
public delegate UUID UpdateItem(UUID itemID, byte[] data);
|
||||
|
||||
public delegate void UpdateTaskScript(UUID itemID, UUID primID, bool isScriptRunning, byte[] data, ref ArrayList errors);
|
||||
@@ -97,7 +95,6 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
private static readonly string m_notecardTaskUpdatePath = "0005/";
|
||||
// private static readonly string m_fetchInventoryPath = "0006/";
|
||||
// private static readonly string m_remoteParcelRequestPath = "0009/";// This is in the LandManagementModule.
|
||||
private static readonly string m_uploadBakedTexturePath = "0010/";// This is in the LandManagementModule.
|
||||
|
||||
|
||||
// These are callbacks which will be setup by the scene so that we can update scene data when we
|
||||
@@ -135,7 +132,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
ItemUpdatedCall = m_Scene.CapsUpdateInventoryItemAsset;
|
||||
TaskScriptUpdatedCall = m_Scene.CapsUpdateTaskInventoryScriptAsset;
|
||||
CAPSFetchInventoryDescendents = m_Scene.HandleFetchInventoryDescendentsCAPS;
|
||||
GetClient = m_Scene.SceneGraph.GetControllingClient;
|
||||
GetClient = m_Scene.SceneContents.GetControllingClient;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -165,8 +162,6 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
IRequestHandler req = new RestStreamHandler("POST", capsBase + m_notecardTaskUpdatePath, ScriptTaskInventory);
|
||||
m_HostCapsObj.RegisterHandler("UpdateScriptTaskInventory", req);
|
||||
m_HostCapsObj.RegisterHandler("UpdateScriptTask", req);
|
||||
m_HostCapsObj.RegisterHandler("UploadBakedTexture", new RestStreamHandler("POST", capsBase + m_uploadBakedTexturePath, UploadBakedTexture));
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -239,7 +234,8 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
Hashtable caps = m_HostCapsObj.CapsHandlers.CapsDetails;
|
||||
Hashtable caps = m_HostCapsObj.CapsHandlers.GetCapsDetails(true);
|
||||
|
||||
// Add the external too
|
||||
foreach (KeyValuePair<string, string> kvp in m_HostCapsObj.ExternalCapsHandlers)
|
||||
caps[kvp.Key] = kvp.Value;
|
||||
@@ -330,74 +326,6 @@ 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);
|
||||
|
||||
string capsBase = "/CAPS/" + m_HostCapsObj.CapsObjectPath;
|
||||
string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000");
|
||||
|
||||
BakedTextureUploader uploader =
|
||||
new BakedTextureUploader(capsBase + uploaderPath, m_HostCapsObj.HttpListener);
|
||||
uploader.OnUpLoad += BakedTextureUploaded;
|
||||
|
||||
m_HostCapsObj.HttpListener.AddStreamHandler(
|
||||
new BinaryStreamHandler("POST", capsBase + uploaderPath,
|
||||
uploader.uploaderCaps));
|
||||
|
||||
string protocol = "http://";
|
||||
|
||||
if (m_HostCapsObj.SSLCaps)
|
||||
protocol = "https://";
|
||||
|
||||
string uploaderURL = protocol + m_HostCapsObj.HostName + ":" +
|
||||
m_HostCapsObj.Port.ToString() + capsBase + uploaderPath;
|
||||
|
||||
LLSDAssetUploadResponse uploadResponse =
|
||||
new LLSDAssetUploadResponse();
|
||||
uploadResponse.uploader = uploaderURL;
|
||||
uploadResponse.state = "upload";
|
||||
|
||||
return LLSDHelpers.SerialiseLLSDReply(uploadResponse);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Error("[CAPS]: " + e.ToString());
|
||||
}
|
||||
|
||||
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());
|
||||
|
||||
AssetBase asset;
|
||||
asset = new AssetBase(assetID, "Baked Texture", (sbyte)AssetType.Texture, m_HostCapsObj.AgentID.ToString());
|
||||
asset.Data = data;
|
||||
asset.Temporary = true;
|
||||
asset.Local = !m_persistBakedTextures; // Local assets aren't persisted, non-local are
|
||||
m_assetService.Store(asset);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when new asset data for an agent inventory item update has been uploaded.
|
||||
/// </summary>
|
||||
@@ -1067,6 +995,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
// XXX Maybe this should be some meaningful error packet
|
||||
return null;
|
||||
}
|
||||
|
||||
///Left this in and commented in case there are unforseen issues
|
||||
//private void SaveAssetToFile(string filename, byte[] data)
|
||||
//{
|
||||
@@ -1090,53 +1019,4 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
fs.Close();
|
||||
}
|
||||
}
|
||||
|
||||
public class BakedTextureUploader
|
||||
{
|
||||
public event UploadedBakedTexture OnUpLoad;
|
||||
private UploadedBakedTexture handlerUpLoad = null;
|
||||
|
||||
private string uploaderPath = String.Empty;
|
||||
private UUID newAssetID;
|
||||
private IHttpServer httpListener;
|
||||
|
||||
public BakedTextureUploader(string path, IHttpServer httpServer)
|
||||
{
|
||||
newAssetID = UUID.Random();
|
||||
uploaderPath = path;
|
||||
httpListener = httpServer;
|
||||
// m_log.InfoFormat("[CAPS] baked texture upload starting for {0}",newAssetID);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle raw uploaded baked texture data.
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <param name="path"></param>
|
||||
/// <param name="param"></param>
|
||||
/// <returns></returns>
|
||||
public string uploaderCaps(byte[] data, string path, string param)
|
||||
{
|
||||
handlerUpLoad = OnUpLoad;
|
||||
if (handlerUpLoad != null)
|
||||
{
|
||||
Util.FireAndForget(delegate(object o) { handlerUpLoad(newAssetID, data); });
|
||||
}
|
||||
|
||||
string res = String.Empty;
|
||||
LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete();
|
||||
uploadComplete.new_asset = newAssetID.ToString();
|
||||
uploadComplete.new_inventory_item = UUID.Zero;
|
||||
uploadComplete.state = "complete";
|
||||
|
||||
res = LLSDHelpers.SerialiseLLSDReply(uploadComplete);
|
||||
|
||||
httpListener.RemoveStreamHandler("POST", uploaderPath);
|
||||
|
||||
// m_log.InfoFormat("[CAPS] baked texture upload completed for {0}",newAssetID);
|
||||
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -39,6 +39,7 @@ using OpenMetaverse.Messages.Linden;
|
||||
using OpenMetaverse.Packets;
|
||||
using OpenMetaverse.StructuredData;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Console;
|
||||
using OpenSim.Framework.Servers;
|
||||
using OpenSim.Framework.Servers.HttpServer;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
@@ -58,9 +59,15 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
public class EventQueueGetModule : IEventQueue, IRegionModule
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
protected Scene m_scene = null;
|
||||
|
||||
/// <value>
|
||||
/// Debug level.
|
||||
/// </value>
|
||||
public int DebugLevel { get; set; }
|
||||
|
||||
protected Scene m_scene;
|
||||
private IConfigSource m_gConfig;
|
||||
bool enabledYN = false;
|
||||
bool enabledYN;
|
||||
|
||||
private Dictionary<UUID, int> m_ids = new Dictionary<UUID, int>();
|
||||
|
||||
@@ -97,6 +104,16 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
scene.EventManager.OnClientClosed += ClientClosed;
|
||||
scene.EventManager.OnMakeChildAgent += MakeChildAgent;
|
||||
scene.EventManager.OnRegisterCaps += OnRegisterCaps;
|
||||
|
||||
MainConsole.Instance.Commands.AddCommand(
|
||||
"event queue",
|
||||
false,
|
||||
"debug eq",
|
||||
"debug eq [0|1]",
|
||||
"Turn on event queue debugging",
|
||||
"debug eq 1 will turn on event queue debugging. This will log all outgoing event queue messages to clients.\n"
|
||||
+ "debug eq 0 will turn off event queue debugging.",
|
||||
HandleDebugEq);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -128,6 +145,22 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
}
|
||||
#endregion
|
||||
|
||||
protected void HandleDebugEq(string module, string[] args)
|
||||
{
|
||||
int debugLevel;
|
||||
|
||||
if (!(args.Length == 3 && int.TryParse(args[2], out debugLevel)))
|
||||
{
|
||||
MainConsole.Instance.OutputFormat("Usage: debug eq [0|1]");
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugLevel = debugLevel;
|
||||
MainConsole.Instance.OutputFormat(
|
||||
"Set event queue debug level to {0} in {1}", DebugLevel, m_scene.RegionInfo.RegionName);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Always returns a valid queue
|
||||
/// </summary>
|
||||
@@ -323,7 +356,9 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
|
||||
// This will persist this beyond the expiry of the caps handlers
|
||||
MainServer.Instance.AddPollServiceHTTPHandler(
|
||||
capsBase + EventQueueGetUUID.ToString() + "/", EventQueuePoll, new PollServiceEventArgs(null, HasEvents, GetEvents, NoEvents, agentID));
|
||||
capsBase + EventQueueGetUUID.ToString() + "/",
|
||||
EventQueuePoll,
|
||||
new PollServiceEventArgs(null, HasEvents, GetEvents, NoEvents, agentID));
|
||||
|
||||
Random rnd = new Random(Environment.TickCount);
|
||||
lock (m_ids)
|
||||
@@ -370,12 +405,31 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
}
|
||||
else
|
||||
{
|
||||
if (DebugLevel > 0 && element is OSDMap)
|
||||
{
|
||||
OSDMap ev = (OSDMap)element;
|
||||
m_log.DebugFormat(
|
||||
"[EVENT QUEUE GET MODULE]: Eq OUT {0} to {1}",
|
||||
ev["message"], m_scene.GetScenePresence(pAgentId).Name);
|
||||
}
|
||||
|
||||
array.Add(element);
|
||||
|
||||
lock (queue)
|
||||
{
|
||||
while (queue.Count > 0)
|
||||
{
|
||||
array.Add(queue.Dequeue());
|
||||
element = queue.Dequeue();
|
||||
|
||||
if (DebugLevel > 0 && element is OSDMap)
|
||||
{
|
||||
OSDMap ev = (OSDMap)element;
|
||||
m_log.DebugFormat(
|
||||
"[EVENT QUEUE GET MODULE]: Eq OUT {0} to {1}",
|
||||
ev["message"], m_scene.GetScenePresence(pAgentId).Name);
|
||||
}
|
||||
|
||||
array.Add(element);
|
||||
thisID++;
|
||||
}
|
||||
}
|
||||
@@ -471,11 +525,29 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
{
|
||||
array.Add(element);
|
||||
|
||||
if (element is OSDMap)
|
||||
{
|
||||
OSDMap ev = (OSDMap)element;
|
||||
m_log.DebugFormat(
|
||||
"[EVENT QUEUE GET MODULE]: Eq OUT {0} to {1}",
|
||||
ev["message"], m_scene.GetScenePresence(agentID).Name);
|
||||
}
|
||||
|
||||
lock (queue)
|
||||
{
|
||||
while (queue.Count > 0)
|
||||
{
|
||||
array.Add(queue.Dequeue());
|
||||
element = queue.Dequeue();
|
||||
|
||||
if (element is OSDMap)
|
||||
{
|
||||
OSDMap ev = (OSDMap)element;
|
||||
m_log.DebugFormat(
|
||||
"[EVENT QUEUE GET MODULE]: Eq OUT {0} to {1}",
|
||||
ev["message"], m_scene.GetScenePresence(agentID).Name);
|
||||
}
|
||||
|
||||
array.Add(element);
|
||||
thisID++;
|
||||
}
|
||||
}
|
||||
@@ -494,7 +566,8 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
responsedata["content_type"] = "application/xml";
|
||||
responsedata["keepalive"] = false;
|
||||
responsedata["str_response_string"] = OSDParser.SerializeLLSDXmlString(events);
|
||||
//m_log.DebugFormat("[EVENTQUEUE]: sending response for {0} in region {1}: {2}", agentID, m_scene.RegionInfo.RegionName, responsedata["str_response_string"]);
|
||||
|
||||
m_log.DebugFormat("[EVENTQUEUE]: sending response for {0} in region {1}: {2}", agentID, m_scene.RegionInfo.RegionName, responsedata["str_response_string"]);
|
||||
|
||||
return responsedata;
|
||||
}
|
||||
@@ -717,6 +790,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
OSD item = EventQueueHelper.GroupMembership(groupUpdate);
|
||||
Enqueue(item, avatarID);
|
||||
}
|
||||
|
||||
public void QueryReply(PlacesReplyPacket groupUpdate, UUID avatarID)
|
||||
{
|
||||
OSD item = EventQueueHelper.PlacesQuery(groupUpdate);
|
||||
|
||||
@@ -75,20 +75,5 @@ namespace OpenSim.Region.ClientStack.Linden.Tests
|
||||
// TODO: Add more assertions for the other aspects of event queues
|
||||
Assert.That(MainServer.Instance.GetPollServiceHandlerKeys().Count, Is.EqualTo(1));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RemoveForClient()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
UUID spId = TestHelpers.ParseTail(0x1);
|
||||
|
||||
SceneHelpers.AddScenePresence(m_scene, spId);
|
||||
m_scene.IncomingCloseAgent(spId);
|
||||
|
||||
// TODO: Add more assertions for the other aspects of event queues
|
||||
Assert.That(MainServer.Instance.GetPollServiceHandlerKeys().Count, Is.EqualTo(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -332,7 +332,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
|
||||
grp.IsAttachment = false;
|
||||
// Required for linking
|
||||
grp.RootPart.ClearUpdateSchedule();
|
||||
grp.RootPart.UpdateFlag = 0;
|
||||
|
||||
if (m_scene.Permissions.CanRezObject(1, avatar.UUID, pos))
|
||||
{
|
||||
@@ -345,9 +345,8 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
|
||||
for (int j = 1; j < allparts.Length; j++)
|
||||
{
|
||||
// Required for linking
|
||||
rootGroup.RootPart.ClearUpdateSchedule();
|
||||
allparts[j].RootPart.ClearUpdateSchedule();
|
||||
rootGroup.RootPart.UpdateFlag = 0;
|
||||
allparts[j].RootPart.UpdateFlag = 0;
|
||||
rootGroup.LinkToGroup(allparts[j]);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Specialized;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Reflection;
|
||||
using System.IO;
|
||||
using System.Web;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
using Mono.Addins;
|
||||
using OpenMetaverse;
|
||||
using OpenMetaverse.StructuredData;
|
||||
using OpenMetaverse.Imaging;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Servers;
|
||||
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;
|
||||
using OpenSim.Capabilities.Handlers;
|
||||
|
||||
namespace OpenSim.Region.ClientStack.Linden
|
||||
{
|
||||
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
|
||||
public class UploadBakedTextureModule : INonSharedRegionModule
|
||||
{
|
||||
// private static readonly ILog m_log =
|
||||
// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
/// <summary>
|
||||
/// For historical reasons this is fixed, but there
|
||||
/// </summary>
|
||||
private static readonly string m_uploadBakedTexturePath = "0010/";// This is in the LandManagementModule.
|
||||
|
||||
private Scene m_scene;
|
||||
private bool m_persistBakedTextures;
|
||||
|
||||
public void Initialise(IConfigSource source)
|
||||
{
|
||||
IConfig sconfig = source.Configs["Startup"];
|
||||
if (sconfig != null)
|
||||
m_persistBakedTextures = sconfig.GetBoolean("PersistBakedTextures", m_persistBakedTextures);
|
||||
}
|
||||
|
||||
public void AddRegion(Scene s)
|
||||
{
|
||||
m_scene = s;
|
||||
}
|
||||
|
||||
public void RemoveRegion(Scene s)
|
||||
{
|
||||
}
|
||||
|
||||
public void RegionLoaded(Scene s)
|
||||
{
|
||||
m_scene.EventManager.OnRegisterCaps += RegisterCaps;
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
}
|
||||
|
||||
public void Close() { }
|
||||
|
||||
public string Name { get { return "UploadBakedTextureModule"; } }
|
||||
|
||||
public Type ReplaceableInterface
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
public void RegisterCaps(UUID agentID, Caps caps)
|
||||
{
|
||||
caps.RegisterHandler(
|
||||
"UploadBakedTexture",
|
||||
new RestStreamHandler(
|
||||
"POST",
|
||||
"/CAPS/" + caps.CapsObjectPath + m_uploadBakedTexturePath,
|
||||
new UploadBakedTextureHandler(
|
||||
caps, m_scene.AssetService, m_persistBakedTextures).UploadBakedTexture));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -45,6 +45,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
private const int IMAGE_PACKET_SIZE = 1000;
|
||||
private const int FIRST_PACKET_SIZE = 600;
|
||||
|
||||
/// <summary>
|
||||
/// If we've requested an asset but not received it in this ticks timeframe, then allow a duplicate
|
||||
/// request from the client to trigger a fresh asset request.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// There are 10,000 ticks in a millisecond
|
||||
/// </remarks>
|
||||
private const int ASSET_REQUEST_TIMEOUT = 100000000;
|
||||
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
public uint LastSequence;
|
||||
@@ -56,9 +65,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
public IAssetService AssetService;
|
||||
public UUID AgentID;
|
||||
public IInventoryAccessModule InventoryAccessModule;
|
||||
public OpenJPEG.J2KLayerInfo[] Layers;
|
||||
public bool IsDecoded;
|
||||
public bool HasAsset;
|
||||
private OpenJPEG.J2KLayerInfo[] m_layers;
|
||||
|
||||
/// <summary>
|
||||
/// Has this request decoded the asset data?
|
||||
/// </summary>
|
||||
public bool IsDecoded { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Has this request received the required asset data?
|
||||
/// </summary>
|
||||
public bool HasAsset { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Time in milliseconds at which the asset was requested.
|
||||
/// </summary>
|
||||
public long AssetRequestTime { get; private set; }
|
||||
|
||||
public C5.IPriorityQueueHandle<J2KImage> PriorityQueueHandle;
|
||||
|
||||
private uint m_currentPacket;
|
||||
@@ -82,7 +105,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
/// <param name="packetsToSend">Maximum number of packets to send during this call</param>
|
||||
/// <param name="packetsSent">Number of packets sent during this call</param>
|
||||
/// <returns>True if the transfer completes at the current discard level, otherwise false</returns>
|
||||
public bool SendPackets(LLClientView client, int packetsToSend, out int packetsSent)
|
||||
public bool SendPackets(IClientAPI client, int packetsToSend, out int packetsSent)
|
||||
{
|
||||
packetsSent = 0;
|
||||
|
||||
@@ -102,7 +125,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
{
|
||||
m_currentPacket = 2;
|
||||
}
|
||||
|
||||
|
||||
while (sendMore && packetsSent < packetsToSend && m_currentPacket <= m_stopPacket)
|
||||
{
|
||||
sendMore = SendPacket(client);
|
||||
@@ -114,17 +137,24 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
return (m_currentPacket > m_stopPacket);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is where we decide what we need to update
|
||||
/// and assign the real discardLevel and packetNumber
|
||||
/// assuming of course that the connected client might be bonkers
|
||||
/// </summary>
|
||||
public void RunUpdate()
|
||||
{
|
||||
//This is where we decide what we need to update
|
||||
//and assign the real discardLevel and packetNumber
|
||||
//assuming of course that the connected client might be bonkers
|
||||
|
||||
if (!HasAsset)
|
||||
{
|
||||
if (!m_assetRequested)
|
||||
if (!m_assetRequested || DateTime.UtcNow.Ticks > AssetRequestTime + ASSET_REQUEST_TIMEOUT)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[J2KIMAGE]: Requesting asset {0} from request in packet {1}, already requested? {2}, due to timeout? {3}",
|
||||
// TextureID, LastSequence, m_assetRequested, DateTime.UtcNow.Ticks > AssetRequestTime + ASSET_REQUEST_TIMEOUT);
|
||||
|
||||
m_assetRequested = true;
|
||||
AssetRequestTime = DateTime.UtcNow.Ticks;
|
||||
|
||||
AssetService.Get(TextureID.ToString(), this, AssetReceived);
|
||||
}
|
||||
}
|
||||
@@ -137,6 +167,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
{
|
||||
//Request decode
|
||||
m_decodeRequested = true;
|
||||
|
||||
// m_log.DebugFormat("[J2KIMAGE]: Requesting decode of asset {0}", TextureID);
|
||||
|
||||
// Do we have a jpeg decoder?
|
||||
if (J2KDecoder != null)
|
||||
{
|
||||
@@ -149,7 +182,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
// Send it off to the jpeg decoder
|
||||
J2KDecoder.BeginDecode(TextureID, m_asset, J2KDecodedCallback);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -170,14 +202,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
if (DiscardLevel >= 0 || m_stopPacket == 0)
|
||||
{
|
||||
// This shouldn't happen, but if it does, we really can't proceed
|
||||
if (Layers == null)
|
||||
if (m_layers == null)
|
||||
{
|
||||
m_log.Warn("[J2KIMAGE]: RunUpdate() called with missing Layers. Canceling texture transfer");
|
||||
m_currentPacket = m_stopPacket;
|
||||
return;
|
||||
}
|
||||
|
||||
int maxDiscardLevel = Math.Max(0, Layers.Length - 1);
|
||||
int maxDiscardLevel = Math.Max(0, m_layers.Length - 1);
|
||||
|
||||
// Treat initial texture downloads with a DiscardLevel of -1 a request for the highest DiscardLevel
|
||||
if (DiscardLevel < 0 && m_stopPacket == 0)
|
||||
@@ -187,9 +219,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
DiscardLevel = (sbyte)Math.Min(DiscardLevel, maxDiscardLevel);
|
||||
|
||||
//Calculate the m_stopPacket
|
||||
if (Layers.Length > 0)
|
||||
if (m_layers.Length > 0)
|
||||
{
|
||||
m_stopPacket = (uint)GetPacketForBytePosition(Layers[(Layers.Length - 1) - DiscardLevel].End);
|
||||
m_stopPacket = (uint)GetPacketForBytePosition(m_layers[(m_layers.Length - 1) - DiscardLevel].End);
|
||||
//I don't know why, but the viewer seems to expect the final packet if the file
|
||||
//is just one packet bigger.
|
||||
if (TexturePacketCount() == m_stopPacket + 1)
|
||||
@@ -202,16 +234,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
m_stopPacket = TexturePacketCount();
|
||||
}
|
||||
|
||||
//Give them at least two packets, to play nice with some broken viewers (SL also behaves this way)
|
||||
if (m_stopPacket == 1 && Layers[0].End > FIRST_PACKET_SIZE) m_stopPacket++;
|
||||
|
||||
m_currentPacket = StartPacket;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool SendFirstPacket(LLClientView client)
|
||||
private bool SendFirstPacket(IClientAPI client)
|
||||
{
|
||||
if (client == null)
|
||||
return false;
|
||||
@@ -246,7 +275,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool SendPacket(LLClientView client)
|
||||
private bool SendPacket(IClientAPI client)
|
||||
{
|
||||
if (client == null)
|
||||
return false;
|
||||
@@ -331,20 +360,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
{
|
||||
if (m_currentPacket == 0)
|
||||
return 0;
|
||||
|
||||
if (m_currentPacket == 1)
|
||||
return FIRST_PACKET_SIZE;
|
||||
|
||||
int result = FIRST_PACKET_SIZE + ((int)m_currentPacket - 2) * IMAGE_PACKET_SIZE;
|
||||
|
||||
if (result < 0)
|
||||
{
|
||||
result = FIRST_PACKET_SIZE;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private void J2KDecodedCallback(UUID AssetId, OpenJPEG.J2KLayerInfo[] layers)
|
||||
{
|
||||
Layers = layers;
|
||||
m_layers = layers;
|
||||
IsDecoded = true;
|
||||
RunUpdate();
|
||||
}
|
||||
@@ -375,9 +405,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
|
||||
private void AssetReceived(string id, Object sender, AssetBase asset)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[J2KIMAGE]: Received asset {0} ({1} bytes)", id, asset != null ? asset.Data.Length.ToString() : "n/a");
|
||||
|
||||
UUID assetID = UUID.Zero;
|
||||
if (asset != null)
|
||||
{
|
||||
assetID = asset.FullID;
|
||||
}
|
||||
else if ((InventoryAccessModule != null) && (sender != InventoryAccessModule))
|
||||
{
|
||||
// Unfortunately we need this here, there's no other way.
|
||||
@@ -395,7 +430,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
}
|
||||
|
||||
AssetDataCallback(assetID, asset);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -39,6 +39,9 @@ using log4net;
|
||||
|
||||
namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
{
|
||||
/// <summary>
|
||||
/// This class handles UDP texture requests.
|
||||
/// </summary>
|
||||
public class LLImageManager
|
||||
{
|
||||
private sealed class J2KImageComparer : IComparer<J2KImage>
|
||||
@@ -52,18 +55,29 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
private bool m_shuttingdown;
|
||||
private AssetBase m_missingImage;
|
||||
private LLClientView m_client; //Client we're assigned to
|
||||
private IAssetService m_assetCache; //Asset Cache
|
||||
private IJ2KDecoder m_j2kDecodeModule; //Our J2K module
|
||||
private IAssetService m_assetCache;
|
||||
private IJ2KDecoder m_j2kDecodeModule;
|
||||
|
||||
/// <summary>
|
||||
/// Priority queue for determining which image to send first.
|
||||
/// </summary>
|
||||
private C5.IntervalHeap<J2KImage> m_priorityQueue = new C5.IntervalHeap<J2KImage>(10, new J2KImageComparer());
|
||||
|
||||
/// <summary>
|
||||
/// Used to control thread access to the priority queue.
|
||||
/// </summary>
|
||||
private object m_syncRoot = new object();
|
||||
|
||||
public LLClientView Client { get { return m_client; } }
|
||||
/// <summary>
|
||||
/// Client served by this image manager
|
||||
/// </summary>
|
||||
public IClientAPI Client { get; private set; }
|
||||
|
||||
public AssetBase MissingImage { get { return m_missingImage; } }
|
||||
|
||||
public LLImageManager(LLClientView client, IAssetService pAssetCache, IJ2KDecoder pJ2kDecodeModule)
|
||||
public LLImageManager(IClientAPI client, IAssetService pAssetCache, IJ2KDecoder pJ2kDecodeModule)
|
||||
{
|
||||
m_client = client;
|
||||
Client = client;
|
||||
m_assetCache = pAssetCache;
|
||||
|
||||
if (pAssetCache != null)
|
||||
@@ -81,7 +95,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
/// <param name="newRequest"></param>
|
||||
public void EnqueueReq(TextureRequestArgs newRequest)
|
||||
{
|
||||
//Make sure we're not shutting down..
|
||||
if (!m_shuttingdown)
|
||||
{
|
||||
J2KImage imgrequest;
|
||||
@@ -96,19 +109,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
{
|
||||
//m_log.Debug("[TEX]: (CAN) ID=" + newRequest.RequestedAssetID);
|
||||
|
||||
try
|
||||
try
|
||||
{
|
||||
lock (m_syncRoot)
|
||||
m_priorityQueue.Delete(imgrequest.PriorityQueueHandle);
|
||||
m_priorityQueue.Delete(imgrequest.PriorityQueueHandle);
|
||||
}
|
||||
catch (Exception) { }
|
||||
}
|
||||
else
|
||||
{
|
||||
//m_log.DebugFormat("[TEX]: (UPD) ID={0}: D={1}, S={2}, P={3}",
|
||||
// newRequest.RequestedAssetID, newRequest.DiscardLevel, newRequest.PacketNumber, newRequest.Priority);
|
||||
// m_log.DebugFormat(
|
||||
// "[LL IMAGE MANAGER]: Received duplicate of existing request for {0}, start packet {1} from {2}",
|
||||
// newRequest.RequestedAssetID, newRequest.PacketNumber, m_client.Name);
|
||||
|
||||
//Check the packet sequence to make sure this isn't older than
|
||||
// m_log.DebugFormat("[TEX]: (UPD) ID={0}: D={1}, S={2}, P={3}",
|
||||
// newRequest.RequestedAssetID, newRequest.DiscardLevel, newRequest.PacketNumber, newRequest.Priority);
|
||||
|
||||
//Check the packet sequence to make sure this isn't older than
|
||||
//one we've already received
|
||||
if (newRequest.requestSequence > imgrequest.LastSequence)
|
||||
{
|
||||
@@ -123,11 +140,34 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
|
||||
//Update the requested priority
|
||||
imgrequest.Priority = newRequest.Priority;
|
||||
|
||||
UpdateImageInQueue(imgrequest);
|
||||
|
||||
//Run an update
|
||||
imgrequest.RunUpdate();
|
||||
|
||||
// J2KImage imgrequest2 = new J2KImage(this);
|
||||
// imgrequest2.J2KDecoder = m_j2kDecodeModule;
|
||||
// imgrequest2.AssetService = m_assetCache;
|
||||
// imgrequest2.AgentID = m_client.AgentId;
|
||||
// imgrequest2.InventoryAccessModule = m_client.Scene.RequestModuleInterface<IInventoryAccessModule>();
|
||||
// imgrequest2.DiscardLevel = newRequest.DiscardLevel;
|
||||
// imgrequest2.StartPacket = Math.Max(1, newRequest.PacketNumber);
|
||||
// imgrequest2.Priority = newRequest.Priority;
|
||||
// imgrequest2.TextureID = newRequest.RequestedAssetID;
|
||||
// imgrequest2.Priority = newRequest.Priority;
|
||||
//
|
||||
// //Add this download to the priority queue
|
||||
// AddImageToQueue(imgrequest2);
|
||||
//
|
||||
// imgrequest2.RunUpdate();
|
||||
|
||||
}
|
||||
// else
|
||||
// {
|
||||
// m_log.DebugFormat(
|
||||
// "[LL IMAGE MANAGER]: Ignoring duplicate of existing request for {0} (sequence {1}) from {2} as its request sequence {3} is not greater",
|
||||
// newRequest.RequestedAssetID, imgrequest.LastSequence, m_client.Name, newRequest.requestSequence);
|
||||
// }
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -139,14 +179,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
}
|
||||
else
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[LL IMAGE MANAGER]: Received request for {0}, start packet {1} from {2}",
|
||||
// newRequest.RequestedAssetID, newRequest.PacketNumber, m_client.Name);
|
||||
|
||||
//m_log.DebugFormat("[TEX]: (NEW) ID={0}: D={1}, S={2}, P={3}",
|
||||
// newRequest.RequestedAssetID, newRequest.DiscardLevel, newRequest.PacketNumber, newRequest.Priority);
|
||||
|
||||
imgrequest = new J2KImage(this);
|
||||
imgrequest.J2KDecoder = m_j2kDecodeModule;
|
||||
imgrequest.AssetService = m_assetCache;
|
||||
imgrequest.AgentID = m_client.AgentId;
|
||||
imgrequest.InventoryAccessModule = m_client.Scene.RequestModuleInterface<IInventoryAccessModule>();
|
||||
imgrequest.AgentID = Client.AgentId;
|
||||
imgrequest.InventoryAccessModule = Client.Scene.RequestModuleInterface<IInventoryAccessModule>();
|
||||
imgrequest.DiscardLevel = newRequest.DiscardLevel;
|
||||
imgrequest.StartPacket = Math.Max(1, newRequest.PacketNumber);
|
||||
imgrequest.Priority = newRequest.Priority;
|
||||
@@ -156,7 +200,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
//Add this download to the priority queue
|
||||
AddImageToQueue(imgrequest);
|
||||
|
||||
//Run an update
|
||||
imgrequest.RunUpdate();
|
||||
}
|
||||
}
|
||||
@@ -173,12 +216,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
|
||||
// If null was returned, the texture priority queue is currently empty
|
||||
if (image == null)
|
||||
return false;
|
||||
break;
|
||||
|
||||
if (image.IsDecoded)
|
||||
{
|
||||
int sent;
|
||||
bool imageDone = image.SendPackets(m_client, packetsToSend - packetsSent, out sent);
|
||||
bool imageDone = image.SendPackets(Client, packetsToSend - packetsSent, out sent);
|
||||
packetsSent += sent;
|
||||
|
||||
// If the send is complete, destroy any knowledge of this transfer
|
||||
@@ -191,10 +234,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
// written. Undecoded textures should not be going into the priority
|
||||
// queue, because a high priority undecoded texture will clog up the
|
||||
// pipeline for a client
|
||||
return true;
|
||||
// m_log.DebugFormat(
|
||||
// "[LL IMAGE MANAGER]: Exiting image queue processing early on encountering undecoded image {0}",
|
||||
// image.TextureID);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if (packetsSent != 0)
|
||||
// m_log.DebugFormat("[LL IMAGE MANAGER]: Processed {0} packets from image queue", packetsSent);
|
||||
|
||||
return m_priorityQueue.Count > 0;
|
||||
}
|
||||
|
||||
@@ -206,9 +256,39 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
m_shuttingdown = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clear the image queue.
|
||||
/// </summary>
|
||||
/// <returns>The number of requests cleared.</returns>
|
||||
public int ClearImageQueue()
|
||||
{
|
||||
int requestsDeleted;
|
||||
|
||||
lock (m_priorityQueue)
|
||||
{
|
||||
requestsDeleted = m_priorityQueue.Count;
|
||||
|
||||
// Surprisingly, there doesn't seem to be a clear method at this time.
|
||||
while (!m_priorityQueue.IsEmpty)
|
||||
m_priorityQueue.DeleteMax();
|
||||
}
|
||||
|
||||
return requestsDeleted;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns an array containing all the images in the queue.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public J2KImage[] GetImages()
|
||||
{
|
||||
lock (m_priorityQueue)
|
||||
return m_priorityQueue.ToArray();
|
||||
}
|
||||
|
||||
#region Priority Queue Helpers
|
||||
|
||||
J2KImage GetHighestPriorityImage()
|
||||
private J2KImage GetHighestPriorityImage()
|
||||
{
|
||||
J2KImage image = null;
|
||||
|
||||
@@ -216,34 +296,50 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
{
|
||||
if (m_priorityQueue.Count > 0)
|
||||
{
|
||||
try { image = m_priorityQueue.FindMax(); }
|
||||
try
|
||||
{
|
||||
image = m_priorityQueue.FindMax();
|
||||
}
|
||||
catch (Exception) { }
|
||||
}
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
void AddImageToQueue(J2KImage image)
|
||||
private void AddImageToQueue(J2KImage image)
|
||||
{
|
||||
image.PriorityQueueHandle = null;
|
||||
|
||||
lock (m_syncRoot)
|
||||
try { m_priorityQueue.Add(ref image.PriorityQueueHandle, image); }
|
||||
{
|
||||
try
|
||||
{
|
||||
m_priorityQueue.Add(ref image.PriorityQueueHandle, image);
|
||||
}
|
||||
catch (Exception) { }
|
||||
}
|
||||
}
|
||||
|
||||
void RemoveImageFromQueue(J2KImage image)
|
||||
{
|
||||
lock (m_syncRoot)
|
||||
try { m_priorityQueue.Delete(image.PriorityQueueHandle); }
|
||||
catch (Exception) { }
|
||||
}
|
||||
|
||||
void UpdateImageInQueue(J2KImage image)
|
||||
private void RemoveImageFromQueue(J2KImage image)
|
||||
{
|
||||
lock (m_syncRoot)
|
||||
{
|
||||
try { m_priorityQueue.Replace(image.PriorityQueueHandle, image); }
|
||||
try
|
||||
{
|
||||
m_priorityQueue.Delete(image.PriorityQueueHandle);
|
||||
}
|
||||
catch (Exception) { }
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateImageInQueue(J2KImage image)
|
||||
{
|
||||
lock (m_syncRoot)
|
||||
{
|
||||
try
|
||||
{
|
||||
m_priorityQueue.Replace(image.PriorityQueueHandle, image);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
image.PriorityQueueHandle = null;
|
||||
@@ -254,4 +350,4 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
|
||||
#endregion Priority Queue Helpers
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -158,7 +158,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
|
||||
private int m_defaultRTO = 1000; // 1sec is the recommendation in the RFC
|
||||
private int m_maxRTO = 60000;
|
||||
public bool m_deliverPackets = true;
|
||||
|
||||
/// <summary>
|
||||
/// Default constructor
|
||||
@@ -440,13 +439,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
if (category >= 0 && category < m_packetOutboxes.Length)
|
||||
{
|
||||
OpenSim.Framework.LocklessQueue<OutgoingPacket> queue = m_packetOutboxes[category];
|
||||
|
||||
if (m_deliverPackets == false)
|
||||
{
|
||||
queue.Enqueue(packet);
|
||||
return true;
|
||||
}
|
||||
|
||||
TokenBucket bucket = m_throttleCategories[category];
|
||||
|
||||
// Don't send this packet if there is already a packet waiting in the queue
|
||||
@@ -496,8 +488,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
/// <returns>True if any packets were sent, otherwise false</returns>
|
||||
public bool DequeueOutgoing()
|
||||
{
|
||||
if (m_deliverPackets == false) return false;
|
||||
|
||||
OutgoingPacket packet;
|
||||
OpenSim.Framework.LocklessQueue<OutgoingPacket> queue;
|
||||
TokenBucket bucket;
|
||||
@@ -530,7 +520,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 != null && queue.Dequeue(out packet))
|
||||
if (queue.Dequeue(out packet))
|
||||
{
|
||||
// A packet was pulled off the queue. See if we have
|
||||
// enough tokens in the bucket to send it out
|
||||
|
||||
@@ -328,7 +328,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
/// The method to call if the packet is not acked by the client. If null, then a standard
|
||||
/// resend of the packet is done.
|
||||
/// </param>
|
||||
public void SendPacket(
|
||||
public virtual void SendPacket(
|
||||
LLUDPClient udpClient, Packet packet, ThrottleOutPacketType category, bool allowSplitting, UnackedPacketMethod method)
|
||||
{
|
||||
// CoarseLocationUpdate packets cannot be split in an automated way
|
||||
@@ -492,6 +492,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
if ((Environment.TickCount & Int32.MaxValue) - udpClient.TickLastPacketReceived > 1000 * 60)
|
||||
{
|
||||
m_log.Warn("[LLUDPSERVER]: Ack timeout, disconnecting " + udpClient.AgentID);
|
||||
StatsManager.SimExtraStats.AddAbnormalClientThreadTermination();
|
||||
|
||||
RemoveClient(udpClient);
|
||||
return;
|
||||
@@ -611,11 +612,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
outgoingPacket.TickCount = Environment.TickCount & Int32.MaxValue;
|
||||
}
|
||||
|
||||
protected override void PacketReceived(UDPPacketBuffer buffer)
|
||||
public override void PacketReceived(UDPPacketBuffer buffer)
|
||||
{
|
||||
// Debugging/Profiling
|
||||
//try { Thread.CurrentThread.Name = "PacketReceived (" + m_scene.RegionInfo.RegionName + ")"; }
|
||||
//catch (Exception) { }
|
||||
// m_log.DebugFormat(
|
||||
// "[LLUDPSERVER]: Packet received from {0} in {1}", buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName);
|
||||
|
||||
LLUDPClient udpClient = null;
|
||||
Packet packet = null;
|
||||
@@ -625,7 +628,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
#region Decoding
|
||||
|
||||
if (buffer.DataLength < 7)
|
||||
{
|
||||
// m_log.WarnFormat(
|
||||
// "[LLUDPSERVER]: Dropping undersized packet with {0} bytes received from {1} in {2}",
|
||||
// buffer.DataLength, buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName);
|
||||
|
||||
return; // Drop undersizd packet
|
||||
}
|
||||
|
||||
int headerLen = 7;
|
||||
if (buffer.Data[6] == 0xFF)
|
||||
@@ -637,7 +646,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
}
|
||||
|
||||
if (buffer.DataLength < headerLen)
|
||||
{
|
||||
// m_log.WarnFormat(
|
||||
// "[LLUDPSERVER]: Dropping packet with malformed header received from {0} in {1}",
|
||||
// buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName);
|
||||
|
||||
return; // Malformed header
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
@@ -650,6 +665,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
}
|
||||
catch (IndexOutOfRangeException)
|
||||
{
|
||||
// m_log.WarnFormat(
|
||||
// "[LLUDPSERVER]: Dropping short packet received from {0} in {1}",
|
||||
// buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName);
|
||||
|
||||
return; // Drop short packet
|
||||
}
|
||||
catch(Exception e)
|
||||
@@ -887,23 +906,55 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
// DateTime startTime = DateTime.Now;
|
||||
object[] array = (object[])o;
|
||||
UDPPacketBuffer buffer = (UDPPacketBuffer)array[0];
|
||||
UseCircuitCodePacket packet = (UseCircuitCodePacket)array[1];
|
||||
UseCircuitCodePacket uccp = (UseCircuitCodePacket)array[1];
|
||||
|
||||
m_log.DebugFormat("[LLUDPSERVER]: Handling UseCircuitCode request from {0}", buffer.RemoteEndPoint);
|
||||
|
||||
IPEndPoint remoteEndPoint = (IPEndPoint)buffer.RemoteEndPoint;
|
||||
|
||||
// Begin the process of adding the client to the simulator
|
||||
AddNewClient((UseCircuitCodePacket)packet, remoteEndPoint);
|
||||
|
||||
// Send ack
|
||||
SendAckImmediate(remoteEndPoint, packet.Header.Sequence);
|
||||
AuthenticateResponse sessionInfo;
|
||||
if (IsClientAuthorized(uccp, out sessionInfo))
|
||||
{
|
||||
// Begin the process of adding the client to the simulator
|
||||
IClientAPI client
|
||||
= AddClient(
|
||||
uccp.CircuitCode.Code,
|
||||
uccp.CircuitCode.ID,
|
||||
uccp.CircuitCode.SessionID,
|
||||
remoteEndPoint,
|
||||
sessionInfo);
|
||||
|
||||
// Send ack straight away to let the viewer know that the connection is active.
|
||||
// The client will be null if it already exists (e.g. if on a region crossing the client sends a use
|
||||
// circuit code to the existing child agent. This is not particularly obvious.
|
||||
SendAckImmediate(remoteEndPoint, uccp.Header.Sequence);
|
||||
|
||||
// We only want to send initial data to new clients, not ones which are being converted from child to root.
|
||||
if (client != null)
|
||||
client.SceneAgent.SendInitialDataToMe();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Don't create clients for unauthorized requesters.
|
||||
m_log.WarnFormat(
|
||||
"[LLUDPSERVER]: Connection request for client {0} connecting with unnotified circuit code {1} from {2}",
|
||||
uccp.CircuitCode.ID, uccp.CircuitCode.Code, remoteEndPoint);
|
||||
}
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[LLUDPSERVER]: Handling UseCircuitCode request from {0} took {1}ms",
|
||||
// buffer.RemoteEndPoint, (DateTime.Now - startTime).Milliseconds);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send an ack immediately to the given endpoint.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// FIXME: Might be possible to use SendPacketData() like everything else, but this will require refactoring so
|
||||
/// that we can obtain the UDPClient easily at this point.
|
||||
/// </remarks>
|
||||
/// <param name="remoteEndpoint"></param>
|
||||
/// <param name="sequenceNumber"></param>
|
||||
private void SendAckImmediate(IPEndPoint remoteEndpoint, uint sequenceNumber)
|
||||
{
|
||||
PacketAckPacket ack = new PacketAckPacket();
|
||||
@@ -912,6 +963,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
ack.Packets[0] = new PacketAckPacket.PacketsBlock();
|
||||
ack.Packets[0].ID = sequenceNumber;
|
||||
|
||||
SendAckImmediate(remoteEndpoint, ack);
|
||||
}
|
||||
|
||||
public virtual void SendAckImmediate(IPEndPoint remoteEndpoint, PacketAckPacket ack)
|
||||
{
|
||||
byte[] packetData = ack.ToBytes();
|
||||
int length = packetData.Length;
|
||||
|
||||
@@ -933,55 +989,39 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
return sessionInfo.Authorised;
|
||||
}
|
||||
|
||||
private void AddNewClient(UseCircuitCodePacket useCircuitCode, IPEndPoint remoteEndPoint)
|
||||
/// <summary>
|
||||
/// Add a client.
|
||||
/// </summary>
|
||||
/// <param name="circuitCode"></param>
|
||||
/// <param name="agentID"></param>
|
||||
/// <param name="sessionID"></param>
|
||||
/// <param name="remoteEndPoint"></param>
|
||||
/// <param name="sessionInfo"></param>
|
||||
/// <returns>The client if it was added. Null if the client already existed.</returns>
|
||||
protected virtual IClientAPI AddClient(
|
||||
uint circuitCode, UUID agentID, UUID sessionID, IPEndPoint remoteEndPoint, AuthenticateResponse sessionInfo)
|
||||
{
|
||||
UUID agentID = useCircuitCode.CircuitCode.ID;
|
||||
UUID sessionID = useCircuitCode.CircuitCode.SessionID;
|
||||
uint circuitCode = useCircuitCode.CircuitCode.Code;
|
||||
IClientAPI client = null;
|
||||
|
||||
AuthenticateResponse sessionInfo;
|
||||
if (IsClientAuthorized(useCircuitCode, out sessionInfo))
|
||||
{
|
||||
AddClient(circuitCode, agentID, sessionID, remoteEndPoint, sessionInfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Don't create circuits for unauthorized clients
|
||||
m_log.WarnFormat(
|
||||
"[LLUDPSERVER]: Connection request for client {0} connecting with unnotified circuit code {1} from {2}",
|
||||
useCircuitCode.CircuitCode.ID, useCircuitCode.CircuitCode.Code, remoteEndPoint);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void AddClient(uint circuitCode, UUID agentID, UUID sessionID, IPEndPoint remoteEndPoint, AuthenticateResponse sessionInfo)
|
||||
{
|
||||
// In priciple there shouldn't be more than one thread here, ever.
|
||||
// But in case that happens, we need to synchronize this piece of code
|
||||
// because it's too important
|
||||
lock (this)
|
||||
{
|
||||
IClientAPI existingClient;
|
||||
|
||||
if (!m_scene.TryGetClient(agentID, out existingClient))
|
||||
if (!m_scene.TryGetClient(agentID, out client))
|
||||
{
|
||||
// Create the LLUDPClient
|
||||
LLUDPClient udpClient = new LLUDPClient(this, ThrottleRates, m_throttle, circuitCode, agentID, remoteEndPoint, m_defaultRTO, m_maxRTO);
|
||||
// Create the LLClientView
|
||||
LLClientView client = new LLClientView(remoteEndPoint, m_scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode);
|
||||
|
||||
client = new LLClientView(remoteEndPoint, m_scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode);
|
||||
client.OnLogout += LogoutHandler;
|
||||
|
||||
client.DisableFacelights = m_disableFacelights;
|
||||
((LLClientView)client).DisableFacelights = m_disableFacelights;
|
||||
|
||||
// Start the IClientAPI
|
||||
client.Start();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.WarnFormat("[LLUDPSERVER]: Ignoring a repeated UseCircuitCode from {0} at {1} for circuit {2}",
|
||||
existingClient.AgentId, remoteEndPoint, circuitCode);
|
||||
}
|
||||
}
|
||||
|
||||
return client;
|
||||
}
|
||||
|
||||
private void RemoveClient(LLUDPClient udpClient)
|
||||
@@ -991,7 +1031,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
if (m_scene.TryGetClient(udpClient.AgentID, out client))
|
||||
{
|
||||
client.IsLoggingOut = true;
|
||||
client.Close(false);
|
||||
client.Close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1003,7 +1043,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
|
||||
while (base.IsRunning)
|
||||
{
|
||||
m_scene.ThreadAlive(1);
|
||||
try
|
||||
{
|
||||
IncomingPacket incomingPacket = null;
|
||||
@@ -1046,7 +1085,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
|
||||
while (base.IsRunning)
|
||||
{
|
||||
m_scene.ThreadAlive(2);
|
||||
try
|
||||
{
|
||||
m_packetSent = false;
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace OpenMetaverse
|
||||
/// This method is called when an incoming packet is received
|
||||
/// </summary>
|
||||
/// <param name="buffer">Incoming packet buffer</param>
|
||||
protected abstract void PacketReceived(UDPPacketBuffer buffer);
|
||||
public abstract void PacketReceived(UDPPacketBuffer buffer);
|
||||
|
||||
/// <summary>UDP port to bind to in server mode</summary>
|
||||
protected int m_udpPort;
|
||||
@@ -100,6 +100,10 @@ namespace OpenMetaverse
|
||||
const int SIO_UDP_CONNRESET = -1744830452;
|
||||
|
||||
IPEndPoint ipep = new IPEndPoint(m_localBindAddress, m_udpPort);
|
||||
|
||||
m_log.DebugFormat(
|
||||
"[UDPBASE]: Binding UDP listener using internal IP address config {0}:{1}",
|
||||
ipep.Address, ipep.Port);
|
||||
|
||||
m_udpSocket = new Socket(
|
||||
AddressFamily.InterNetwork,
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Net;
|
||||
using log4net.Config;
|
||||
using Nini.Config;
|
||||
@@ -32,6 +33,7 @@ using NUnit.Framework;
|
||||
using OpenMetaverse;
|
||||
using OpenMetaverse.Packets;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Tests.Common;
|
||||
using OpenSim.Tests.Common.Mock;
|
||||
|
||||
@@ -43,19 +45,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
|
||||
[TestFixture]
|
||||
public class BasicCircuitTests
|
||||
{
|
||||
[SetUp]
|
||||
public void Init()
|
||||
[TestFixtureSetUp]
|
||||
public void FixtureInit()
|
||||
{
|
||||
try
|
||||
{
|
||||
XmlConfigurator.Configure();
|
||||
}
|
||||
catch
|
||||
{
|
||||
// I don't care, just leave log4net off
|
||||
}
|
||||
// Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread.
|
||||
Util.FireAndForgetMethod = FireAndForgetMethod.RegressionTest;
|
||||
}
|
||||
|
||||
|
||||
[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 so none of them require async stuff (which regression
|
||||
// tests really shouldn't).
|
||||
Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod;
|
||||
}
|
||||
|
||||
// /// <summary>
|
||||
// /// Add a client for testing
|
||||
// /// </summary>
|
||||
@@ -78,54 +83,54 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
|
||||
// testLLUDPServer.LocalScene = scene;
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// Set up a client for tests which aren't concerned with this process itself and where only one client is being
|
||||
/// tested
|
||||
/// </summary>
|
||||
/// <param name="circuitCode"></param>
|
||||
/// <param name="epSender"></param>
|
||||
/// <param name="testLLUDPServer"></param>
|
||||
/// <param name="acm"></param>
|
||||
protected void AddClient(
|
||||
uint circuitCode, EndPoint epSender, TestLLUDPServer testLLUDPServer, AgentCircuitManager acm)
|
||||
{
|
||||
UUID myAgentUuid = UUID.Parse("00000000-0000-0000-0000-000000000001");
|
||||
UUID mySessionUuid = UUID.Parse("00000000-0000-0000-0000-000000000002");
|
||||
|
||||
AddClient(circuitCode, epSender, myAgentUuid, mySessionUuid, testLLUDPServer, acm);
|
||||
}
|
||||
// /// <summary>
|
||||
// /// Set up a client for tests which aren't concerned with this process itself and where only one client is being
|
||||
// /// tested
|
||||
// /// </summary>
|
||||
// /// <param name="circuitCode"></param>
|
||||
// /// <param name="epSender"></param>
|
||||
// /// <param name="testLLUDPServer"></param>
|
||||
// /// <param name="acm"></param>
|
||||
// protected void AddClient(
|
||||
// uint circuitCode, EndPoint epSender, TestLLUDPServer testLLUDPServer, AgentCircuitManager acm)
|
||||
// {
|
||||
// UUID myAgentUuid = UUID.Parse("00000000-0000-0000-0000-000000000001");
|
||||
// UUID mySessionUuid = UUID.Parse("00000000-0000-0000-0000-000000000002");
|
||||
//
|
||||
// AddClient(circuitCode, epSender, myAgentUuid, mySessionUuid, testLLUDPServer, acm);
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// Set up a client for tests which aren't concerned with this process itself
|
||||
/// </summary>
|
||||
/// <param name="circuitCode"></param>
|
||||
/// <param name="epSender"></param>
|
||||
/// <param name="agentId"></param>
|
||||
/// <param name="sessionId"></param>
|
||||
/// <param name="testLLUDPServer"></param>
|
||||
/// <param name="acm"></param>
|
||||
protected void AddClient(
|
||||
uint circuitCode, EndPoint epSender, UUID agentId, UUID sessionId,
|
||||
TestLLUDPServer testLLUDPServer, AgentCircuitManager acm)
|
||||
{
|
||||
AgentCircuitData acd = new AgentCircuitData();
|
||||
acd.AgentID = agentId;
|
||||
acd.SessionID = sessionId;
|
||||
|
||||
UseCircuitCodePacket uccp = new UseCircuitCodePacket();
|
||||
|
||||
UseCircuitCodePacket.CircuitCodeBlock uccpCcBlock
|
||||
= new UseCircuitCodePacket.CircuitCodeBlock();
|
||||
uccpCcBlock.Code = circuitCode;
|
||||
uccpCcBlock.ID = agentId;
|
||||
uccpCcBlock.SessionID = sessionId;
|
||||
uccp.CircuitCode = uccpCcBlock;
|
||||
|
||||
acm.AddNewCircuit(circuitCode, acd);
|
||||
|
||||
testLLUDPServer.LoadReceive(uccp, epSender);
|
||||
testLLUDPServer.ReceiveData(null);
|
||||
}
|
||||
// /// <summary>
|
||||
// /// Set up a client for tests which aren't concerned with this process itself
|
||||
// /// </summary>
|
||||
// /// <param name="circuitCode"></param>
|
||||
// /// <param name="epSender"></param>
|
||||
// /// <param name="agentId"></param>
|
||||
// /// <param name="sessionId"></param>
|
||||
// /// <param name="testLLUDPServer"></param>
|
||||
// /// <param name="acm"></param>
|
||||
// protected void AddClient(
|
||||
// uint circuitCode, EndPoint epSender, UUID agentId, UUID sessionId,
|
||||
// TestLLUDPServer testLLUDPServer, AgentCircuitManager acm)
|
||||
// {
|
||||
// AgentCircuitData acd = new AgentCircuitData();
|
||||
// acd.AgentID = agentId;
|
||||
// acd.SessionID = sessionId;
|
||||
//
|
||||
// UseCircuitCodePacket uccp = new UseCircuitCodePacket();
|
||||
//
|
||||
// UseCircuitCodePacket.CircuitCodeBlock uccpCcBlock
|
||||
// = new UseCircuitCodePacket.CircuitCodeBlock();
|
||||
// uccpCcBlock.Code = circuitCode;
|
||||
// uccpCcBlock.ID = agentId;
|
||||
// uccpCcBlock.SessionID = sessionId;
|
||||
// uccp.CircuitCode = uccpCcBlock;
|
||||
//
|
||||
// acm.AddNewCircuit(circuitCode, acd);
|
||||
//
|
||||
// testLLUDPServer.LoadReceive(uccp, epSender);
|
||||
// testLLUDPServer.ReceiveData(null);
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// Build an object name packet for test purposes
|
||||
@@ -144,54 +149,69 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
|
||||
return onp;
|
||||
}
|
||||
|
||||
// /// <summary>
|
||||
// /// Test adding a client to the stack
|
||||
// /// </summary>
|
||||
// [Test]
|
||||
// public void TestAddClient()
|
||||
// {
|
||||
// TestHelper.InMethod();
|
||||
//
|
||||
// uint myCircuitCode = 123456;
|
||||
// UUID myAgentUuid = UUID.Parse("00000000-0000-0000-0000-000000000001");
|
||||
// UUID mySessionUuid = UUID.Parse("00000000-0000-0000-0000-000000000002");
|
||||
//
|
||||
// TestLLUDPServer testLLUDPServer;
|
||||
// TestLLPacketServer testLLPacketServer;
|
||||
// AgentCircuitManager acm;
|
||||
// SetupStack(new MockScene(), out testLLUDPServer, out testLLPacketServer, out acm);
|
||||
//
|
||||
// AgentCircuitData acd = new AgentCircuitData();
|
||||
// acd.AgentID = myAgentUuid;
|
||||
// acd.SessionID = mySessionUuid;
|
||||
//
|
||||
// UseCircuitCodePacket uccp = new UseCircuitCodePacket();
|
||||
//
|
||||
// UseCircuitCodePacket.CircuitCodeBlock uccpCcBlock
|
||||
// = new UseCircuitCodePacket.CircuitCodeBlock();
|
||||
// uccpCcBlock.Code = myCircuitCode;
|
||||
// uccpCcBlock.ID = myAgentUuid;
|
||||
// uccpCcBlock.SessionID = mySessionUuid;
|
||||
// uccp.CircuitCode = uccpCcBlock;
|
||||
//
|
||||
// EndPoint testEp = new IPEndPoint(IPAddress.Loopback, 999);
|
||||
//
|
||||
// testLLUDPServer.LoadReceive(uccp, testEp);
|
||||
// testLLUDPServer.ReceiveData(null);
|
||||
//
|
||||
// // Circuit shouildn't exist since the circuit manager doesn't know about this circuit for authentication yet
|
||||
// Assert.IsFalse(testLLUDPServer.HasCircuit(myCircuitCode));
|
||||
//
|
||||
// acm.AddNewCircuit(myCircuitCode, acd);
|
||||
//
|
||||
// testLLUDPServer.LoadReceive(uccp, testEp);
|
||||
// testLLUDPServer.ReceiveData(null);
|
||||
//
|
||||
// // Should succeed now
|
||||
// Assert.IsTrue(testLLUDPServer.HasCircuit(myCircuitCode));
|
||||
// Assert.IsFalse(testLLUDPServer.HasCircuit(101));
|
||||
// }
|
||||
//
|
||||
/// <summary>
|
||||
/// Test adding a client to the stack
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestAddClient()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// XmlConfigurator.Configure();
|
||||
|
||||
TestScene scene = SceneHelpers.SetupScene();
|
||||
uint myCircuitCode = 123456;
|
||||
UUID myAgentUuid = TestHelpers.ParseTail(0x1);
|
||||
UUID mySessionUuid = TestHelpers.ParseTail(0x2);
|
||||
IPEndPoint testEp = new IPEndPoint(IPAddress.Loopback, 999);
|
||||
|
||||
uint port = 0;
|
||||
AgentCircuitManager acm = scene.AuthenticateHandler;
|
||||
|
||||
TestLLUDPServer llUdpServer
|
||||
= new TestLLUDPServer(IPAddress.Any, ref port, 0, false, new IniConfigSource(), acm);
|
||||
llUdpServer.AddScene(scene);
|
||||
|
||||
UseCircuitCodePacket uccp = new UseCircuitCodePacket();
|
||||
|
||||
UseCircuitCodePacket.CircuitCodeBlock uccpCcBlock
|
||||
= new UseCircuitCodePacket.CircuitCodeBlock();
|
||||
uccpCcBlock.Code = myCircuitCode;
|
||||
uccpCcBlock.ID = myAgentUuid;
|
||||
uccpCcBlock.SessionID = mySessionUuid;
|
||||
uccp.CircuitCode = uccpCcBlock;
|
||||
|
||||
byte[] uccpBytes = uccp.ToBytes();
|
||||
UDPPacketBuffer upb = new UDPPacketBuffer(testEp, uccpBytes.Length);
|
||||
upb.DataLength = uccpBytes.Length; // God knows why this isn't set by the constructor.
|
||||
Buffer.BlockCopy(uccpBytes, 0, upb.Data, 0, uccpBytes.Length);
|
||||
|
||||
llUdpServer.PacketReceived(upb);
|
||||
|
||||
// Presence shouldn't exist since the circuit manager doesn't know about this circuit for authentication yet
|
||||
Assert.That(scene.GetScenePresence(myAgentUuid), Is.Null);
|
||||
|
||||
AgentCircuitData acd = new AgentCircuitData();
|
||||
acd.AgentID = myAgentUuid;
|
||||
acd.SessionID = mySessionUuid;
|
||||
|
||||
acm.AddNewCircuit(myCircuitCode, acd);
|
||||
|
||||
llUdpServer.PacketReceived(upb);
|
||||
|
||||
// Should succeed now
|
||||
ScenePresence sp = scene.GetScenePresence(myAgentUuid);
|
||||
Assert.That(sp.UUID, Is.EqualTo(myAgentUuid));
|
||||
|
||||
Assert.That(llUdpServer.PacketsSent.Count, Is.EqualTo(1));
|
||||
|
||||
Packet packet = llUdpServer.PacketsSent[0];
|
||||
Assert.That(packet, Is.InstanceOf(typeof(PacketAckPacket)));
|
||||
|
||||
PacketAckPacket ackPacket = packet as PacketAckPacket;
|
||||
Assert.That(ackPacket.Packets.Length, Is.EqualTo(1));
|
||||
Assert.That(ackPacket.Packets[0].ID, Is.EqualTo(0));
|
||||
}
|
||||
|
||||
// /// <summary>
|
||||
// /// Test removing a client from the stack
|
||||
// /// </summary>
|
||||
|
||||
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Reflection;
|
||||
using log4net.Config;
|
||||
using Nini.Config;
|
||||
using NUnit.Framework;
|
||||
using OpenMetaverse;
|
||||
using OpenMetaverse.Packets;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.CoreModules.Agent.TextureSender;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Tests.Common;
|
||||
using OpenSim.Tests.Common.Mock;
|
||||
|
||||
namespace OpenSim.Region.ClientStack.LindenUDP.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class LLImageManagerTests
|
||||
{
|
||||
private AssetBase m_testImageAsset;
|
||||
private Scene scene;
|
||||
private LLImageManager llim;
|
||||
private TestClient tc;
|
||||
|
||||
[TestFixtureSetUp]
|
||||
public void FixtureInit()
|
||||
{
|
||||
using (
|
||||
Stream resource
|
||||
= GetType().Assembly.GetManifestResourceStream(
|
||||
"OpenSim.Region.ClientStack.LindenUDP.Tests.Resources.4-tile2.jp2"))
|
||||
{
|
||||
using (BinaryReader br = new BinaryReader(resource))
|
||||
{
|
||||
m_testImageAsset
|
||||
= new AssetBase(
|
||||
TestHelpers.ParseTail(0x1),
|
||||
"Test Image",
|
||||
(sbyte)AssetType.Texture,
|
||||
TestHelpers.ParseTail(0x2).ToString());
|
||||
|
||||
m_testImageAsset.Data = br.ReadBytes(99999999);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
UUID userId = TestHelpers.ParseTail(0x3);
|
||||
|
||||
J2KDecoderModule j2kdm = new J2KDecoderModule();
|
||||
|
||||
scene = SceneHelpers.SetupScene();
|
||||
SceneHelpers.SetupSceneModules(scene, j2kdm);
|
||||
|
||||
tc = new TestClient(SceneHelpers.GenerateAgentData(userId), scene);
|
||||
llim = new LLImageManager(tc, scene.AssetService, j2kdm);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestSendImage()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// XmlConfigurator.Configure();
|
||||
|
||||
scene.AssetService.Store(m_testImageAsset);
|
||||
|
||||
TextureRequestArgs args = new TextureRequestArgs();
|
||||
args.RequestedAssetID = m_testImageAsset.FullID;
|
||||
args.DiscardLevel = 0;
|
||||
args.PacketNumber = 1;
|
||||
args.Priority = 5;
|
||||
args.requestSequence = 1;
|
||||
|
||||
llim.EnqueueReq(args);
|
||||
llim.ProcessImageQueue(20);
|
||||
|
||||
Assert.That(tc.SentImageDataPackets.Count, Is.EqualTo(1));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDiscardImage()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// XmlConfigurator.Configure();
|
||||
|
||||
scene.AssetService.Store(m_testImageAsset);
|
||||
|
||||
TextureRequestArgs args = new TextureRequestArgs();
|
||||
args.RequestedAssetID = m_testImageAsset.FullID;
|
||||
args.DiscardLevel = 0;
|
||||
args.PacketNumber = 1;
|
||||
args.Priority = 5;
|
||||
args.requestSequence = 1;
|
||||
llim.EnqueueReq(args);
|
||||
|
||||
// Now create a discard request
|
||||
TextureRequestArgs discardArgs = new TextureRequestArgs();
|
||||
discardArgs.RequestedAssetID = m_testImageAsset.FullID;
|
||||
discardArgs.DiscardLevel = -1;
|
||||
discardArgs.PacketNumber = 1;
|
||||
discardArgs.Priority = 0;
|
||||
discardArgs.requestSequence = 2;
|
||||
llim.EnqueueReq(discardArgs);
|
||||
|
||||
llim.ProcessImageQueue(20);
|
||||
|
||||
Assert.That(tc.SentImageDataPackets.Count, Is.EqualTo(0));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestMissingImage()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// XmlConfigurator.Configure();
|
||||
|
||||
TextureRequestArgs args = new TextureRequestArgs();
|
||||
args.RequestedAssetID = m_testImageAsset.FullID;
|
||||
args.DiscardLevel = 0;
|
||||
args.PacketNumber = 1;
|
||||
args.Priority = 5;
|
||||
args.requestSequence = 1;
|
||||
|
||||
llim.EnqueueReq(args);
|
||||
llim.ProcessImageQueue(20);
|
||||
|
||||
Assert.That(tc.SentImageDataPackets.Count, Is.EqualTo(0));
|
||||
Assert.That(tc.SentImageNotInDatabasePackets.Count, Is.EqualTo(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -53,9 +53,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
|
||||
public override void Update() {}
|
||||
public override void LoadWorldMap() {}
|
||||
|
||||
public override void AddNewClient(IClientAPI client, PresenceType type)
|
||||
public override ISceneAgent AddNewClient(IClientAPI client, PresenceType type)
|
||||
{
|
||||
client.OnObjectName += RecordObjectNameCall;
|
||||
|
||||
// FIXME
|
||||
return null;
|
||||
}
|
||||
|
||||
public override void RemoveClient(UUID agentID, bool someReason) {}
|
||||
|
||||
Binary file not shown.
@@ -36,107 +36,106 @@ using OpenSim.Framework;
|
||||
namespace OpenSim.Region.ClientStack.LindenUDP.Tests
|
||||
{
|
||||
/// <summary>
|
||||
/// This class enables synchronous testing of the LLUDPServer by allowing us to load our own data into the end
|
||||
/// receive event
|
||||
/// This class enables regression testing of the LLUDPServer by allowing us to intercept outgoing data.
|
||||
/// </summary>
|
||||
public class TestLLUDPServer : LLUDPServer
|
||||
{
|
||||
public List<Packet> PacketsSent { get; private set; }
|
||||
|
||||
public TestLLUDPServer(IPAddress listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port, IConfigSource configSource, AgentCircuitManager circuitManager)
|
||||
: base(listenIP, ref port, proxyPortOffsetParm, allow_alternate_port, configSource, circuitManager)
|
||||
{}
|
||||
{
|
||||
PacketsSent = new List<Packet>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The chunks of data to pass to the LLUDPServer when it calls EndReceive
|
||||
/// </summary>
|
||||
protected Queue<ChunkSenderTuple> m_chunksToLoad = new Queue<ChunkSenderTuple>();
|
||||
|
||||
// protected override void BeginReceive()
|
||||
// {
|
||||
// if (m_chunksToLoad.Count > 0 && m_chunksToLoad.Peek().BeginReceiveException)
|
||||
// {
|
||||
// ChunkSenderTuple tuple = m_chunksToLoad.Dequeue();
|
||||
// reusedEpSender = tuple.Sender;
|
||||
// throw new SocketException();
|
||||
// }
|
||||
// }
|
||||
|
||||
// protected override bool EndReceive(out int numBytes, IAsyncResult result, ref EndPoint epSender)
|
||||
// {
|
||||
// numBytes = 0;
|
||||
//
|
||||
// //m_log.Debug("Queue size " + m_chunksToLoad.Count);
|
||||
//
|
||||
// if (m_chunksToLoad.Count <= 0)
|
||||
// return false;
|
||||
//
|
||||
// ChunkSenderTuple tuple = m_chunksToLoad.Dequeue();
|
||||
// RecvBuffer = tuple.Data;
|
||||
// numBytes = tuple.Data.Length;
|
||||
// epSender = tuple.Sender;
|
||||
//
|
||||
// return true;
|
||||
// }
|
||||
|
||||
// public override void SendPacketTo(byte[] buffer, int size, SocketFlags flags, uint circuitcode)
|
||||
// {
|
||||
// // Don't do anything just yet
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// Signal that this chunk should throw an exception on Socket.BeginReceive()
|
||||
/// </summary>
|
||||
/// <param name="epSender"></param>
|
||||
public void LoadReceiveWithBeginException(EndPoint epSender)
|
||||
public override void SendAckImmediate(IPEndPoint remoteEndpoint, PacketAckPacket ack)
|
||||
{
|
||||
ChunkSenderTuple tuple = new ChunkSenderTuple(epSender);
|
||||
tuple.BeginReceiveException = true;
|
||||
m_chunksToLoad.Enqueue(tuple);
|
||||
PacketsSent.Add(ack);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Load some data to be received by the LLUDPServer on the next receive call
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <param name="epSender"></param>
|
||||
public void LoadReceive(byte[] data, EndPoint epSender)
|
||||
{
|
||||
m_chunksToLoad.Enqueue(new ChunkSenderTuple(data, epSender));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Load a packet to be received by the LLUDPServer on the next receive call
|
||||
/// </summary>
|
||||
/// <param name="packet"></param>
|
||||
public void LoadReceive(Packet packet, EndPoint epSender)
|
||||
{
|
||||
LoadReceive(packet.ToBytes(), epSender);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calls the protected asynchronous result method. This fires out all data chunks currently queued for send
|
||||
/// </summary>
|
||||
/// <param name="result"></param>
|
||||
public void ReceiveData(IAsyncResult result)
|
||||
{
|
||||
// Doesn't work the same way anymore
|
||||
// while (m_chunksToLoad.Count > 0)
|
||||
// OnReceivedData(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Has a circuit with the given code been established?
|
||||
/// </summary>
|
||||
/// <param name="circuitCode"></param>
|
||||
/// <returns></returns>
|
||||
public bool HasCircuit(uint circuitCode)
|
||||
{
|
||||
// lock (clientCircuits_reverse)
|
||||
// {
|
||||
// return clientCircuits_reverse.ContainsKey(circuitCode);
|
||||
// }
|
||||
|
||||
return true;
|
||||
public override void SendPacket(
|
||||
LLUDPClient udpClient, Packet packet, ThrottleOutPacketType category, bool allowSplitting, UnackedPacketMethod method)
|
||||
{
|
||||
PacketsSent.Add(packet);
|
||||
}
|
||||
|
||||
//// /// <summary>
|
||||
//// /// The chunks of data to pass to the LLUDPServer when it calls EndReceive
|
||||
//// /// </summary>
|
||||
//// protected Queue<ChunkSenderTuple> m_chunksToLoad = new Queue<ChunkSenderTuple>();
|
||||
//
|
||||
//// protected override void BeginReceive()
|
||||
//// {
|
||||
//// if (m_chunksToLoad.Count > 0 && m_chunksToLoad.Peek().BeginReceiveException)
|
||||
//// {
|
||||
//// ChunkSenderTuple tuple = m_chunksToLoad.Dequeue();
|
||||
//// reusedEpSender = tuple.Sender;
|
||||
//// throw new SocketException();
|
||||
//// }
|
||||
//// }
|
||||
//
|
||||
//// protected override bool EndReceive(out int numBytes, IAsyncResult result, ref EndPoint epSender)
|
||||
//// {
|
||||
//// numBytes = 0;
|
||||
////
|
||||
//// //m_log.Debug("Queue size " + m_chunksToLoad.Count);
|
||||
////
|
||||
//// if (m_chunksToLoad.Count <= 0)
|
||||
//// return false;
|
||||
////
|
||||
//// ChunkSenderTuple tuple = m_chunksToLoad.Dequeue();
|
||||
//// RecvBuffer = tuple.Data;
|
||||
//// numBytes = tuple.Data.Length;
|
||||
//// epSender = tuple.Sender;
|
||||
////
|
||||
//// return true;
|
||||
//// }
|
||||
//
|
||||
//// public override void SendPacketTo(byte[] buffer, int size, SocketFlags flags, uint circuitcode)
|
||||
//// {
|
||||
//// // Don't do anything just yet
|
||||
//// }
|
||||
//
|
||||
// /// <summary>
|
||||
// /// Signal that this chunk should throw an exception on Socket.BeginReceive()
|
||||
// /// </summary>
|
||||
// /// <param name="epSender"></param>
|
||||
// public void LoadReceiveWithBeginException(EndPoint epSender)
|
||||
// {
|
||||
// ChunkSenderTuple tuple = new ChunkSenderTuple(epSender);
|
||||
// tuple.BeginReceiveException = true;
|
||||
// m_chunksToLoad.Enqueue(tuple);
|
||||
// }
|
||||
//
|
||||
// /// <summary>
|
||||
// /// Load some data to be received by the LLUDPServer on the next receive call
|
||||
// /// </summary>
|
||||
// /// <param name="data"></param>
|
||||
// /// <param name="epSender"></param>
|
||||
// public void LoadReceive(byte[] data, EndPoint epSender)
|
||||
// {
|
||||
// m_chunksToLoad.Enqueue(new ChunkSenderTuple(data, epSender));
|
||||
// }
|
||||
//
|
||||
// /// <summary>
|
||||
// /// Load a packet to be received by the LLUDPServer on the next receive call
|
||||
// /// </summary>
|
||||
// /// <param name="packet"></param>
|
||||
// public void LoadReceive(Packet packet, EndPoint epSender)
|
||||
// {
|
||||
// LoadReceive(packet.ToBytes(), epSender);
|
||||
// }
|
||||
//
|
||||
// /// <summary>
|
||||
// /// Calls the protected asynchronous result method. This fires out all data chunks currently queued for send
|
||||
// /// </summary>
|
||||
// /// <param name="result"></param>
|
||||
// public void ReceiveData(IAsyncResult result)
|
||||
// {
|
||||
// // Doesn't work the same way anymore
|
||||
//// while (m_chunksToLoad.Count > 0)
|
||||
//// OnReceivedData(result);
|
||||
// }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -46,6 +46,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
||||
// Fields
|
||||
private bool m_dumpAssetsToFile;
|
||||
private Scene m_Scene;
|
||||
private UUID UserID;
|
||||
private Dictionary<UUID, AssetXferUploader> XferUploaders = new Dictionary<UUID, AssetXferUploader>();
|
||||
|
||||
// Methods
|
||||
@@ -53,6 +54,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
||||
bool dumpAssetsToFile)
|
||||
{
|
||||
m_Scene = scene;
|
||||
UserID = agentID;
|
||||
m_dumpAssetsToFile = dumpAssetsToFile;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Collections.Generic;
|
||||
using log4net;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
@@ -39,13 +38,6 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
||||
{
|
||||
public class AssetXferUploader
|
||||
{
|
||||
// Viewer's notion of the default texture
|
||||
private List<UUID> defaultIDs = new List<UUID> {
|
||||
new UUID("5748decc-f629-461c-9a36-a35a221fe21f"),
|
||||
new UUID("7ca39b4c-bd19-4699-aff7-f93fd03d3e7b"),
|
||||
new UUID("6522e74d-1660-4e7f-b601-6f48c1659a77"),
|
||||
new UUID("c228d1cf-4b5d-4ba8-84f4-899a0796aa97")
|
||||
};
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
/// <summary>
|
||||
@@ -73,7 +65,6 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
||||
private UUID TransactionID = UUID.Zero;
|
||||
private sbyte type = 0;
|
||||
private byte wearableType = 0;
|
||||
private byte[] m_oldData = null;
|
||||
public ulong XferID;
|
||||
private Scene m_Scene;
|
||||
|
||||
@@ -311,7 +302,6 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
||||
|
||||
private void DoCreateItem(uint callbackID)
|
||||
{
|
||||
ValidateAssets();
|
||||
m_Scene.AssetService.Store(m_asset);
|
||||
|
||||
InventoryItemBase item = new InventoryItemBase();
|
||||
@@ -332,84 +322,12 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
||||
item.Flags = (uint) wearableType;
|
||||
item.CreationDate = Util.UnixTimeSinceEpoch();
|
||||
|
||||
m_log.DebugFormat("[XFER]: Created item {0} with asset {1}",
|
||||
item.ID, item.AssetID);
|
||||
|
||||
if (m_Scene.AddInventoryItem(item))
|
||||
ourClient.SendInventoryItemCreateUpdate(item, callbackID);
|
||||
else
|
||||
ourClient.SendAlertMessage("Unable to create inventory item");
|
||||
}
|
||||
|
||||
private void ValidateAssets()
|
||||
{
|
||||
if (m_asset.Type == (sbyte)AssetType.Clothing ||
|
||||
m_asset.Type == (sbyte)AssetType.Bodypart)
|
||||
{
|
||||
string content = System.Text.Encoding.ASCII.GetString(m_asset.Data);
|
||||
string[] lines = content.Split(new char[] {'\n'});
|
||||
|
||||
List<string> validated = new List<string>();
|
||||
|
||||
Dictionary<int, UUID> allowed = ExtractTexturesFromOldData();
|
||||
|
||||
int textures = 0;
|
||||
|
||||
foreach (string line in lines)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (line.StartsWith("textures "))
|
||||
{
|
||||
textures = Convert.ToInt32(line.Substring(9));
|
||||
validated.Add(line);
|
||||
}
|
||||
else if (textures > 0)
|
||||
{
|
||||
string[] parts = line.Split(new char[] {' '});
|
||||
|
||||
UUID tx = new UUID(parts[1]);
|
||||
int id = Convert.ToInt32(parts[0]);
|
||||
|
||||
if (defaultIDs.Contains(tx) || tx == UUID.Zero ||
|
||||
(allowed.ContainsKey(id) && allowed[id] == tx))
|
||||
{
|
||||
validated.Add(parts[0] + " " + tx.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
int perms = m_Scene.InventoryService.GetAssetPermissions(ourClient.AgentId, tx);
|
||||
int full = (int)(PermissionMask.Modify | PermissionMask.Transfer | PermissionMask.Copy);
|
||||
|
||||
if ((perms & full) != full)
|
||||
{
|
||||
m_log.ErrorFormat("[ASSET UPLOADER]: REJECTED update with texture {0} from {1} because they do not own the texture", tx, ourClient.AgentId);
|
||||
validated.Add(parts[0] + " " + UUID.Zero.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
validated.Add(line);
|
||||
}
|
||||
}
|
||||
textures--;
|
||||
}
|
||||
else
|
||||
{
|
||||
validated.Add(line);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// If it's malformed, skip it
|
||||
}
|
||||
}
|
||||
|
||||
string final = String.Join("\n", validated.ToArray());
|
||||
|
||||
m_asset.Data = System.Text.Encoding.ASCII.GetBytes(final);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the asset data uploaded in this transfer.
|
||||
/// </summary>
|
||||
@@ -418,55 +336,10 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
||||
{
|
||||
if (m_finished)
|
||||
{
|
||||
ValidateAssets();
|
||||
return m_asset;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void SetOldData(byte[] d)
|
||||
{
|
||||
m_oldData = d;
|
||||
}
|
||||
|
||||
private Dictionary<int,UUID> ExtractTexturesFromOldData()
|
||||
{
|
||||
Dictionary<int,UUID> result = new Dictionary<int,UUID>();
|
||||
if (m_oldData == null)
|
||||
return result;
|
||||
|
||||
string content = System.Text.Encoding.ASCII.GetString(m_oldData);
|
||||
string[] lines = content.Split(new char[] {'\n'});
|
||||
|
||||
int textures = 0;
|
||||
|
||||
foreach (string line in lines)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (line.StartsWith("textures "))
|
||||
{
|
||||
textures = Convert.ToInt32(line.Substring(9));
|
||||
}
|
||||
else if (textures > 0)
|
||||
{
|
||||
string[] parts = line.Split(new char[] {' '});
|
||||
|
||||
UUID tx = new UUID(parts[1]);
|
||||
int id = Convert.ToInt32(parts[0]);
|
||||
result[id] = tx;
|
||||
textures--;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// If it's malformed, skip it
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -103,6 +103,10 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
|
||||
// If it's cached, return the cached results
|
||||
if (m_decodedCache.TryGetValue(assetID, out result))
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[J2KDecoderModule]: Returning existing cached {0} layers j2k decode for {1}",
|
||||
// result.Length, assetID);
|
||||
|
||||
callback(assetID, result);
|
||||
}
|
||||
else
|
||||
@@ -129,18 +133,20 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
|
||||
|
||||
// Do Decode!
|
||||
if (decode)
|
||||
DoJ2KDecode(assetID, j2kData);
|
||||
Decode(assetID, j2kData);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Provides a synchronous decode so that caller can be assured that this executes before the next line
|
||||
/// </summary>
|
||||
/// <param name="assetID"></param>
|
||||
/// <param name="j2kData"></param>
|
||||
public void Decode(UUID assetID, byte[] j2kData)
|
||||
public bool Decode(UUID assetID, byte[] j2kData)
|
||||
{
|
||||
DoJ2KDecode(assetID, j2kData);
|
||||
OpenJPEG.J2KLayerInfo[] layers;
|
||||
int components;
|
||||
return Decode(assetID, j2kData, out layers, out components);
|
||||
}
|
||||
|
||||
public bool Decode(UUID assetID, byte[] j2kData, out OpenJPEG.J2KLayerInfo[] layers, out int components)
|
||||
{
|
||||
return DoJ2KDecode(assetID, j2kData, out layers, out components);
|
||||
}
|
||||
|
||||
#endregion IJ2KDecoder
|
||||
@@ -150,11 +156,21 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
|
||||
/// </summary>
|
||||
/// <param name="assetID">UUID of Asset</param>
|
||||
/// <param name="j2kData">JPEG2000 data</param>
|
||||
private void DoJ2KDecode(UUID assetID, byte[] j2kData)
|
||||
/// <param name="layers">layer data</param>
|
||||
/// <param name="components">number of components</param>
|
||||
/// <returns>true if decode was successful. false otherwise.</returns>
|
||||
private bool DoJ2KDecode(UUID assetID, byte[] j2kData, out OpenJPEG.J2KLayerInfo[] layers, out int components)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[J2KDecoderModule]: Doing J2K decoding of {0} bytes for asset {1}", j2kData.Length, assetID);
|
||||
|
||||
bool decodedSuccessfully = true;
|
||||
|
||||
//int DecodeTime = 0;
|
||||
//DecodeTime = Environment.TickCount;
|
||||
OpenJPEG.J2KLayerInfo[] layers;
|
||||
|
||||
// We don't get this from CSJ2K. Is it relevant?
|
||||
components = 0;
|
||||
|
||||
if (!TryLoadCacheForAsset(assetID, out layers))
|
||||
{
|
||||
@@ -189,14 +205,15 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
|
||||
catch (Exception ex)
|
||||
{
|
||||
m_log.Warn("[J2KDecoderModule]: CSJ2K threw an exception decoding texture " + assetID + ": " + ex.Message);
|
||||
decodedSuccessfully = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int components;
|
||||
if (!OpenJPEG.DecodeLayerBoundaries(j2kData, out layers, out components))
|
||||
{
|
||||
m_log.Warn("[J2KDecoderModule]: OpenJPEG failed to decode texture " + assetID);
|
||||
decodedSuccessfully = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -205,6 +222,7 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
|
||||
m_log.Warn("[J2KDecoderModule]: Failed to decode layer data for texture " + assetID + ", guessing sane defaults");
|
||||
// Layer decoding completely failed. Guess at sane defaults for the layer boundaries
|
||||
layers = CreateDefaultLayers(j2kData.Length);
|
||||
decodedSuccessfully = false;
|
||||
}
|
||||
|
||||
// Cache Decoded layers
|
||||
@@ -224,6 +242,8 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
|
||||
m_notifyList.Remove(assetID);
|
||||
}
|
||||
}
|
||||
|
||||
return decodedSuccessfully;
|
||||
}
|
||||
|
||||
private OpenJPEG.J2KLayerInfo[] CreateDefaultLayers(int j2kLength)
|
||||
|
||||
@@ -257,66 +257,53 @@ namespace Flotsam.RegionModules.AssetCache
|
||||
|
||||
private void UpdateFileCache(string key, AssetBase asset)
|
||||
{
|
||||
// TODO: Spawn this off to some seperate thread to do the actual writing
|
||||
if (asset != null)
|
||||
string filename = GetFileName(asset.ID);
|
||||
|
||||
try
|
||||
{
|
||||
string filename = GetFileName(key);
|
||||
|
||||
try
|
||||
// If the file is already cached, don't cache it, just touch it so access time is updated
|
||||
if (File.Exists(filename))
|
||||
{
|
||||
// If the file is already cached, don't cache it, just touch it so access time is updated
|
||||
if (File.Exists(filename))
|
||||
File.SetLastAccessTime(filename, DateTime.Now);
|
||||
}
|
||||
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.
|
||||
lock (m_CurrentlyWriting)
|
||||
{
|
||||
// We don't really want to know about sharing
|
||||
// violations here. If the file is locked, then
|
||||
// the other thread has updated the time for us.
|
||||
try
|
||||
{
|
||||
File.SetLastAccessTime(filename, DateTime.Now);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
} 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.
|
||||
lock (m_CurrentlyWriting)
|
||||
{
|
||||
#if WAIT_ON_INPROGRESS_REQUESTS
|
||||
if (m_CurrentlyWriting.ContainsKey(filename))
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_CurrentlyWriting.Add(filename, new ManualResetEvent(false));
|
||||
}
|
||||
if (m_CurrentlyWriting.ContainsKey(filename))
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_CurrentlyWriting.Add(filename, new ManualResetEvent(false));
|
||||
}
|
||||
|
||||
#else
|
||||
if (m_CurrentlyWriting.Contains(filename))
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_CurrentlyWriting.Add(filename);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (m_CurrentlyWriting.Contains(filename))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Util.FireAndForget(
|
||||
delegate { WriteFileCache(filename, asset); });
|
||||
else
|
||||
{
|
||||
m_CurrentlyWriting.Add(filename);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
Util.FireAndForget(
|
||||
delegate { WriteFileCache(filename, asset); });
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat(
|
||||
"[FLOTSAM ASSET CACHE]: Failed to update cache for asset {0}. Exception {1} {2}",
|
||||
asset.ID, e.Message, e.StackTrace);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat(
|
||||
"[FLOTSAM ASSET CACHE]: Failed to update cache for asset {0}. Exception {1} {2}",
|
||||
asset.ID, e.Message, e.StackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -106,7 +106,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
|
||||
|
||||
SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName).ParentGroup;
|
||||
|
||||
m_attMod.AttachObject(m_presence, so, (uint)AttachmentPoint.Chest, false);
|
||||
m_attMod.AttachObject(m_presence.ControllingClient, so, (uint)AttachmentPoint.Chest, false);
|
||||
|
||||
// Check status on scene presence
|
||||
Assert.That(m_presence.HasAttachments(), Is.True);
|
||||
@@ -140,7 +140,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
|
||||
scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object);
|
||||
|
||||
m_attMod.RezSingleAttachmentFromInventory(
|
||||
m_presence, attItemId, (uint)AttachmentPoint.Chest);
|
||||
m_presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest);
|
||||
|
||||
// Check scene presence status
|
||||
Assert.That(m_presence.HasAttachments(), Is.True);
|
||||
@@ -174,8 +174,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
|
||||
scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object);
|
||||
|
||||
ISceneEntity so = m_attMod.RezSingleAttachmentFromInventory(
|
||||
m_presence, attItemId, (uint)AttachmentPoint.Chest);
|
||||
m_attMod.DetachSingleAttachmentToGround(m_presence, so.LocalId);
|
||||
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);
|
||||
@@ -208,8 +208,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
|
||||
scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object);
|
||||
|
||||
m_attMod.RezSingleAttachmentFromInventory(
|
||||
m_presence, attItemId, (uint)AttachmentPoint.Chest);
|
||||
m_attMod.DetachSingleAttachmentToInv(m_presence, attItemId);
|
||||
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);
|
||||
|
||||
@@ -42,7 +42,7 @@ using OpenSim.Services.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
{
|
||||
public class AvatarFactoryModule : IAvatarFactoryModule, IRegionModule
|
||||
public class AvatarFactoryModule : IAvatarFactory, IRegionModule
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
private Scene m_scene = null;
|
||||
@@ -57,19 +57,22 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
|
||||
private object m_setAppearanceLock = new object();
|
||||
|
||||
#region IRegionModule
|
||||
#region RegionModule Members
|
||||
|
||||
public void Initialise(Scene scene, IConfigSource config)
|
||||
{
|
||||
scene.RegisterModuleInterface<IAvatarFactoryModule>(this);
|
||||
scene.EventManager.OnNewClient += SubscribeToClientEvents;
|
||||
scene.RegisterModuleInterface<IAvatarFactory>(this);
|
||||
scene.EventManager.OnNewClient += NewClient;
|
||||
|
||||
IConfig sconfig = config.Configs["Startup"];
|
||||
if (sconfig != null)
|
||||
if (config != null)
|
||||
{
|
||||
m_savetime = Convert.ToInt32(sconfig.GetString("DelayBeforeAppearanceSave",Convert.ToString(m_savetime)));
|
||||
m_sendtime = Convert.ToInt32(sconfig.GetString("DelayBeforeAppearanceSend",Convert.ToString(m_sendtime)));
|
||||
// m_log.InfoFormat("[AVFACTORY] configured for {0} save and {1} send",m_savetime,m_sendtime);
|
||||
IConfig sconfig = config.Configs["Startup"];
|
||||
if (sconfig != null)
|
||||
{
|
||||
m_savetime = Convert.ToInt32(sconfig.GetString("DelayBeforeAppearanceSave",Convert.ToString(m_savetime)));
|
||||
m_sendtime = Convert.ToInt32(sconfig.GetString("DelayBeforeAppearanceSend",Convert.ToString(m_sendtime)));
|
||||
// m_log.InfoFormat("[AVFACTORY] configured for {0} save and {1} send",m_savetime,m_sendtime);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_scene == null)
|
||||
@@ -98,26 +101,127 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
private void SubscribeToClientEvents(IClientAPI client)
|
||||
public void NewClient(IClientAPI client)
|
||||
{
|
||||
client.OnRequestWearables += Client_OnRequestWearables;
|
||||
client.OnSetAppearance += Client_OnSetAppearance;
|
||||
client.OnAvatarNowWearing += Client_OnAvatarNowWearing;
|
||||
client.OnRequestWearables += SendWearables;
|
||||
client.OnSetAppearance += SetAppearanceFromClient;
|
||||
client.OnAvatarNowWearing += AvatarIsWearing;
|
||||
}
|
||||
|
||||
public void RemoveClient(IClientAPI client)
|
||||
{
|
||||
// client.OnAvatarNowWearing -= AvatarIsWearing;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IAvatarFactoryModule
|
||||
public bool ValidateBakedTextureCache(IClientAPI client)
|
||||
{
|
||||
ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
|
||||
if (sp == null)
|
||||
{
|
||||
m_log.WarnFormat("[AVFACTORY]: SetAppearance unable to find presence for {0}", client.AgentId);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool defonly = true; // are we only using default textures
|
||||
|
||||
// Process the texture entry
|
||||
for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++)
|
||||
{
|
||||
int idx = AvatarAppearance.BAKE_INDICES[i];
|
||||
Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx];
|
||||
|
||||
// if there is no texture entry, skip it
|
||||
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
|
||||
// textures is default then the rest should be as well
|
||||
if (face.TextureID == UUID.Zero || face.TextureID == AppearanceManager.DEFAULT_AVATAR_TEXTURE)
|
||||
continue;
|
||||
|
||||
defonly = false; // found a non-default texture reference
|
||||
|
||||
if (m_scene.AssetService.Get(face.TextureID.ToString()) == null)
|
||||
return false;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
public int RequestRebake(IScenePresence sp, bool missingTexturesOnly)
|
||||
{
|
||||
int texturesRebaked = 0;
|
||||
|
||||
for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++)
|
||||
{
|
||||
int idx = AvatarAppearance.BAKE_INDICES[i];
|
||||
Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx];
|
||||
|
||||
// if there is no texture entry, skip it
|
||||
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
|
||||
// textures is default then the rest should be as well
|
||||
if (face.TextureID == UUID.Zero || face.TextureID == AppearanceManager.DEFAULT_AVATAR_TEXTURE)
|
||||
continue;
|
||||
|
||||
if (missingTexturesOnly)
|
||||
{
|
||||
if (m_scene.AssetService.Get(face.TextureID.ToString()) != null)
|
||||
continue;
|
||||
else
|
||||
m_log.DebugFormat(
|
||||
"[AVFACTORY]: Missing baked texture {0} ({1}) for {2}, requesting rebake.",
|
||||
face.TextureID, idx, sp.Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"[AVFACTORY]: Requesting rebake of {0} ({1}) for {2}.",
|
||||
face.TextureID, idx, sp.Name);
|
||||
}
|
||||
|
||||
texturesRebaked++;
|
||||
sp.ControllingClient.SendRebakeAvatarTextures(face.TextureID);
|
||||
}
|
||||
|
||||
return texturesRebaked;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set appearance data (texture asset IDs and slider settings)
|
||||
/// Set appearance data (texture asset IDs and slider settings) received from the client
|
||||
/// </summary>
|
||||
/// <param name="sp"></param>
|
||||
/// <param name="client"></param>
|
||||
/// <param name="texture"></param>
|
||||
/// <param name="visualParam"></param>
|
||||
public void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams)
|
||||
public void SetAppearanceFromClient(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams)
|
||||
{
|
||||
// m_log.InfoFormat("[AVFACTORY]: start SetAppearance for {0}", client.AgentId);
|
||||
ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
|
||||
if (sp == null)
|
||||
{
|
||||
m_log.WarnFormat("[AVFACTORY]: SetAppearance unable to find presence for {0}", client.AgentId);
|
||||
return;
|
||||
}
|
||||
|
||||
// m_log.InfoFormat("[AVFACTORY]: start SetAppearance for {0}", client.AgentId);
|
||||
|
||||
// TODO: This is probably not necessary any longer, just assume the
|
||||
// textureEntry set implies that the appearance transaction is complete
|
||||
@@ -130,18 +234,18 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
// Process the visual params, this may change height as well
|
||||
if (visualParams != null)
|
||||
{
|
||||
// string[] visualParamsStrings = new string[visualParams.Length];
|
||||
// for (int i = 0; i < visualParams.Length; i++)
|
||||
// visualParamsStrings[i] = visualParams[i].ToString();
|
||||
// m_log.DebugFormat(
|
||||
// "[AVFACTORY]: Setting visual params for {0} to {1}",
|
||||
// client.Name, string.Join(", ", visualParamsStrings));
|
||||
// string[] visualParamsStrings = new string[visualParams.Length];
|
||||
// for (int i = 0; i < visualParams.Length; i++)
|
||||
// visualParamsStrings[i] = visualParams[i].ToString();
|
||||
// m_log.DebugFormat(
|
||||
// "[AVFACTORY]: Setting visual params for {0} to {1}",
|
||||
// client.Name, string.Join(", ", visualParamsStrings));
|
||||
|
||||
float oldHeight = sp.Appearance.AvatarHeight;
|
||||
changed = sp.Appearance.SetVisualParams(visualParams);
|
||||
|
||||
if (sp.Appearance.AvatarHeight != oldHeight && sp.Appearance.AvatarHeight > 0)
|
||||
((ScenePresence)sp).SetHeight(sp.Appearance.AvatarHeight);
|
||||
sp.SetHeight(sp.Appearance.AvatarHeight);
|
||||
}
|
||||
|
||||
// Process the baked texture array
|
||||
@@ -149,41 +253,39 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
{
|
||||
changed = sp.Appearance.SetTextureEntries(textureEntry) || changed;
|
||||
|
||||
m_log.InfoFormat("[AVFACTORY]: received texture update for {0}", sp.UUID);
|
||||
Util.FireAndForget(delegate(object o) { ValidateBakedTextureCache(sp, false); });
|
||||
if (!ValidateBakedTextureCache(sp.ControllingClient))
|
||||
RequestRebake(sp, true);
|
||||
|
||||
// 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(sp.ControllingClient.AgentId);
|
||||
|
||||
// save only if there were changes, send no matter what (doesn't hurt to send twice)
|
||||
if (changed)
|
||||
QueueAppearanceSave(client.AgentId);
|
||||
|
||||
QueueAppearanceSend(sp.ControllingClient.AgentId);
|
||||
QueueAppearanceSend(client.AgentId);
|
||||
}
|
||||
|
||||
// m_log.WarnFormat("[AVFACTORY]: complete SetAppearance for {0}:\n{1}",client.AgentId,sp.Appearance.ToString());
|
||||
}
|
||||
|
||||
public bool SendAppearance(UUID agentId)
|
||||
/// <summary>
|
||||
/// Checks for the existance of a baked texture asset and
|
||||
/// requests the viewer rebake if the asset is not found
|
||||
/// </summary>
|
||||
/// <param name="client"></param>
|
||||
/// <param name="textureID"></param>
|
||||
/// <param name="idx"></param>
|
||||
private bool CheckBakedTextureAsset(IClientAPI client, UUID textureID, int idx)
|
||||
{
|
||||
// m_log.DebugFormat("[AVFACTORY]: Sending appearance for {0}", agentId);
|
||||
|
||||
ScenePresence sp = m_scene.GetScenePresence(agentId);
|
||||
if (sp == null)
|
||||
if (m_scene.AssetService.Get(textureID.ToString()) == null)
|
||||
{
|
||||
m_log.WarnFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentId);
|
||||
m_log.WarnFormat("[AVFACTORY]: Missing baked texture {0} ({1}) for avatar {2}",
|
||||
textureID, idx, client.Name);
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -197,6 +299,35 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
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);
|
||||
@@ -241,17 +372,35 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check for the existence of the baked texture assets.
|
||||
/// </summary>
|
||||
/// <param name="sp"></param>
|
||||
public bool ValidateBakedTextureCache(IScenePresence sp)
|
||||
{
|
||||
return ValidateBakedTextureCache(sp, true);
|
||||
}
|
||||
#region UpdateAppearanceTimer
|
||||
|
||||
/// <summary>
|
||||
/// Queue up a request to send appearance, makes it possible to
|
||||
@@ -283,105 +432,30 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region AvatarFactoryModule private methods
|
||||
|
||||
/// <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>
|
||||
private bool ValidateBakedTextureCache(IScenePresence sp, bool checkonly)
|
||||
private void SaveAppearance(UUID agentid)
|
||||
{
|
||||
bool defonly = true; // are we only using default textures
|
||||
// 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();
|
||||
|
||||
// Process the texture entry
|
||||
for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++)
|
||||
ScenePresence sp = m_scene.GetScenePresence(agentid);
|
||||
if (sp == null)
|
||||
{
|
||||
int idx = AvatarAppearance.BAKE_INDICES[i];
|
||||
Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx];
|
||||
|
||||
// if there is no texture entry, skip it
|
||||
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
|
||||
// textures is default then the rest should be as well
|
||||
if (face.TextureID == UUID.Zero || face.TextureID == AppearanceManager.DEFAULT_AVATAR_TEXTURE)
|
||||
continue;
|
||||
|
||||
defonly = false; // found a non-default texture reference
|
||||
|
||||
if (!CheckBakedTextureAsset(sp, 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;
|
||||
|
||||
sp.ControllingClient.SendRebakeAvatarTextures(face.TextureID);
|
||||
}
|
||||
m_log.WarnFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentid);
|
||||
return;
|
||||
}
|
||||
|
||||
m_log.DebugFormat("[AVFACTORY]: Completed texture check for {0}", sp.UUID);
|
||||
// m_log.WarnFormat("[AVFACTORY] avatar {0} save appearance",agentid);
|
||||
|
||||
// If we only found default textures, then the appearance is not cached
|
||||
return (defonly ? false : true);
|
||||
}
|
||||
// This could take awhile since it needs to pull inventory
|
||||
// We need to do it at the point of save so that there is a sufficient delay for any upload of new body part/shape
|
||||
// assets and item asset id changes to complete.
|
||||
// I don't think we need to worry about doing this within m_setAppearanceLock since the queueing avoids
|
||||
// multiple save requests.
|
||||
SetAppearanceAssets(sp.UUID, sp.Appearance);
|
||||
|
||||
/// <summary>
|
||||
/// Checks for the existance of a baked texture asset and
|
||||
/// requests the viewer rebake if the asset is not found
|
||||
/// </summary>
|
||||
/// <param name="sp"></param>
|
||||
/// <param name="textureID"></param>
|
||||
/// <param name="idx"></param>
|
||||
private bool CheckBakedTextureAsset(IScenePresence sp, UUID textureID, int idx)
|
||||
{
|
||||
if (m_scene.AssetService.Get(textureID.ToString()) == null)
|
||||
{
|
||||
m_log.InfoFormat("[AVFACTORY]: Missing baked texture {0} ({1}) for avatar {2}",
|
||||
textureID, idx, sp.Name);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
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;
|
||||
m_scene.AvatarService.SetAppearance(agentid, sp.Appearance);
|
||||
}
|
||||
|
||||
private void HandleAppearanceUpdateTimer(object sender, EventArgs ea)
|
||||
@@ -424,36 +498,97 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
m_savequeue.Remove(avatarID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_savequeue.Count == 0 && m_sendqueue.Count == 0)
|
||||
m_updateTimer.Stop();
|
||||
// We must lock both queues here so that QueueAppearanceSave() or *Send() don't m_updateTimer.Start() on
|
||||
// another thread inbetween the first count calls and m_updateTimer.Stop() on this thread.
|
||||
lock (m_sendqueue)
|
||||
if (m_savequeue.Count == 0 && m_sendqueue.Count == 0)
|
||||
m_updateTimer.Stop();
|
||||
}
|
||||
}
|
||||
|
||||
private void SaveAppearance(UUID agentid)
|
||||
{
|
||||
// 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();
|
||||
#endregion
|
||||
|
||||
ScenePresence sp = m_scene.GetScenePresence(agentid);
|
||||
/// <summary>
|
||||
/// Tell the client for this scene presence what items it should be wearing now
|
||||
/// </summary>
|
||||
public void SendWearables(IClientAPI client)
|
||||
{
|
||||
ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
|
||||
if (sp == null)
|
||||
{
|
||||
m_log.WarnFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentid);
|
||||
m_log.WarnFormat("[AVFACTORY]: SendWearables unable to find presence for {0}", client.AgentId);
|
||||
return;
|
||||
}
|
||||
|
||||
// m_log.WarnFormat("[AVFACTORY] avatar {0} save appearance",agentid);
|
||||
// m_log.DebugFormat("[AVFACTORY]: Received request for wearables of {0}", client.Name);
|
||||
|
||||
// This could take awhile since it needs to pull inventory
|
||||
// We need to do it at the point of save so that there is a sufficient delay for any upload of new body part/shape
|
||||
// assets and item asset id changes to complete.
|
||||
// I don't think we need to worry about doing this within m_setAppearanceLock since the queueing avoids
|
||||
// multiple save requests.
|
||||
SetAppearanceAssets(sp.UUID, sp.Appearance);
|
||||
client.SendWearables(sp.Appearance.Wearables, sp.Appearance.Serial++);
|
||||
}
|
||||
|
||||
m_scene.AvatarService.SetAppearance(agentid, sp.Appearance);
|
||||
/// <summary>
|
||||
/// Update what the avatar is wearing using an item from their inventory.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
public void AvatarIsWearing(IClientAPI client, AvatarWearingArgs e)
|
||||
{
|
||||
ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
|
||||
if (sp == null)
|
||||
{
|
||||
m_log.WarnFormat("[AVFACTORY]: AvatarIsWearing unable to find presence for {0}", client.AgentId);
|
||||
return;
|
||||
}
|
||||
|
||||
// m_log.WarnFormat("[AVFACTORY]: AvatarIsWearing called for {0}", client.AgentId);
|
||||
|
||||
// we need to clean out the existing textures
|
||||
sp.Appearance.ResetAppearance();
|
||||
|
||||
// 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)
|
||||
avatAppearance.Wearables[wear.Type].Add(wear.ItemID, UUID.Zero);
|
||||
}
|
||||
|
||||
avatAppearance.GetAssetsFrom(sp.Appearance);
|
||||
|
||||
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)
|
||||
{
|
||||
// m_log.DebugFormat("[AVFACTORY]: Sending appearance for {0}", 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, AvatarAppearance appearance)
|
||||
@@ -495,83 +630,5 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
m_log.WarnFormat("[AVFACTORY]: user {0} has no inventory, appearance isn't going to work", userID);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Client Event Handlers
|
||||
/// <summary>
|
||||
/// Tell the client for this scene presence what items it should be wearing now
|
||||
/// </summary>
|
||||
/// <param name="client"></param>
|
||||
private void Client_OnRequestWearables(IClientAPI client)
|
||||
{
|
||||
// m_log.DebugFormat("[AVFACTORY]: Client_OnRequestWearables called for {0} ({1})", client.Name, client.AgentId);
|
||||
ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
|
||||
if (sp != null)
|
||||
client.SendWearables(sp.Appearance.Wearables, sp.Appearance.Serial++);
|
||||
else
|
||||
m_log.WarnFormat("[AVFACTORY]: Client_OnRequestWearables unable to find presence for {0}", client.AgentId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set appearance data (texture asset IDs and slider settings) received from a client
|
||||
/// </summary>
|
||||
/// <param name="client"></param>
|
||||
/// <param name="texture"></param>
|
||||
/// <param name="visualParam"></param>
|
||||
private void Client_OnSetAppearance(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams)
|
||||
{
|
||||
// m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance called for {0} ({1})", client.Name, client.AgentId);
|
||||
ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
|
||||
if (sp != null)
|
||||
SetAppearance(sp, textureEntry, visualParams);
|
||||
else
|
||||
m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance unable to find presence for {0}", client.AgentId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update what the avatar is wearing using an item from their inventory.
|
||||
/// </summary>
|
||||
/// <param name="client"></param>
|
||||
/// <param name="e"></param>
|
||||
private void Client_OnAvatarNowWearing(IClientAPI client, AvatarWearingArgs e)
|
||||
{
|
||||
// m_log.WarnFormat("[AVFACTORY]: Client_OnAvatarNowWearing called for {0} ({1})", client.Name, client.AgentId);
|
||||
ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
|
||||
if (sp == null)
|
||||
{
|
||||
m_log.WarnFormat("[AVFACTORY]: Client_OnAvatarNowWearing unable to find presence for {0}", client.AgentId);
|
||||
return;
|
||||
}
|
||||
|
||||
// we need to clean out the existing textures
|
||||
sp.Appearance.ResetAppearance();
|
||||
|
||||
// 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)
|
||||
avatAppearance.Wearables[wear.Type].Add(wear.ItemID, UUID.Zero);
|
||||
}
|
||||
|
||||
avatAppearance.GetAssetsFrom(sp.Appearance);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,13 +55,15 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
AvatarFactoryModule afm = new AvatarFactoryModule();
|
||||
TestScene scene = SceneHelpers.SetupScene();
|
||||
SceneHelpers.SetupSceneModules(scene, afm);
|
||||
ScenePresence sp = SceneHelpers.AddScenePresence(scene, userId);
|
||||
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.SetAppearance(sp, new Primitive.TextureEntry(TestHelpers.ParseTail(0x10)), visualParams);
|
||||
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);
|
||||
@@ -83,7 +85,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
AvatarFactoryModule afm = new AvatarFactoryModule();
|
||||
TestScene scene = SceneHelpers.SetupScene(assetCache);
|
||||
SceneHelpers.SetupSceneModules(scene, afm);
|
||||
ScenePresence sp = SceneHelpers.AddScenePresence(scene, userId);
|
||||
IClientAPI tc = SceneHelpers.AddScenePresence(scene, userId).ControllingClient;
|
||||
|
||||
// TODO: Use the actual BunchOfCaps functionality once we slot in the CapabilitiesModules
|
||||
AssetBase uploadedAsset;
|
||||
@@ -102,7 +104,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
Primitive.TextureEntryFace eyesFace = bakedTextureEntry.CreateFace(eyesFaceIndex);
|
||||
eyesFace.TextureID = eyesTextureId;
|
||||
|
||||
afm.SetAppearance(sp, bakedTextureEntry, visualParams);
|
||||
afm.SetAppearanceFromClient(tc, bakedTextureEntry, visualParams);
|
||||
afm.SaveBakedTextures(userId);
|
||||
// Dictionary<BakeType, Primitive.TextureEntryFace> bakedTextures = afm.GetBakedTextureFaces(userId);
|
||||
|
||||
|
||||
@@ -45,12 +45,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
|
||||
private const int DEBUG_CHANNEL = 2147483647;
|
||||
|
||||
private bool m_enabled = true;
|
||||
private int m_saydistance = 20;
|
||||
private int m_saydistance = 30;
|
||||
private int m_shoutdistance = 100;
|
||||
private int m_whisperdistance = 10;
|
||||
private List<Scene> m_scenes = new List<Scene>();
|
||||
private List<string> FreezeCache = new List<string>();
|
||||
private string m_adminPrefix = "";
|
||||
|
||||
internal object m_syncy = new object();
|
||||
|
||||
internal IConfig m_config;
|
||||
@@ -77,7 +76,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
|
||||
m_whisperdistance = config.Configs["Chat"].GetInt("whisper_distance", m_whisperdistance);
|
||||
m_saydistance = config.Configs["Chat"].GetInt("say_distance", m_saydistance);
|
||||
m_shoutdistance = config.Configs["Chat"].GetInt("shout_distance", m_shoutdistance);
|
||||
m_adminPrefix = config.Configs["Chat"].GetString("admin_prefix", "");
|
||||
}
|
||||
|
||||
public virtual void AddRegion(Scene scene)
|
||||
@@ -173,15 +171,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
|
||||
return;
|
||||
}
|
||||
|
||||
if (FreezeCache.Contains(c.Sender.AgentId.ToString()))
|
||||
{
|
||||
if (c.Type != ChatTypeEnum.StartTyping || c.Type != ChatTypeEnum.StopTyping)
|
||||
c.Sender.SendAgentAlertMessage("You may not talk as you are frozen.", false);
|
||||
}
|
||||
else
|
||||
{
|
||||
DeliverChatToAvatars(ChatSourceType.Agent, c);
|
||||
}
|
||||
DeliverChatToAvatars(ChatSourceType.Agent, c);
|
||||
}
|
||||
|
||||
public virtual void OnChatFromWorld(Object sender, OSChatMessage c)
|
||||
@@ -195,7 +185,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
|
||||
protected virtual void DeliverChatToAvatars(ChatSourceType sourceType, OSChatMessage c)
|
||||
{
|
||||
string fromName = c.From;
|
||||
string fromNamePrefix = "";
|
||||
UUID fromID = UUID.Zero;
|
||||
string message = c.Message;
|
||||
IScene scene = c.Scene;
|
||||
@@ -218,10 +207,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
|
||||
fromPos = avatar.AbsolutePosition;
|
||||
fromName = avatar.Name;
|
||||
fromID = c.Sender.AgentId;
|
||||
if (avatar.GodLevel >= 200)
|
||||
{
|
||||
fromNamePrefix = m_adminPrefix;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case ChatSourceType.Object:
|
||||
@@ -242,25 +228,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
|
||||
|
||||
foreach (Scene s in m_scenes)
|
||||
{
|
||||
// This should use ForEachClient, but clients don't have a position.
|
||||
// If camera is moved into client, then camera position can be used
|
||||
s.ForEachRootScenePresence(
|
||||
s.ForEachScenePresence(
|
||||
delegate(ScenePresence presence)
|
||||
{
|
||||
ILandObject Presencecheck = s.LandChannel.GetLandObject(presence.AbsolutePosition.X, presence.AbsolutePosition.Y);
|
||||
if (Presencecheck != null)
|
||||
{
|
||||
// This will pass all chat from objects. Not
|
||||
// perfect, but it will do. For now. Better
|
||||
// than the prior behavior of muting all
|
||||
// objects on a parcel with access restrictions
|
||||
if (c.Sender == null || Presencecheck.IsEitherBannedOrRestricted(c.Sender.AgentId) != true)
|
||||
{
|
||||
if (TrySendChatMessage(presence, fromPos, regionPos, fromID, fromNamePrefix + fromName, c.Type, message, sourceType))
|
||||
receiverIDs.Add(presence.UUID);
|
||||
}
|
||||
}
|
||||
|
||||
if (TrySendChatMessage(presence, fromPos, regionPos, fromID, fromName, c.Type, message, sourceType))
|
||||
receiverIDs.Add(presence.UUID);
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -304,29 +276,28 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
|
||||
}
|
||||
|
||||
// m_log.DebugFormat("[CHAT] Broadcast: fromID {0} fromName {1}, cType {2}, sType {3}", fromID, fromName, cType, sourceType);
|
||||
|
||||
HashSet<UUID> receiverIDs = new HashSet<UUID>();
|
||||
|
||||
if (c.Scene != null)
|
||||
{
|
||||
((Scene)c.Scene).ForEachRootClient
|
||||
(
|
||||
delegate(IClientAPI client)
|
||||
{
|
||||
// don't forward SayOwner chat from objects to
|
||||
// non-owner agents
|
||||
if ((c.Type == ChatTypeEnum.Owner) &&
|
||||
(null != c.SenderObject) &&
|
||||
(((SceneObjectPart)c.SenderObject).OwnerID != client.AgentId))
|
||||
return;
|
||||
|
||||
client.SendChatMessage(c.Message, (byte)cType, CenterOfRegion, fromName, fromID,
|
||||
(byte)sourceType, (byte)ChatAudibleLevel.Fully);
|
||||
receiverIDs.Add(client.AgentId);
|
||||
}
|
||||
);
|
||||
(c.Scene as Scene).EventManager.TriggerOnChatToClients(
|
||||
fromID, receiverIDs, c.Message, cType, CenterOfRegion, fromName, sourceType, ChatAudibleLevel.Fully);
|
||||
}
|
||||
((Scene)c.Scene).ForEachRootScenePresence(
|
||||
delegate(ScenePresence presence)
|
||||
{
|
||||
IClientAPI client = presence.ControllingClient;
|
||||
|
||||
// don't forward SayOwner chat from objects to
|
||||
// non-owner agents
|
||||
if ((c.Type == ChatTypeEnum.Owner) &&
|
||||
(null != c.SenderObject) &&
|
||||
(((SceneObjectPart)c.SenderObject).OwnerID != client.AgentId))
|
||||
return;
|
||||
|
||||
client.SendChatMessage(c.Message, (byte)cType, CenterOfRegion, fromName, fromID,
|
||||
(byte)sourceType, (byte)ChatAudibleLevel.Fully);
|
||||
receiverIDs.Add(presence.UUID);
|
||||
});
|
||||
|
||||
(c.Scene as Scene).EventManager.TriggerOnChatToClients(
|
||||
fromID, receiverIDs, c.Message, cType, CenterOfRegion, fromName, sourceType, ChatAudibleLevel.Fully);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -369,35 +340,5 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Dictionary<UUID, System.Threading.Timer> Timers = new Dictionary<UUID, System.Threading.Timer>();
|
||||
public void ParcelFreezeUser(IClientAPI client, UUID parcelowner, uint flags, UUID target)
|
||||
{
|
||||
System.Threading.Timer Timer;
|
||||
if (flags == 0)
|
||||
{
|
||||
FreezeCache.Add(target.ToString());
|
||||
System.Threading.TimerCallback timeCB = new System.Threading.TimerCallback(OnEndParcelFrozen);
|
||||
Timer = new System.Threading.Timer(timeCB, target, 30000, 0);
|
||||
Timers.Add(target, Timer);
|
||||
}
|
||||
else
|
||||
{
|
||||
FreezeCache.Remove(target.ToString());
|
||||
Timers.TryGetValue(target, out Timer);
|
||||
Timers.Remove(target);
|
||||
Timer.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnEndParcelFrozen(object avatar)
|
||||
{
|
||||
UUID target = (UUID)avatar;
|
||||
FreezeCache.Remove(target.ToString());
|
||||
System.Threading.Timer Timer;
|
||||
Timers.TryGetValue(target, out Timer);
|
||||
Timers.Remove(target);
|
||||
Timer.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,9 +98,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog
|
||||
|
||||
public void SendGeneralAlert(string message)
|
||||
{
|
||||
m_scene.ForEachRootClient(delegate(IClientAPI client)
|
||||
m_scene.ForEachRootScenePresence(delegate(ScenePresence presence)
|
||||
{
|
||||
client.SendAlertMessage(message);
|
||||
presence.ControllingClient.SendAlertMessage(message);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -162,9 +162,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog
|
||||
public void SendNotificationToUsersInRegion(
|
||||
UUID fromAvatarID, string fromAvatarName, string message)
|
||||
{
|
||||
m_scene.ForEachRootClient(delegate(IClientAPI client)
|
||||
m_scene.ForEachRootScenePresence(delegate(ScenePresence presence)
|
||||
{
|
||||
client.SendBlueBoxMessage(fromAvatarID, fromAvatarName, message);
|
||||
presence.ControllingClient.SendBlueBoxMessage(fromAvatarID, fromAvatarName, message);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -216,4 +216,4 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -29,7 +29,6 @@ using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
using Nwc.XmlRpc;
|
||||
@@ -328,7 +327,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
//m_log.DebugFormat("[XXX]: OnClientLogin!");
|
||||
// Inform the friends that this user is online
|
||||
StatusChange(agentID, true);
|
||||
|
||||
|
||||
// Register that we need to send the list of online friends to this user
|
||||
lock (m_NeedsListOfOnlineFriends)
|
||||
m_NeedsListOfOnlineFriends.Add(agentID);
|
||||
@@ -378,12 +377,20 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
continue;
|
||||
}
|
||||
|
||||
im.offline = 0;
|
||||
PresenceInfo presence = null;
|
||||
PresenceInfo[] presences = PresenceService.GetAgents(new string[] { fid });
|
||||
if (presences != null && presences.Length > 0)
|
||||
presence = presences[0];
|
||||
if (presence != null)
|
||||
im.offline = 0;
|
||||
|
||||
im.fromAgentID = fromAgentID.Guid;
|
||||
im.fromAgentName = firstname + " " + lastname;
|
||||
im.offline = (byte)((presence == null) ? 1 : 0);
|
||||
im.imSessionID = im.fromAgentID;
|
||||
im.message = FriendshipMessage(fid);
|
||||
|
||||
// Finally
|
||||
LocalFriendshipOffered(agentID, im);
|
||||
}
|
||||
|
||||
@@ -603,12 +610,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
{
|
||||
StoreFriendships(client.AgentId, friendID);
|
||||
|
||||
ICallingCardModule ccm = client.Scene.RequestModuleInterface<ICallingCardModule>();
|
||||
if (ccm != null)
|
||||
{
|
||||
ccm.CreateCallingCard(client.AgentId, friendID, UUID.Zero);
|
||||
}
|
||||
|
||||
// Update the local cache
|
||||
RecacheFriends(client);
|
||||
|
||||
@@ -785,13 +786,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
(byte)OpenMetaverse.InstantMessageDialog.FriendshipAccepted, userID.ToString(), false, Vector3.Zero);
|
||||
friendClient.SendInstantMessage(im);
|
||||
|
||||
ICallingCardModule ccm = friendClient.Scene.RequestModuleInterface<ICallingCardModule>();
|
||||
if (ccm != null)
|
||||
{
|
||||
ccm.CreateCallingCard(friendID, userID, UUID.Zero);
|
||||
}
|
||||
|
||||
|
||||
// Update the local cache
|
||||
RecacheFriends(friendClient);
|
||||
|
||||
@@ -814,7 +808,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
// we're done
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -866,11 +860,11 @@ 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);
|
||||
// m_log.DebugFormat("[FRIENDS]: Local Status Notify {0} that user {1} is {2}", friendID, userID, online);
|
||||
IClientAPI friendClient = LocateClientObject(friendID);
|
||||
if (friendClient != null)
|
||||
{
|
||||
// the friend in this sim as root agent
|
||||
// the friend in this sim as root agent
|
||||
if (online)
|
||||
friendClient.SendAgentOnline(new UUID[] { userID });
|
||||
else
|
||||
@@ -927,8 +921,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
|
||||
private void RecacheFriends(IClientAPI client)
|
||||
{
|
||||
// FIXME: Ideally, we want to avoid doing this here since it sits the EventManager.OnMakeRootAgent event
|
||||
// is on the critical path for transferring an avatar from one region to another.
|
||||
UUID agentID = client.AgentId;
|
||||
lock (m_Friends)
|
||||
{
|
||||
|
||||
@@ -85,8 +85,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
|
||||
protected override bool CacheFriends(IClientAPI client)
|
||||
{
|
||||
// m_log.DebugFormat("[HGFRIENDS MODULE]: Entered CacheFriends for {0}", client.Name);
|
||||
|
||||
if (base.CacheFriends(client))
|
||||
{
|
||||
UUID agentID = client.AgentId;
|
||||
@@ -111,20 +109,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// m_log.DebugFormat("[HGFRIENDS MODULE]: Exiting CacheFriends for {0} since detected root agent", client.Name);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// m_log.DebugFormat("[HGFRIENDS MODULE]: Exiting CacheFriends for {0} since detected not root agent", client.Name);
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool SendFriendsOnlineIfNeeded(IClientAPI client)
|
||||
{
|
||||
// m_log.DebugFormat("[HGFRIENDS MODULE]: Entering SendFriendsOnlineIfNeeded for {0}", client.Name);
|
||||
|
||||
if (base.SendFriendsOnlineIfNeeded(client))
|
||||
{
|
||||
AgentCircuitData aCircuit = ((Scene)client.Scene).AuthenticateHandler.GetAgentCircuitData(client.AgentId);
|
||||
@@ -141,25 +133,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// m_log.DebugFormat("[HGFRIENDS MODULE]: Exiting SendFriendsOnlineIfNeeded for {0}", client.Name);
|
||||
return false;
|
||||
}
|
||||
|
||||
protected override void GetOnlineFriends(UUID userID, List<string> friendList, /*collector*/ List<UUID> online)
|
||||
{
|
||||
// m_log.DebugFormat("[HGFRIENDS MODULE]: Entering GetOnlineFriends for {0}", userID);
|
||||
|
||||
List<string> fList = new List<string>();
|
||||
foreach (string s in friendList)
|
||||
{
|
||||
if (s.Length < 36)
|
||||
m_log.WarnFormat(
|
||||
"[HGFRIENDS MODULE]: Ignoring friend {0} ({1} chars) for {2} since identifier too short",
|
||||
s, s.Length, userID);
|
||||
else
|
||||
fList.Add(s.Substring(0, 36));
|
||||
}
|
||||
fList.Add(s.Substring(0, 36));
|
||||
|
||||
PresenceInfo[] presence = PresenceService.GetAgents(fList.ToArray());
|
||||
foreach (PresenceInfo pi in presence)
|
||||
@@ -168,8 +149,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
if (UUID.TryParse(pi.UserID, out presenceID))
|
||||
online.Add(presenceID);
|
||||
}
|
||||
|
||||
// m_log.DebugFormat("[HGFRIENDS MODULE]: Exiting GetOnlineFriends for {0}", userID);
|
||||
}
|
||||
|
||||
//protected override void GetOnlineFriends(UUID userID, List<string> friendList, /*collector*/ List<UUID> online)
|
||||
@@ -259,8 +238,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
|
||||
protected override void StatusNotify(List<FriendInfo> friendList, UUID userID, bool online)
|
||||
{
|
||||
// m_log.DebugFormat("[HGFRIENDS MODULE]: Entering StatusNotify for {0}", userID);
|
||||
|
||||
// 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)
|
||||
@@ -313,8 +290,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// m_log.DebugFormat("[HGFRIENDS MODULE]: Exiting StatusNotify for {0}", userID);
|
||||
}
|
||||
|
||||
protected override bool GetAgentInfo(UUID scopeID, string fid, out UUID agentID, out string first, out string last)
|
||||
@@ -368,8 +343,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
|
||||
protected override FriendInfo[] GetFriendsFromService(IClientAPI client)
|
||||
{
|
||||
// m_log.DebugFormat("[HGFRIENDS MODULE]: Entering GetFriendsFromService for {0}", client.Name);
|
||||
|
||||
UserAccount account1 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, client.AgentId);
|
||||
if (account1 != null)
|
||||
return base.GetFriendsFromService(client);
|
||||
@@ -384,9 +357,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
finfos = FriendsService.GetFriends(agentUUI);
|
||||
m_log.DebugFormat("[HGFRIENDS MODULE]: Fetched {0} local friends for visitor {1}", finfos.Length, agentUUI);
|
||||
}
|
||||
|
||||
// m_log.DebugFormat("[HGFRIENDS MODULE]: Exiting GetFriendsFromService for {0}", client.Name);
|
||||
|
||||
return finfos;
|
||||
}
|
||||
|
||||
@@ -423,6 +393,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
protected override void StoreBackwards(UUID friendID, UUID agentID)
|
||||
@@ -648,4 +619,4 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends.Tests
|
||||
UUID user2Id = TestHelpers.ParseTail(0x2);
|
||||
|
||||
ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, userId);
|
||||
SceneHelpers.AddScenePresence(m_scene, user2Id);
|
||||
ScenePresence sp2 = SceneHelpers.AddScenePresence(m_scene, user2Id);
|
||||
|
||||
// This fiendship is two-way but without a connector, only the first user will receive the online
|
||||
// notification.
|
||||
|
||||
@@ -31,40 +31,16 @@ using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Collections;
|
||||
using System.Collections.Specialized;
|
||||
using System.Reflection;
|
||||
using System.IO;
|
||||
using System.Web;
|
||||
using System.Xml;
|
||||
using log4net;
|
||||
using Mono.Addins;
|
||||
using OpenMetaverse.Messages.Linden;
|
||||
using OpenMetaverse.StructuredData;
|
||||
using OpenSim.Framework.Capabilities;
|
||||
using OpenSim.Framework.Servers;
|
||||
using OpenSim.Framework.Servers.HttpServer;
|
||||
using Caps = OpenSim.Framework.Capabilities.Caps;
|
||||
using OSDArray = OpenMetaverse.StructuredData.OSDArray;
|
||||
using OSDMap = OpenMetaverse.StructuredData.OSDMap;
|
||||
|
||||
namespace OpenSim.Region.CoreModules.Avatar.Gods
|
||||
{
|
||||
public class GodsModule : IRegionModule, IGodsModule
|
||||
{
|
||||
private static readonly ILog m_log =
|
||||
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
/// <summary>Special UUID for actions that apply to all agents</summary>
|
||||
private static readonly UUID ALL_AGENTS = new UUID("44e87126-e794-4ded-05b3-7c42da3d5cdb");
|
||||
|
||||
protected Scene m_scene;
|
||||
protected IDialogModule m_dialogModule;
|
||||
|
||||
protected Dictionary<UUID, string> m_capsDict =
|
||||
new Dictionary<UUID, string>();
|
||||
|
||||
public void Initialise(Scene scene, IConfigSource source)
|
||||
{
|
||||
@@ -72,10 +48,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods
|
||||
m_dialogModule = m_scene.RequestModuleInterface<IDialogModule>();
|
||||
m_scene.RegisterModuleInterface<IGodsModule>(this);
|
||||
m_scene.EventManager.OnNewClient += SubscribeToClientEvents;
|
||||
m_scene.EventManager.OnRegisterCaps += OnRegisterCaps;
|
||||
m_scene.EventManager.OnClientClosed += OnClientClosed;
|
||||
scene.EventManager.OnIncomingInstantMessage +=
|
||||
OnIncomingInstantMessage;
|
||||
}
|
||||
|
||||
public void PostInitialise() {}
|
||||
@@ -95,54 +67,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods
|
||||
client.OnRequestGodlikePowers -= RequestGodlikePowers;
|
||||
}
|
||||
|
||||
private void OnClientClosed(UUID agentID, Scene scene)
|
||||
{
|
||||
m_capsDict.Remove(agentID);
|
||||
}
|
||||
|
||||
private void OnRegisterCaps(UUID agentID, Caps caps)
|
||||
{
|
||||
string uri = "/CAPS/" + UUID.Random();
|
||||
m_capsDict[agentID] = uri;
|
||||
|
||||
caps.RegisterHandler("UntrustedSimulatorMessage",
|
||||
new RestStreamHandler("POST", uri,
|
||||
HandleUntrustedSimulatorMessage));
|
||||
}
|
||||
|
||||
private string HandleUntrustedSimulatorMessage(string request,
|
||||
string path, string param, OSHttpRequest httpRequest,
|
||||
OSHttpResponse httpResponse)
|
||||
{
|
||||
OSDMap osd = (OSDMap)OSDParser.DeserializeLLSDXml(request);
|
||||
|
||||
string message = osd["message"].AsString();
|
||||
|
||||
if (message == "GodKickUser")
|
||||
{
|
||||
OSDMap body = (OSDMap)osd["body"];
|
||||
OSDArray userInfo = (OSDArray)body["UserInfo"];
|
||||
OSDMap userData = (OSDMap)userInfo[0];
|
||||
|
||||
UUID agentID = userData["AgentID"].AsUUID();
|
||||
UUID godID = userData["GodID"].AsUUID();
|
||||
UUID godSessionID = userData["GodSessionID"].AsUUID();
|
||||
uint kickFlags = userData["KickFlags"].AsUInteger();
|
||||
string reason = userData["Reason"].AsString();
|
||||
|
||||
ScenePresence god = m_scene.GetScenePresence(godID);
|
||||
if (god == null || god.ControllingClient.SessionId != godSessionID)
|
||||
return String.Empty;
|
||||
|
||||
KickUser(godID, godSessionID, agentID, kickFlags, Util.StringToBytes1024(reason));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.ErrorFormat("[GOD]: Unhandled UntrustedSimulatorMessage: {0}", message);
|
||||
}
|
||||
return String.Empty;
|
||||
}
|
||||
|
||||
public void RequestGodlikePowers(
|
||||
UUID agentID, UUID sessionID, UUID token, bool godLike, IClientAPI controllingClient)
|
||||
{
|
||||
@@ -191,85 +115,71 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods
|
||||
/// <param name="reason">The message to send to the user after it's been turned into a field</param>
|
||||
public void KickUser(UUID godID, UUID sessionID, UUID agentID, uint kickflags, byte[] reason)
|
||||
{
|
||||
if (!m_scene.Permissions.IsGod(godID))
|
||||
return;
|
||||
|
||||
UUID kickUserID = ALL_AGENTS;
|
||||
|
||||
ScenePresence sp = m_scene.GetScenePresence(agentID);
|
||||
|
||||
if (sp == null && agentID != ALL_AGENTS)
|
||||
if (sp != null || agentID == kickUserID)
|
||||
{
|
||||
IMessageTransferModule transferModule =
|
||||
m_scene.RequestModuleInterface<IMessageTransferModule>();
|
||||
if (transferModule != null)
|
||||
if (m_scene.Permissions.IsGod(godID))
|
||||
{
|
||||
m_log.DebugFormat("[GODS]: Sending nonlocal kill for agent {0}", agentID);
|
||||
transferModule.SendInstantMessage(new GridInstantMessage(
|
||||
m_scene, godID, "God", agentID, (byte)250, false,
|
||||
Utils.BytesToString(reason), UUID.Zero, true,
|
||||
new Vector3(), new byte[] {(byte)kickflags}),
|
||||
delegate(bool success) {} );
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (kickflags == 0)
|
||||
{
|
||||
if (agentID == kickUserID)
|
||||
{
|
||||
string reasonStr = Utils.BytesToString(reason);
|
||||
|
||||
switch (kickflags)
|
||||
{
|
||||
case 0:
|
||||
if (sp != null)
|
||||
{
|
||||
KickPresence(sp, Utils.BytesToString(reason));
|
||||
}
|
||||
else if (agentID == ALL_AGENTS)
|
||||
{
|
||||
m_scene.ForEachRootScenePresence(
|
||||
delegate(ScenePresence p)
|
||||
{
|
||||
if (p.UUID != godID && (!m_scene.Permissions.IsGod(p.UUID)))
|
||||
KickPresence(p, Utils.BytesToString(reason));
|
||||
}
|
||||
);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (sp != null)
|
||||
{
|
||||
sp.AllowMovement = false;
|
||||
m_dialogModule.SendAlertToUser(agentID, Utils.BytesToString(reason));
|
||||
m_dialogModule.SendAlertToUser(godID, "User Frozen");
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (sp != null)
|
||||
{
|
||||
sp.AllowMovement = true;
|
||||
m_dialogModule.SendAlertToUser(agentID, Utils.BytesToString(reason));
|
||||
m_dialogModule.SendAlertToUser(godID, "User Unfrozen");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
m_scene.ForEachClient(
|
||||
delegate(IClientAPI controller)
|
||||
{
|
||||
if (controller.AgentId != godID)
|
||||
controller.Kick(reasonStr);
|
||||
}
|
||||
);
|
||||
|
||||
private void KickPresence(ScenePresence sp, string reason)
|
||||
{
|
||||
if (sp.IsChildAgent)
|
||||
return;
|
||||
sp.ControllingClient.Kick(reason);
|
||||
sp.Scene.IncomingCloseAgent(sp.UUID);
|
||||
}
|
||||
// This is a bit crude. It seems the client will be null before it actually stops the thread
|
||||
// The thread will kill itself eventually :/
|
||||
// Is there another way to make sure *all* clients get this 'inter region' message?
|
||||
m_scene.ForEachRootScenePresence(
|
||||
delegate(ScenePresence p)
|
||||
{
|
||||
if (p.UUID != godID)
|
||||
{
|
||||
// Possibly this should really be p.Close() though that method doesn't send a close
|
||||
// to the client
|
||||
p.ControllingClient.Close();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_scene.SceneGraph.removeUserCount(!sp.IsChildAgent);
|
||||
|
||||
private void OnIncomingInstantMessage(GridInstantMessage msg)
|
||||
{
|
||||
if (msg.dialog == (uint)250) // Nonlocal kick
|
||||
{
|
||||
UUID agentID = new UUID(msg.toAgentID);
|
||||
string reason = msg.message;
|
||||
UUID godID = new UUID(msg.fromAgentID);
|
||||
uint kickMode = (uint)msg.binaryBucket[0];
|
||||
|
||||
KickUser(godID, UUID.Zero, agentID, kickMode, Util.StringToBytes1024(reason));
|
||||
sp.ControllingClient.Kick(Utils.BytesToString(reason));
|
||||
sp.ControllingClient.Close();
|
||||
}
|
||||
}
|
||||
|
||||
if (kickflags == 1)
|
||||
{
|
||||
sp.AllowMovement = false;
|
||||
m_dialogModule.SendAlertToUser(agentID, Utils.BytesToString(reason));
|
||||
m_dialogModule.SendAlertToUser(godID, "User Frozen");
|
||||
}
|
||||
|
||||
if (kickflags == 2)
|
||||
{
|
||||
sp.AllowMovement = true;
|
||||
m_dialogModule.SendAlertToUser(agentID, Utils.BytesToString(reason));
|
||||
m_dialogModule.SendAlertToUser(godID, "User Unfrozen");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_dialogModule.SendAlertToUser(godID, "Kick request denied");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -143,19 +143,24 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
|
||||
// Try root avatar only first
|
||||
foreach (Scene scene in m_Scenes)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[HG INSTANT MESSAGE]: Looking for root agent {0} in {1}",
|
||||
// toAgentID.ToString(), scene.RegionInfo.RegionName);
|
||||
ScenePresence sp = scene.GetScenePresence(toAgentID);
|
||||
if (sp != null && !sp.IsChildAgent)
|
||||
{
|
||||
// Local message
|
||||
// m_log.DebugFormat("[HG INSTANT MESSAGE]: Delivering IM to root agent {0} {1}", user.Name, toAgentID);
|
||||
sp.ControllingClient.SendInstantMessage(im);
|
||||
if (scene.Entities.ContainsKey(toAgentID) &&
|
||||
scene.Entities[toAgentID] is ScenePresence)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[HG 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("[HG INSTANT MESSAGE]: Delivering IM to root agent {0} {1}", user.Name, toAgentID);
|
||||
user.ControllingClient.SendInstantMessage(im);
|
||||
|
||||
// Message sent
|
||||
result(true);
|
||||
return;
|
||||
// Message sent
|
||||
result(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,14 +168,16 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
|
||||
foreach (Scene scene in m_Scenes)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[HG INSTANT MESSAGE]: Looking for child of {0} in {1}",
|
||||
// toAgentID, scene.RegionInfo.RegionName);
|
||||
ScenePresence sp = scene.GetScenePresence(toAgentID);
|
||||
if (sp != null)
|
||||
{
|
||||
// "[HG 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("[HG INSTANT MESSAGE]: Delivering IM to child agent {0} {1}", user.Name, toAgentID);
|
||||
sp.ControllingClient.SendInstantMessage(im);
|
||||
user.ControllingClient.SendInstantMessage(im);
|
||||
|
||||
// Message sent
|
||||
result(true);
|
||||
@@ -224,14 +231,19 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
|
||||
bool successful = false;
|
||||
foreach (Scene scene in m_Scenes)
|
||||
{
|
||||
ScenePresence sp = scene.GetScenePresence(toAgentID);
|
||||
if(sp != null && !sp.IsChildAgent)
|
||||
if (scene.Entities.ContainsKey(toAgentID) &&
|
||||
scene.Entities[toAgentID] is ScenePresence)
|
||||
{
|
||||
scene.EventManager.TriggerIncomingInstantMessage(gim);
|
||||
successful = true;
|
||||
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
|
||||
@@ -291,24 +303,41 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Find the root client for a ID
|
||||
/// Find the scene for an agent
|
||||
/// </summary>
|
||||
public IClientAPI LocateClientObject(UUID agentID)
|
||||
private Scene GetClientScene(UUID agentId)
|
||||
{
|
||||
lock (m_Scenes)
|
||||
{
|
||||
foreach (Scene scene in m_Scenes)
|
||||
{
|
||||
ScenePresence presence = scene.GetScenePresence(agentID);
|
||||
ScenePresence presence = scene.GetScenePresence(agentId);
|
||||
if (presence != null && !presence.IsChildAgent)
|
||||
return presence.ControllingClient;
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -151,38 +151,11 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
|
||||
if (dialog != (byte)InstantMessageDialog.MessageFromAgent
|
||||
&& dialog != (byte)InstantMessageDialog.StartTyping
|
||||
&& dialog != (byte)InstantMessageDialog.StopTyping
|
||||
&& dialog != (byte)InstantMessageDialog.BusyAutoResponse
|
||||
&& dialog != (byte)InstantMessageDialog.MessageFromObject)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//DateTime dt = DateTime.UtcNow;
|
||||
|
||||
// Ticks from UtcNow, but make it look like local. Evil, huh?
|
||||
//dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
|
||||
|
||||
//try
|
||||
//{
|
||||
// // Convert that to the PST timezone
|
||||
// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
|
||||
// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
|
||||
//}
|
||||
//catch
|
||||
//{
|
||||
// //m_log.Info("[OFFLINE MESSAGING]: No PST timezone found on this machine. Saving with local timestamp.");
|
||||
//}
|
||||
|
||||
//// And make it look local again to fool the unix time util
|
||||
//dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
|
||||
|
||||
// If client is null, this message comes from storage and IS offline
|
||||
if (client != null)
|
||||
im.offline = 0;
|
||||
|
||||
if (im.offline == 0)
|
||||
im.timestamp = (uint)Util.UnixTimeSinceEpoch();
|
||||
|
||||
if (m_TransferModule != null)
|
||||
{
|
||||
if (client != null)
|
||||
|
||||
@@ -48,7 +48,6 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private bool m_Enabled = false;
|
||||
protected string m_MessageKey = String.Empty;
|
||||
protected List<Scene> m_Scenes = new List<Scene>();
|
||||
protected Dictionary<UUID, UUID> m_UserRegionMap = new Dictionary<UUID, UUID>();
|
||||
|
||||
@@ -68,17 +67,14 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
|
||||
public virtual void Initialise(IConfigSource config)
|
||||
{
|
||||
IConfig cnf = config.Configs["Messaging"];
|
||||
if (cnf != null)
|
||||
if (cnf != null && cnf.GetString(
|
||||
"MessageTransferModule", "MessageTransferModule") !=
|
||||
"MessageTransferModule")
|
||||
{
|
||||
if (cnf.GetString("MessageTransferModule",
|
||||
"MessageTransferModule") != "MessageTransferModule")
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_MessageKey = cnf.GetString("MessageKey", String.Empty);
|
||||
m_log.Debug("[MESSAGE TRANSFER]: Disabled by configuration");
|
||||
return;
|
||||
}
|
||||
m_log.Debug("[MESSAGE TRANSFER]: Module enabled");
|
||||
|
||||
m_Enabled = true;
|
||||
}
|
||||
|
||||
@@ -140,11 +136,8 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
|
||||
// Try root avatar only first
|
||||
foreach (Scene scene in m_Scenes)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[INSTANT MESSAGE]: Looking for root agent {0} in {1}",
|
||||
// toAgentID.ToString(), scene.RegionInfo.RegionName);
|
||||
ScenePresence sp = scene.GetScenePresence(toAgentID);
|
||||
if (sp != null && !sp.IsChildAgent)
|
||||
if (scene.Entities.ContainsKey(toAgentID) &&
|
||||
scene.Entities[toAgentID] is ScenePresence)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[INSTANT MESSAGE]: Looking for root agent {0} in {1}",
|
||||
@@ -153,7 +146,8 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
|
||||
ScenePresence user = (ScenePresence) scene.Entities[toAgentID];
|
||||
if (!user.IsChildAgent)
|
||||
{
|
||||
// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering to client");
|
||||
// Local message
|
||||
// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to root agent {0} {1}", user.Name, toAgentID);
|
||||
user.ControllingClient.SendInstantMessage(im);
|
||||
|
||||
// Message sent
|
||||
@@ -168,13 +162,14 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[INSTANT MESSAGE]: Looking for child of {0} in {1}", toAgentID, scene.RegionInfo.RegionName);
|
||||
ScenePresence sp = scene.GetScenePresence(toAgentID);
|
||||
if (sp != null)
|
||||
|
||||
if (scene.Entities.ContainsKey(toAgentID) &&
|
||||
scene.Entities[toAgentID] is ScenePresence)
|
||||
{
|
||||
// Local message
|
||||
ScenePresence user = (ScenePresence) scene.Entities[toAgentID];
|
||||
|
||||
// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering to client");
|
||||
// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to child agent {0} {1}", user.Name, toAgentID);
|
||||
user.ControllingClient.SendInstantMessage(im);
|
||||
|
||||
// Message sent
|
||||
@@ -257,19 +252,6 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
|
||||
&& requestData.ContainsKey("position_z") && requestData.ContainsKey("region_id")
|
||||
&& requestData.ContainsKey("binary_bucket"))
|
||||
{
|
||||
if (m_MessageKey != String.Empty)
|
||||
{
|
||||
XmlRpcResponse error_resp = new XmlRpcResponse();
|
||||
Hashtable error_respdata = new Hashtable();
|
||||
error_respdata["success"] = "FALSE";
|
||||
error_resp.Value = error_respdata;
|
||||
|
||||
if (!requestData.Contains("message_key"))
|
||||
return error_resp;
|
||||
if (m_MessageKey != (string)requestData["message_key"])
|
||||
return error_resp;
|
||||
}
|
||||
|
||||
// Do the easy way of validating the UUIDs
|
||||
UUID.TryParse((string)requestData["from_agent_id"], out fromAgentID);
|
||||
UUID.TryParse((string)requestData["to_agent_id"], out toAgentID);
|
||||
@@ -407,11 +389,17 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
|
||||
// Trigger the Instant message in the scene.
|
||||
foreach (Scene scene in m_Scenes)
|
||||
{
|
||||
ScenePresence sp = scene.GetScenePresence(toAgentID);
|
||||
if (sp != null && !sp.IsChildAgent)
|
||||
if (scene.Entities.ContainsKey(toAgentID) &&
|
||||
scene.Entities[toAgentID] is ScenePresence)
|
||||
{
|
||||
scene.EventManager.TriggerIncomingInstantMessage(gim);
|
||||
successful = true;
|
||||
ScenePresence user =
|
||||
(ScenePresence)scene.Entities[toAgentID];
|
||||
|
||||
if (!user.IsChildAgent)
|
||||
{
|
||||
scene.EventManager.TriggerIncomingInstantMessage(gim);
|
||||
successful = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!successful)
|
||||
@@ -446,37 +434,24 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
|
||||
return resp;
|
||||
}
|
||||
|
||||
private delegate void GridInstantMessageDelegate(GridInstantMessage im, MessageResultNotification result);
|
||||
/// <summary>
|
||||
/// delegate for sending a grid instant message asynchronously
|
||||
/// </summary>
|
||||
public delegate void GridInstantMessageDelegate(GridInstantMessage im, MessageResultNotification result, UUID prevRegionID);
|
||||
|
||||
private class GIM {
|
||||
public GridInstantMessage im;
|
||||
public MessageResultNotification result;
|
||||
};
|
||||
|
||||
private Queue<GIM> pendingInstantMessages = new Queue<GIM>();
|
||||
private int numInstantMessageThreads = 0;
|
||||
|
||||
private void SendGridInstantMessageViaXMLRPC(GridInstantMessage im, MessageResultNotification result)
|
||||
protected virtual void GridInstantMessageCompleted(IAsyncResult iar)
|
||||
{
|
||||
lock (pendingInstantMessages) {
|
||||
if (numInstantMessageThreads >= 4) {
|
||||
GIM gim = new GIM();
|
||||
gim.im = im;
|
||||
gim.result = result;
|
||||
pendingInstantMessages.Enqueue(gim);
|
||||
} else {
|
||||
++ numInstantMessageThreads;
|
||||
//m_log.DebugFormat("[SendGridInstantMessageViaXMLRPC]: ++numInstantMessageThreads={0}", numInstantMessageThreads);
|
||||
GridInstantMessageDelegate d = SendGridInstantMessageViaXMLRPCAsyncMain;
|
||||
d.BeginInvoke(im, result, GridInstantMessageCompleted, d);
|
||||
}
|
||||
}
|
||||
GridInstantMessageDelegate icon =
|
||||
(GridInstantMessageDelegate)iar.AsyncState;
|
||||
icon.EndInvoke(iar);
|
||||
}
|
||||
|
||||
private void GridInstantMessageCompleted(IAsyncResult iar)
|
||||
|
||||
protected virtual void SendGridInstantMessageViaXMLRPC(GridInstantMessage im, MessageResultNotification result)
|
||||
{
|
||||
GridInstantMessageDelegate d = (GridInstantMessageDelegate)iar.AsyncState;
|
||||
d.EndInvoke(iar);
|
||||
GridInstantMessageDelegate d = SendGridInstantMessageViaXMLRPCAsync;
|
||||
|
||||
d.BeginInvoke(im, result, UUID.Zero, GridInstantMessageCompleted, d);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -491,31 +466,8 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
|
||||
/// Pass in 0 the first time this method is called. It will be called recursively with the last
|
||||
/// regionhandle tried
|
||||
/// </param>
|
||||
private void SendGridInstantMessageViaXMLRPCAsyncMain(GridInstantMessage im, MessageResultNotification result)
|
||||
protected virtual void SendGridInstantMessageViaXMLRPCAsync(GridInstantMessage im, MessageResultNotification result, UUID prevRegionID)
|
||||
{
|
||||
GIM gim;
|
||||
do {
|
||||
try {
|
||||
SendGridInstantMessageViaXMLRPCAsync(im, result, UUID.Zero);
|
||||
} catch (Exception e) {
|
||||
m_log.Error("[SendGridInstantMessageViaXMLRPC]: exception " + e.Message);
|
||||
}
|
||||
lock (pendingInstantMessages) {
|
||||
if (pendingInstantMessages.Count > 0) {
|
||||
gim = pendingInstantMessages.Dequeue();
|
||||
im = gim.im;
|
||||
result = gim.result;
|
||||
} else {
|
||||
gim = null;
|
||||
-- numInstantMessageThreads;
|
||||
//m_log.DebugFormat("[SendGridInstantMessageViaXMLRPC]: --numInstantMessageThreads={0}", numInstantMessageThreads);
|
||||
}
|
||||
}
|
||||
} while (gim != null);
|
||||
}
|
||||
private void SendGridInstantMessageViaXMLRPCAsync(GridInstantMessage im, MessageResultNotification result, UUID prevRegionID)
|
||||
{
|
||||
|
||||
UUID toAgentID = new UUID(im.toAgentID);
|
||||
|
||||
PresenceInfo upd = null;
|
||||
@@ -582,7 +534,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
|
||||
|
||||
if (upd != null)
|
||||
{
|
||||
GridRegion reginfo = m_Scenes[0].GridService.GetRegionByUUID(UUID.Zero,
|
||||
GridRegion reginfo = m_Scenes[0].GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID,
|
||||
upd.RegionID);
|
||||
if (reginfo != null)
|
||||
{
|
||||
@@ -731,8 +683,6 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
|
||||
gim["position_z"] = msg.Position.Z.ToString();
|
||||
gim["region_id"] = msg.RegionID.ToString();
|
||||
gim["binary_bucket"] = Convert.ToBase64String(msg.binaryBucket,Base64FormattingOptions.None);
|
||||
if (m_MessageKey != String.Empty)
|
||||
gim["message_key"] = m_MessageKey;
|
||||
return gim;
|
||||
}
|
||||
|
||||
|
||||
@@ -171,11 +171,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
|
||||
|
||||
private void RetrieveInstantMessages(IClientAPI client)
|
||||
{
|
||||
if (m_RestURL == String.Empty)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
if (m_RestURL != "")
|
||||
{
|
||||
m_log.DebugFormat("[OFFLINE MESSAGING]: Retrieving stored messages for {0}", client.AgentId);
|
||||
|
||||
@@ -183,61 +179,48 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
|
||||
= SynchronousRestObjectRequester.MakeRequest<UUID, List<GridInstantMessage>>(
|
||||
"POST", m_RestURL + "/RetrieveMessages/", client.AgentId);
|
||||
|
||||
if (msglist != null)
|
||||
if (msglist == null)
|
||||
m_log.WarnFormat("[OFFLINE MESSAGING]: WARNING null message list.");
|
||||
|
||||
foreach (GridInstantMessage im in msglist)
|
||||
{
|
||||
foreach (GridInstantMessage im in msglist)
|
||||
{
|
||||
// client.SendInstantMessage(im);
|
||||
// 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
|
||||
//
|
||||
|
||||
im.offline = 1;
|
||||
|
||||
Scene s = FindScene(client.AgentId);
|
||||
if (s != null)
|
||||
s.EventManager.TriggerIncomingInstantMessage(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
|
||||
//
|
||||
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);
|
||||
|
||||
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 = SynchronousRestObjectRequester.MakeRequest<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()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -632,4 +632,4 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
m_assetsLoaded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user