Compare commits
29 Commits
master
...
0.8.1-post
Author | SHA1 | Date |
---|---|---|
Diva Canto | e09c8681ad | |
Diva Canto | eab6b3aee8 | |
Melanie Thielker | b24e177aac | |
Melanie Thielker | 7a9fbec3f5 | |
Melanie Thielker | 6b932f6a64 | |
Melanie Thielker | d9aa456175 | |
Diva Canto | fe92e025f4 | |
Justin Clark-Casey (justincc) | 593678a26b | |
Justin Clark-Casey (justincc) | c2500de0c7 | |
Robert Adams | d8642ff210 | |
Justin Clark-Casey (justincc) | 60889f139a | |
Justin Clark-Casey (justincc) | 4ac3d4a229 | |
Justin Clark-Casey (justincc) | 64fa2249f8 | |
Justin Clark-Casey (justincc) | 0e97633f71 | |
Justin Clark-Casey (justincc) | 63ccb54d40 | |
Justin Clark-Casey (justincc) | 7f5cf0f3c1 | |
Shy Robbiani | ad8d172079 | |
Justin Clark-Casey (justincc) | f03734710a | |
Justin Clark-Casey (justincc) | d2b4b99263 | |
Justin Clark-Casey (justincc) | c8cc768c85 | |
Justin Clark-Casey (justincc) | 33a14f358b | |
Freaky Tech | bea2569b6d | |
Justin Clark-Casey (justincc) | a4f6cef832 | |
Justin Clark-Casey (justincc) | 86d4724e24 | |
Justin Clark-Casey (justincc) | 56dcb4e283 | |
Justin Clark-Casey (justincc) | 1a185a048b | |
AliciaRaven | 14a3375bed | |
Justin Clark-Casey (justincc) | b8c7175d34 | |
Justin Clark-Casey (justincc) | 144f1400c5 |
|
@ -1,6 +1,5 @@
|
||||||
.project
|
.project
|
||||||
.settings
|
.settings
|
||||||
.gitignore
|
|
||||||
*.csproj
|
*.csproj
|
||||||
*.csproj.user
|
*.csproj.user
|
||||||
*.build
|
*.build
|
||||||
|
@ -11,7 +10,6 @@
|
||||||
*.pidb
|
*.pidb
|
||||||
*.dll.build
|
*.dll.build
|
||||||
*.dll
|
*.dll
|
||||||
*.log
|
|
||||||
|
|
||||||
# Ignore .user and .suo files as these are user preference specific
|
# Ignore .user and .suo files as these are user preference specific
|
||||||
# http://stackoverflow.com/questions/72298/should-i-add-the-visual-studio-suo-and-user-files-to-source-control
|
# http://stackoverflow.com/questions/72298/should-i-add-the-visual-studio-suo-and-user-files-to-source-control
|
||||||
|
@ -31,8 +29,6 @@
|
||||||
*/*/*/*/*/bin
|
*/*/*/*/*/bin
|
||||||
*/*/*/*/*/*/bin
|
*/*/*/*/*/*/bin
|
||||||
*/*/*/*/*/*/*/bin
|
*/*/*/*/*/*/*/bin
|
||||||
.vs/
|
|
||||||
addon-modules/
|
|
||||||
bin/Debug/*.dll
|
bin/Debug/*.dll
|
||||||
bin/*.dll.mdb
|
bin/*.dll.mdb
|
||||||
bin/*.db
|
bin/*.db
|
||||||
|
@ -71,12 +67,6 @@ bin/OpenSim.Grid.InventoryServer.log
|
||||||
bin/OpenSim.Grid.MessagingServer.log
|
bin/OpenSim.Grid.MessagingServer.log
|
||||||
bin/OpenSim.Grid.UserServer.log
|
bin/OpenSim.Grid.UserServer.log
|
||||||
bin/OpenSim.log
|
bin/OpenSim.log
|
||||||
bin/OpenSimStats.log
|
|
||||||
bin/Robust.log
|
|
||||||
bin/RobustStats.log
|
|
||||||
bin/OpenSimConsoleHistory.txt
|
|
||||||
bin/RobustConsoleHistory.txt
|
|
||||||
bin/*.Tests.log
|
|
||||||
bin/*.manifest
|
bin/*.manifest
|
||||||
bin/crashes/
|
bin/crashes/
|
||||||
Examples/*.dll
|
Examples/*.dll
|
||||||
|
@ -94,6 +84,7 @@ TAGS
|
||||||
Makefile.local
|
Makefile.local
|
||||||
bin/.version
|
bin/.version
|
||||||
compile.bat
|
compile.bat
|
||||||
|
addon-modules
|
||||||
OpenSim/Data/Tests/test-results/
|
OpenSim/Data/Tests/test-results/
|
||||||
OpenSim/Framework/Serialization/Tests/test-results/
|
OpenSim/Framework/Serialization/Tests/test-results/
|
||||||
OpenSim/Framework/Servers/Tests/test-results/
|
OpenSim/Framework/Servers/Tests/test-results/
|
||||||
|
@ -112,5 +103,3 @@ OpenSim/Tests/test-results/
|
||||||
test-results/
|
test-results/
|
||||||
doc/html
|
doc/html
|
||||||
doc/doxygen.error.log
|
doc/doxygen.error.log
|
||||||
|
|
||||||
*.patch
|
|
||||||
|
|
|
@ -113,12 +113,10 @@
|
||||||
</exec>
|
</exec>
|
||||||
<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.coremodules.tests)==0}" />
|
||||||
|
|
||||||
<!--
|
|
||||||
<exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.region.optionalmodules.tests">
|
<exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.region.optionalmodules.tests">
|
||||||
<arg value="./bin/OpenSim.Region.OptionalModules.Tests.dll" />
|
<arg value="./bin/OpenSim.Region.OptionalModules.Tests.dll" />
|
||||||
</exec>
|
</exec>
|
||||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.optionalmodules.tests)==0}" />
|
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.optionalmodules.tests)==0}" />
|
||||||
-->
|
|
||||||
|
|
||||||
<exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.region.framework.tests">
|
<exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.region.framework.tests">
|
||||||
<arg value="./bin/OpenSim.Region.Framework.Tests.dll" />
|
<arg value="./bin/OpenSim.Region.Framework.Tests.dll" />
|
||||||
|
@ -145,12 +143,7 @@
|
||||||
</exec>
|
</exec>
|
||||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.services.inventoryservice.tests)==0}" />
|
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.services.inventoryservice.tests)==0}" />
|
||||||
|
|
||||||
<exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.tests.permissions">
|
<delete dir="%temp%"/>
|
||||||
<arg value="./bin/OpenSim.Tests.Permissions.dll" />
|
|
||||||
</exec>
|
|
||||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.tests.permissions)==0}" />
|
|
||||||
|
|
||||||
<delete dir="%temp%"/>
|
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
<target name="test-stress" depends="build, find-nunit">
|
<target name="test-stress" depends="build, find-nunit">
|
||||||
|
@ -233,12 +226,10 @@
|
||||||
<arg value="-xml=test-results/OpenSim.Region.CoreModules.Tests.dll-Results.xml" />
|
<arg value="-xml=test-results/OpenSim.Region.CoreModules.Tests.dll-Results.xml" />
|
||||||
</exec>
|
</exec>
|
||||||
|
|
||||||
<!--
|
|
||||||
<exec program="${nunitcmd}" failonerror="false" resultproperty="testresult.opensim.region.optionalmodules.tests">
|
<exec program="${nunitcmd}" failonerror="false" resultproperty="testresult.opensim.region.optionalmodules.tests">
|
||||||
<arg value="./bin/OpenSim.Region.OptionalModules.Tests.dll" />
|
<arg value="./bin/OpenSim.Region.OptionalModules.Tests.dll" />
|
||||||
<arg value="-xml=test-results/OpenSim.Region.OptionalModules.Tests.dll-Results.xml" />
|
<arg value="-xml=test-results/OpenSim.Region.OptionalModules.Tests.dll-Results.xml" />
|
||||||
</exec>
|
</exec>
|
||||||
-->
|
|
||||||
|
|
||||||
<exec program="${nunitcmd}" failonerror="false" resultproperty="testresult.opensim.region.framework.tests">
|
<exec program="${nunitcmd}" failonerror="false" resultproperty="testresult.opensim.region.framework.tests">
|
||||||
<arg value="./bin/OpenSim.Region.Framework.Tests.dll" />
|
<arg value="./bin/OpenSim.Region.Framework.Tests.dll" />
|
||||||
|
@ -265,23 +256,17 @@
|
||||||
<arg value="-xml=test-results/OpenSim.Services.InventoryService.Tests.dll-Results.xml" />
|
<arg value="-xml=test-results/OpenSim.Services.InventoryService.Tests.dll-Results.xml" />
|
||||||
</exec>
|
</exec>
|
||||||
|
|
||||||
<exec program="${nunitcmd}" failonerror="false" resultproperty="testresult.opensim.tests.permissions">
|
|
||||||
<arg value="./bin/OpenSim.Tests.Permissions.dll" />
|
|
||||||
<arg value="-xml=test-results/OpenSim.Tests.Permissions.dll-Results.xml" />
|
|
||||||
</exec>
|
|
||||||
|
|
||||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.tests)==0}" />
|
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.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.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.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.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.coremodules.tests)==0}" />
|
||||||
<!-- <fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.optionalmodules.tests)==0}" /> -->
|
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.optionalmodules.tests)==0}" />
|
||||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.framework.tests)==0}" />
|
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.framework.tests)==0}" />
|
||||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.data.tests)==0}" />
|
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.data.tests)==0}" />
|
||||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.capabilities.handlers.tests)==0}" />
|
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.capabilities.handlers.tests)==0}" />
|
||||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.services.inventoryservice.tests)==0}" />
|
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.services.inventoryservice.tests)==0}" />
|
||||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.tests.permissions)==0}" />
|
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
<target name="doxygen">
|
<target name="doxygen">
|
||||||
|
|
35
BUILDING.md
35
BUILDING.md
|
@ -1,35 +1,38 @@
|
||||||
# Building on Windows
|
# Building on Windows
|
||||||
|
|
||||||
Steps:
|
Steps:
|
||||||
|
|
||||||
* runprebuild.bat
|
* runprebuild.bat
|
||||||
* Load OpenSim.sln into Visual Studio .NET and build the solution.
|
* Load OpenSim.sln into Visual Studio .NET and build the solution.
|
||||||
* chdir bin
|
* chdir bin
|
||||||
* copy OpenSim.ini.example to OpenSim.ini and other appropriate files in bin/config-include
|
* copy OpenSim.ini.example to OpenSim.ini and other appropriate files in bin/config-include
|
||||||
* run OpenSim.exe
|
* run OpenSim.exe
|
||||||
|
|
||||||
# Building on Linux / Mac
|
# Building on Linux
|
||||||
|
|
||||||
Prereqs:
|
Prereqs:
|
||||||
|
* Mono >= 2.4.3
|
||||||
* Mono > 5.0
|
* Nant >= 0.85
|
||||||
* On some Linux distributions you may need to install additional packages.
|
* On some Linux distributions you may need to install additional packages.
|
||||||
* msbuild or xbuild if still supported by the mono version
|
See http://opensimulator.org/wiki/Dependencies for more information.
|
||||||
* See http://opensimulator.org/wiki/Dependencies for more information.
|
* May also use xbuild (included in mono distributions)
|
||||||
|
* May use Monodevelop, a cross-platform IDE
|
||||||
|
|
||||||
From the distribution type:
|
From the distribution type:
|
||||||
|
|
||||||
* ./runprebuild.sh
|
* ./runprebuild.sh
|
||||||
* type msbuild or xbuild
|
* nant (or !* xbuild)
|
||||||
* cd bin
|
* cd bin
|
||||||
* copy OpenSim.ini.example to OpenSim.ini and other appropriate files in bin/config-include
|
* copy OpenSim.ini.example to OpenSim.ini and other appropriate files in bin/config-include
|
||||||
* review and change those ini files according to your needs
|
* run mono OpenSim.exe
|
||||||
* windows: execute opensim.exe or opensim32.exe for small regions
|
!* xbuild option switches
|
||||||
* linux: run ./opensim.sh
|
!* clean: xbuild /target:clean
|
||||||
* msbuild (xbuild) option switches
|
!* debug: (default) xbuild /property:Configuration=Debug
|
||||||
* clean: msbuild /target:clean
|
!* release: xbuild /property:Configuration=Release
|
||||||
* debug: (default) msbuild /property:Configuration=Debug
|
|
||||||
* release: msbuild /property:Configuration=Release
|
# Using Monodevelop
|
||||||
|
|
||||||
|
From the distribution type:
|
||||||
|
* ./runprebuild.sh
|
||||||
|
* type monodevelop OpenSim.sln
|
||||||
|
|
||||||
# References
|
# References
|
||||||
|
|
||||||
|
|
|
@ -4,19 +4,37 @@ The following people have contributed to OpenSim (Thank you for your effort!)
|
||||||
These folks represent the current core team for OpenSim, and are the
|
These folks represent the current core team for OpenSim, and are the
|
||||||
people that make the day to day of OpenSim happen.
|
people that make the day to day of OpenSim happen.
|
||||||
|
|
||||||
|
* justincc (OSVW Consulting, justincc.org)
|
||||||
|
* chi11ken (Genkii)
|
||||||
|
* dahlia
|
||||||
* Melanie Thielker
|
* Melanie Thielker
|
||||||
* Diva (Crista Lopes, University of California, Irvine)
|
* Diva (Crista Lopes, University of California, Irvine)
|
||||||
* Robert Adams (MisterBlue)
|
* Dan Lake
|
||||||
|
* Marck
|
||||||
|
* Mic Bowman
|
||||||
|
* BlueWall (James Hughes)
|
||||||
|
* Nebadon Izumi (Michael Cerquoni, OSgrid)
|
||||||
|
* Snoopy Pfeffer
|
||||||
|
* Robert Adams
|
||||||
|
* Oren Hurvitz (Kitely)
|
||||||
* Kevin Cozens
|
* Kevin Cozens
|
||||||
* Leal Duarte (Ubit Umarov)
|
|
||||||
|
|
||||||
= Core Developers Following the White Rabbit =
|
= Core Developers Following the White Rabbit =
|
||||||
Core developers who have temporarily (we hope) gone chasing the white rabbit.
|
Core developers who have temporarily (we hope) gone chasing the white rabbit.
|
||||||
They are in all similar to the active core developers, except that they haven't
|
They are in all similar to the active core developers, except that they haven't
|
||||||
been that active lately, so their voting rights are awaiting their come back.
|
been that active lately, so their voting rights are awaiting their come back.
|
||||||
|
|
||||||
* Nebadon Izumi (Michael Cerquoni, OSgrid)
|
* MW (Tribal Media AB)
|
||||||
* Alicia Raven
|
* Adam Frisby (DeepThink Pty Ltd)
|
||||||
|
* lbsa71 (Tribal Media AB)
|
||||||
|
* Teravus (w3z)
|
||||||
|
* Ckrinke (Charles Krinke)
|
||||||
|
* Dr Scofield aka Dirk Husemann (IBM Research - Zurich)
|
||||||
|
* mikem (3Di)
|
||||||
|
* Homer_Horwitz
|
||||||
|
* nlin (3Di)
|
||||||
|
* Arthur Rodrigo S Valadares (IBM)
|
||||||
|
* John Hurliman
|
||||||
|
|
||||||
= Past Open Sim Developers =
|
= Past Open Sim Developers =
|
||||||
These folks are alumns of the OpenSim core group, but are now
|
These folks are alumns of the OpenSim core group, but are now
|
||||||
|
@ -38,26 +56,7 @@ where we are today.
|
||||||
* adjohn (Genkii)
|
* adjohn (Genkii)
|
||||||
* idb (Ian Brown)
|
* idb (Ian Brown)
|
||||||
* Johan Berntsson (3Di)
|
* Johan Berntsson (3Di)
|
||||||
* MW (Tribal Media AB)
|
|
||||||
* Adam Frisby (DeepThink Pty Ltd)
|
|
||||||
* lbsa71 (Tribal Media AB)
|
|
||||||
* Ckrinke (Charles Krinke)
|
|
||||||
* Dr Scofield aka Dirk Husemann (IBM Research - Zurich)
|
|
||||||
* mikem (3Di)
|
|
||||||
* Homer_Horwitz
|
|
||||||
* nlin (3Di)
|
|
||||||
* John Hurliman
|
|
||||||
* chi11ken (Genkii)
|
|
||||||
* dahlia
|
|
||||||
* justincc (OSVW Consulting, justincc.org)
|
|
||||||
* Arthur Rodrigo S Valadares (IBM)
|
|
||||||
* BlueWall (James Hughes)
|
|
||||||
* Dan Lake
|
|
||||||
* Marck
|
|
||||||
* Mic Bowman
|
|
||||||
* Oren Hurvitz (Kitely)
|
|
||||||
* Snoopy Pfeffer
|
|
||||||
* Teravus (w3z)
|
|
||||||
|
|
||||||
= Additional OpenSim Contributors =
|
= Additional OpenSim Contributors =
|
||||||
These folks have contributed code patches or content to OpenSimulator to help make it
|
These folks have contributed code patches or content to OpenSimulator to help make it
|
||||||
|
@ -69,9 +68,9 @@ what it is today.
|
||||||
* alex_carnell
|
* alex_carnell
|
||||||
* Alan Webb (IBM)
|
* Alan Webb (IBM)
|
||||||
* Aleric
|
* Aleric
|
||||||
|
* Alicia Raven
|
||||||
* Allen Kerensky
|
* Allen Kerensky
|
||||||
* BigFootAg
|
* BigFootAg
|
||||||
* Bill Blight
|
|
||||||
* BlueWall Slade
|
* BlueWall Slade
|
||||||
* bobshaffer2
|
* bobshaffer2
|
||||||
* brianw/Sir_Ahzz
|
* brianw/Sir_Ahzz
|
||||||
|
@ -89,14 +88,12 @@ what it is today.
|
||||||
* dmiles (Daxtron Labs)
|
* dmiles (Daxtron Labs)
|
||||||
* Dong Jun Lan (IBM)
|
* Dong Jun Lan (IBM)
|
||||||
* DoranZemlja
|
* DoranZemlja
|
||||||
* Drake Arconis
|
|
||||||
* dr0b3rts
|
* dr0b3rts
|
||||||
* dslake
|
* dslake
|
||||||
* eeyore
|
* eeyore
|
||||||
* FredoChaplin
|
* FredoChaplin
|
||||||
* FreakyTech
|
* FreakyTech
|
||||||
* Garmin Kawaguichi
|
* Garmin Kawaguichi
|
||||||
* Gavin Hird
|
|
||||||
* Gerhard
|
* Gerhard
|
||||||
* Godfrey
|
* Godfrey
|
||||||
* Greg C.
|
* Greg C.
|
||||||
|
@ -106,10 +103,7 @@ what it is today.
|
||||||
* Fernando Oliveira
|
* Fernando Oliveira
|
||||||
* Fly-Man
|
* Fly-Man
|
||||||
* Flyte Xevious
|
* Flyte Xevious
|
||||||
* Freaky Tech
|
|
||||||
* Garmin Kawaguichi
|
* Garmin Kawaguichi
|
||||||
* Geir Noklebye
|
|
||||||
* Glenn Martin (MOSES)
|
|
||||||
* Gryc Ueusp
|
* Gryc Ueusp
|
||||||
* H-H-H (ginge264)
|
* H-H-H (ginge264)
|
||||||
* Hiro Lecker
|
* Hiro Lecker
|
||||||
|
@ -117,7 +111,6 @@ what it is today.
|
||||||
* Imaze Rhiano
|
* Imaze Rhiano
|
||||||
* Intimidated
|
* Intimidated
|
||||||
* Jak Daniels
|
* Jak Daniels
|
||||||
* Jeff Kelly
|
|
||||||
* Jeremy Bongio (IBM)
|
* Jeremy Bongio (IBM)
|
||||||
* jhurliman
|
* jhurliman
|
||||||
* John R Sohn (XenReborn)
|
* John R Sohn (XenReborn)
|
||||||
|
@ -131,7 +124,6 @@ what it is today.
|
||||||
* KittyLiu
|
* KittyLiu
|
||||||
* Kurt Taylor (IBM)
|
* Kurt Taylor (IBM)
|
||||||
* Lani Global
|
* Lani Global
|
||||||
* lickx
|
|
||||||
* lillith_xue
|
* lillith_xue
|
||||||
* lkalif
|
* lkalif
|
||||||
* LuciusSirnah
|
* LuciusSirnah
|
||||||
|
@ -140,18 +132,14 @@ what it is today.
|
||||||
* Magnuz Binder
|
* Magnuz Binder
|
||||||
* maimedleech
|
* maimedleech
|
||||||
* Mana Janus
|
* Mana Janus
|
||||||
* Mandarinka Tasty
|
|
||||||
* MarcelEdward
|
* MarcelEdward
|
||||||
* Matt Lehmann
|
* Matt Lehmann
|
||||||
* mewtwo0641
|
|
||||||
* Mic Bowman
|
* Mic Bowman
|
||||||
* Michelle Argus
|
* Michelle Argus
|
||||||
* Michael Cortez (The Flotsam Project, http://osflotsam.org/)
|
* Michael Cortez (The Flotsam Project, http://osflotsam.org/)
|
||||||
* Michael Heilmann (MOSES)
|
|
||||||
* Micheil Merlin
|
* Micheil Merlin
|
||||||
* Mike Osias (IBM)
|
* Mike Osias (IBM)
|
||||||
* Mike Pitman (IBM)
|
* Mike Pitman (IBM)
|
||||||
* Mike Rieker (Dreamnation)
|
|
||||||
* mikemig
|
* mikemig
|
||||||
* mikkopa/_someone - RealXtend
|
* mikkopa/_someone - RealXtend
|
||||||
* Misterblue
|
* Misterblue
|
||||||
|
@ -165,14 +153,12 @@ what it is today.
|
||||||
* openlifegrid.com
|
* openlifegrid.com
|
||||||
* otakup0pe
|
* otakup0pe
|
||||||
* Pixel Tomsen
|
* Pixel Tomsen
|
||||||
* Quill Littlefeather
|
|
||||||
* ralphos
|
* ralphos
|
||||||
* RemedyTomm
|
* RemedyTomm
|
||||||
* Revolution
|
* Revolution
|
||||||
* Richard Alimi (IBM)
|
* Richard Alimi (IBM)
|
||||||
* Rick Alther (IBM)
|
* Rick Alther (IBM)
|
||||||
* Rob Smart (IBM)
|
* Rob Smart (IBM)
|
||||||
* Robert Louden (MOSES)
|
|
||||||
* Roger Kirkman (zadark)
|
* Roger Kirkman (zadark)
|
||||||
* rtomita
|
* rtomita
|
||||||
* Ruud Lathorp
|
* Ruud Lathorp
|
||||||
|
@ -184,21 +170,14 @@ what it is today.
|
||||||
* SignpostMarv
|
* SignpostMarv
|
||||||
* SpotOn3D
|
* SpotOn3D
|
||||||
* Stefan_Boom / stoehr
|
* Stefan_Boom / stoehr
|
||||||
* Steven Zielinski (MOSES)
|
|
||||||
* Stolen Ruby
|
|
||||||
* Strawberry Fride
|
* Strawberry Fride
|
||||||
* Talun
|
* Talun
|
||||||
* TechplexEngineer (Blake Bourque)
|
* TechplexEngineer (Blake Bourque)
|
||||||
* TBG Renfold
|
* TBG Renfold
|
||||||
* Terry Ford
|
|
||||||
* tglion
|
* tglion
|
||||||
* tlaukkan/Tommil (Tommi S. E. Laukkanen, Bubble Cloud)
|
* tlaukkan/Tommil (Tommi S. E. Laukkanen, Bubble Cloud)
|
||||||
* TomDataWorks
|
|
||||||
* TomTheDragon (muckwaddle)
|
|
||||||
* tyre
|
* tyre
|
||||||
* uriesk
|
|
||||||
* Vegaslon <vegaslon@gmail.com>
|
* Vegaslon <vegaslon@gmail.com>
|
||||||
* Vincent Sylvester
|
|
||||||
* VikingErik
|
* VikingErik
|
||||||
* Vytek
|
* Vytek
|
||||||
* webmage (IBM)
|
* webmage (IBM)
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -46,7 +46,7 @@ namespace OpenSim.Groups
|
||||||
public string AccessToken;
|
public string AccessToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ExtendedGroupMembersData
|
public class ExtendedGroupMembersData
|
||||||
{
|
{
|
||||||
// This is the only difference: this is a string
|
// This is the only difference: this is a string
|
||||||
public string AgentID;
|
public string AgentID;
|
||||||
|
@ -65,7 +65,7 @@ namespace OpenSim.Groups
|
||||||
public UUID RoleID;
|
public UUID RoleID;
|
||||||
// This is the only difference: this is a string
|
// This is the only difference: this is a string
|
||||||
public string MemberID;
|
public string MemberID;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct ExtendedGroupNoticeData
|
public struct ExtendedGroupNoticeData
|
||||||
|
|
|
@ -131,7 +131,7 @@ namespace OpenSim.Groups
|
||||||
{
|
{
|
||||||
if (!m_groupMessagingEnabled)
|
if (!m_groupMessagingEnabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
scene.RegisterModuleInterface<IGroupsMessagingModule>(this);
|
scene.RegisterModuleInterface<IGroupsMessagingModule>(this);
|
||||||
m_sceneList.Add(scene);
|
m_sceneList.Add(scene);
|
||||||
|
|
||||||
|
@ -163,7 +163,7 @@ namespace OpenSim.Groups
|
||||||
if (m_groupData == null)
|
if (m_groupData == null)
|
||||||
{
|
{
|
||||||
m_log.Error("[Groups.Messaging]: Could not get IGroupsServicesConnector, GroupsMessagingModule is now disabled.");
|
m_log.Error("[Groups.Messaging]: Could not get IGroupsServicesConnector, GroupsMessagingModule is now disabled.");
|
||||||
RemoveRegion(scene);
|
RemoveRegion(scene);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,7 +218,7 @@ namespace OpenSim.Groups
|
||||||
m_msgTransferModule = null;
|
m_msgTransferModule = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Type ReplaceableInterface
|
public Type ReplaceableInterface
|
||||||
{
|
{
|
||||||
get { return null; }
|
get { return null; }
|
||||||
}
|
}
|
||||||
|
@ -252,7 +252,7 @@ namespace OpenSim.Groups
|
||||||
|
|
||||||
m_debugEnabled = verbose;
|
m_debugEnabled = verbose;
|
||||||
|
|
||||||
MainConsole.Instance.Output("{0} verbose logging set to {1}", Name, m_debugEnabled);
|
MainConsole.Instance.OutputFormat("{0} verbose logging set to {1}", Name, m_debugEnabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -262,7 +262,7 @@ namespace OpenSim.Groups
|
||||||
{
|
{
|
||||||
if (m_debugEnabled)
|
if (m_debugEnabled)
|
||||||
m_log.DebugFormat("[Groups.Messaging]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
|
m_log.DebugFormat("[Groups.Messaging]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
|
||||||
|
|
||||||
GroupRecord groupInfo = m_groupData.GetGroupRecord(agentID.ToString(), groupID, null);
|
GroupRecord groupInfo = m_groupData.GetGroupRecord(agentID.ToString(), groupID, null);
|
||||||
|
|
||||||
if (groupInfo != null)
|
if (groupInfo != null)
|
||||||
|
@ -279,7 +279,7 @@ namespace OpenSim.Groups
|
||||||
{
|
{
|
||||||
SendMessageToGroup(im, groupID, UUID.Zero, null);
|
SendMessageToGroup(im, groupID, UUID.Zero, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendMessageToGroup(
|
public void SendMessageToGroup(
|
||||||
GridInstantMessage im, UUID groupID, UUID sendingAgentForGroupCalls, Func<GroupMembersData, bool> sendCondition)
|
GridInstantMessage im, UUID groupID, UUID sendingAgentForGroupCalls, Func<GroupMembersData, bool> sendCondition)
|
||||||
{
|
{
|
||||||
|
@ -355,9 +355,9 @@ namespace OpenSim.Groups
|
||||||
{
|
{
|
||||||
if (!sendCondition(member))
|
if (!sendCondition(member))
|
||||||
{
|
{
|
||||||
if (m_debugEnabled)
|
if (m_debugEnabled)
|
||||||
m_log.DebugFormat(
|
m_log.DebugFormat(
|
||||||
"[Groups.Messaging]: Not sending to {0} as they do not fulfill send condition",
|
"[Groups.Messaging]: Not sending to {0} as they do not fulfill send condition",
|
||||||
member.AgentID);
|
member.AgentID);
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
|
@ -366,7 +366,7 @@ namespace OpenSim.Groups
|
||||||
else if (hasAgentDroppedGroupChatSession(member.AgentID.ToString(), groupID))
|
else if (hasAgentDroppedGroupChatSession(member.AgentID.ToString(), groupID))
|
||||||
{
|
{
|
||||||
// Don't deliver messages to people who have dropped this session
|
// Don't deliver messages to people who have dropped this session
|
||||||
if (m_debugEnabled)
|
if (m_debugEnabled)
|
||||||
m_log.DebugFormat("[Groups.Messaging]: {0} has dropped session, not delivering to them", member.AgentID);
|
m_log.DebugFormat("[Groups.Messaging]: {0} has dropped session, not delivering to them", member.AgentID);
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
|
@ -414,7 +414,7 @@ namespace OpenSim.Groups
|
||||||
"[Groups.Messaging]: SendMessageToGroup for group {0} with {1} visible members, {2} online took {3}ms",
|
"[Groups.Messaging]: SendMessageToGroup for group {0} with {1} visible members, {2} online took {3}ms",
|
||||||
groupID, groupMembersCount, groupMembers.Count(), Environment.TickCount - requestStartTick);
|
groupID, groupMembersCount, groupMembers.Count(), Environment.TickCount - requestStartTick);
|
||||||
}
|
}
|
||||||
|
|
||||||
#region SimGridEventHandlers
|
#region SimGridEventHandlers
|
||||||
|
|
||||||
void OnClientLogin(IClientAPI client)
|
void OnClientLogin(IClientAPI client)
|
||||||
|
@ -445,13 +445,13 @@ namespace OpenSim.Groups
|
||||||
// The instant message module will only deliver messages of dialog types:
|
// The instant message module will only deliver messages of dialog types:
|
||||||
// MessageFromAgent, StartTyping, StopTyping, MessageFromObject
|
// MessageFromAgent, StartTyping, StopTyping, MessageFromObject
|
||||||
//
|
//
|
||||||
// Any other message type will not be delivered to a client by the
|
// Any other message type will not be delivered to a client by the
|
||||||
// Instant Message Module
|
// Instant Message Module
|
||||||
|
|
||||||
UUID regionID = new UUID(msg.RegionID);
|
UUID regionID = new UUID(msg.RegionID);
|
||||||
if (m_debugEnabled)
|
if (m_debugEnabled)
|
||||||
{
|
{
|
||||||
m_log.DebugFormat("[Groups.Messaging]: {0} called, IM from region {1}",
|
m_log.DebugFormat("[Groups.Messaging]: {0} called, IM from region {1}",
|
||||||
System.Reflection.MethodBase.GetCurrentMethod().Name, regionID);
|
System.Reflection.MethodBase.GetCurrentMethod().Name, regionID);
|
||||||
|
|
||||||
DebugGridInstantMessage(msg);
|
DebugGridInstantMessage(msg);
|
||||||
|
@ -508,7 +508,7 @@ namespace OpenSim.Groups
|
||||||
m_log.DebugFormat("[Groups.Messaging]: skipping agent {0} because he has an agent in region of origin", sp.UUID);
|
m_log.DebugFormat("[Groups.Messaging]: skipping agent {0} because he has an agent in region of origin", sp.UUID);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (m_debugEnabled)
|
if (m_debugEnabled)
|
||||||
m_log.DebugFormat("[Groups.Messaging]: not skipping agent {0}", sp.UUID);
|
m_log.DebugFormat("[Groups.Messaging]: not skipping agent {0}", sp.UUID);
|
||||||
|
@ -531,7 +531,7 @@ namespace OpenSim.Groups
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -555,7 +555,7 @@ namespace OpenSim.Groups
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case (byte)InstantMessageDialog.SessionSend:
|
case (byte)InstantMessageDialog.SessionSend:
|
||||||
// User hasn't dropped, so they're in the session,
|
// User hasn't dropped, so they're in the session,
|
||||||
// maybe we should deliver it.
|
// maybe we should deliver it.
|
||||||
IClientAPI client = GetActiveClient(new UUID(msg.toAgentID));
|
IClientAPI client = GetActiveClient(new UUID(msg.toAgentID));
|
||||||
if (client != null)
|
if (client != null)
|
||||||
|
@ -599,34 +599,35 @@ namespace OpenSim.Groups
|
||||||
{
|
{
|
||||||
if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Sending chatterbox invite instant message");
|
if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Sending chatterbox invite instant message");
|
||||||
|
|
||||||
UUID fromAgent = new UUID(msg.fromAgentID);
|
|
||||||
// Force? open the group session dialog???
|
// Force? open the group session dialog???
|
||||||
// and simultanously deliver the message, so we don't need to do a seperate client.SendInstantMessage(msg);
|
// and simultanously deliver the message, so we don't need to do a seperate client.SendInstantMessage(msg);
|
||||||
IEventQueue eq = activeClient.Scene.RequestModuleInterface<IEventQueue>();
|
IEventQueue eq = activeClient.Scene.RequestModuleInterface<IEventQueue>();
|
||||||
if (eq != null)
|
eq.ChatterboxInvitation(
|
||||||
{
|
GroupID
|
||||||
eq.ChatterboxInvitation(
|
, groupInfo.GroupName
|
||||||
GroupID
|
, new UUID(msg.fromAgentID)
|
||||||
, groupInfo.GroupName
|
, msg.message
|
||||||
, fromAgent
|
, AgentID
|
||||||
, msg.message
|
, msg.fromAgentName
|
||||||
, AgentID
|
, msg.dialog
|
||||||
, msg.fromAgentName
|
, msg.timestamp
|
||||||
, msg.dialog
|
, msg.offline == 1
|
||||||
, msg.timestamp
|
, (int)msg.ParentEstateID
|
||||||
, msg.offline == 1
|
, msg.Position
|
||||||
, (int)msg.ParentEstateID
|
, 1
|
||||||
, msg.Position
|
, new UUID(msg.imSessionID)
|
||||||
, 1
|
, msg.fromGroup
|
||||||
, new UUID(msg.imSessionID)
|
, OpenMetaverse.Utils.StringToBytes(groupInfo.GroupName)
|
||||||
, msg.fromGroup
|
);
|
||||||
, OpenMetaverse.Utils.StringToBytes(groupInfo.GroupName)
|
|
||||||
);
|
|
||||||
|
|
||||||
var update = new GroupChatListAgentUpdateData(AgentID);
|
eq.ChatterBoxSessionAgentListUpdates(
|
||||||
var updates = new List<GroupChatListAgentUpdateData> { update };
|
new UUID(GroupID)
|
||||||
eq.ChatterBoxSessionAgentListUpdates(GroupID, new UUID(msg.toAgentID), updates);
|
, AgentID
|
||||||
}
|
, new UUID(msg.toAgentID)
|
||||||
|
, false //canVoiceChat
|
||||||
|
, false //isModerator
|
||||||
|
, false //text mute
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -653,7 +654,7 @@ namespace OpenSim.Groups
|
||||||
UUID AgentID = new UUID(im.fromAgentID);
|
UUID AgentID = new UUID(im.fromAgentID);
|
||||||
|
|
||||||
GroupRecord groupInfo = m_groupData.GetGroupRecord(UUID.Zero.ToString(), GroupID, null);
|
GroupRecord groupInfo = m_groupData.GetGroupRecord(UUID.Zero.ToString(), GroupID, null);
|
||||||
|
|
||||||
if (groupInfo != null)
|
if (groupInfo != null)
|
||||||
{
|
{
|
||||||
AgentInvitedToGroupChatSession(AgentID.ToString(), GroupID);
|
AgentInvitedToGroupChatSession(AgentID.ToString(), GroupID);
|
||||||
|
@ -661,12 +662,14 @@ namespace OpenSim.Groups
|
||||||
ChatterBoxSessionStartReplyViaCaps(remoteClient, groupInfo.GroupName, GroupID);
|
ChatterBoxSessionStartReplyViaCaps(remoteClient, groupInfo.GroupName, GroupID);
|
||||||
|
|
||||||
IEventQueue queue = remoteClient.Scene.RequestModuleInterface<IEventQueue>();
|
IEventQueue queue = remoteClient.Scene.RequestModuleInterface<IEventQueue>();
|
||||||
if (queue != null)
|
queue.ChatterBoxSessionAgentListUpdates(
|
||||||
{
|
GroupID
|
||||||
var update = new GroupChatListAgentUpdateData(AgentID);
|
, AgentID
|
||||||
var updates = new List<GroupChatListAgentUpdateData> { update };
|
, new UUID(im.toAgentID)
|
||||||
queue.ChatterBoxSessionAgentListUpdates(GroupID, remoteClient.AgentId, updates);
|
, false //canVoiceChat
|
||||||
}
|
, false //isModerator
|
||||||
|
, false //text mute
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -676,7 +679,7 @@ namespace OpenSim.Groups
|
||||||
UUID GroupID = new UUID(im.imSessionID);
|
UUID GroupID = new UUID(im.imSessionID);
|
||||||
UUID AgentID = new UUID(im.fromAgentID);
|
UUID AgentID = new UUID(im.fromAgentID);
|
||||||
|
|
||||||
if (m_debugEnabled)
|
if (m_debugEnabled)
|
||||||
m_log.DebugFormat("[Groups.Messaging]: Send message to session for group {0} with session ID {1}", GroupID, im.imSessionID.ToString());
|
m_log.DebugFormat("[Groups.Messaging]: Send message to session for group {0} with session ID {1}", GroupID, im.imSessionID.ToString());
|
||||||
|
|
||||||
//If this agent is sending a message, then they want to be in the session
|
//If this agent is sending a message, then they want to be in the session
|
||||||
|
@ -708,7 +711,11 @@ namespace OpenSim.Groups
|
||||||
bodyMap.Add("session_info", sessionMap);
|
bodyMap.Add("session_info", sessionMap);
|
||||||
|
|
||||||
IEventQueue queue = remoteClient.Scene.RequestModuleInterface<IEventQueue>();
|
IEventQueue queue = remoteClient.Scene.RequestModuleInterface<IEventQueue>();
|
||||||
queue?.Enqueue(queue.BuildEvent("ChatterBoxSessionStartReply", bodyMap), remoteClient.AgentId);
|
|
||||||
|
if (queue != null)
|
||||||
|
{
|
||||||
|
queue.Enqueue(queue.BuildEvent("ChatterBoxSessionStartReply", bodyMap), remoteClient.AgentId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DebugGridInstantMessage(GridInstantMessage im)
|
private void DebugGridInstantMessage(GridInstantMessage im)
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -103,7 +103,7 @@ namespace OpenSim.Groups
|
||||||
if (!m_Enabled)
|
if (!m_Enabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_log.DebugFormat("[Groups]: Registering {0} with {1}", this.Name, scene.RegionInfo.RegionName);
|
m_log.DebugFormat("[Groups]: Registering {0} with {1}", this.Name, scene.RegionInfo.RegionName);
|
||||||
scene.RegisterModuleInterface<IGroupsServicesConnector>(this);
|
scene.RegisterModuleInterface<IGroupsServicesConnector>(this);
|
||||||
m_Scenes.Add(scene);
|
m_Scenes.Add(scene);
|
||||||
|
|
||||||
|
@ -135,7 +135,7 @@ namespace OpenSim.Groups
|
||||||
{
|
{
|
||||||
m_LocalGroupsConnector = new GroupsServiceLocalConnectorModule(m_Config, m_UserManagement);
|
m_LocalGroupsConnector = new GroupsServiceLocalConnectorModule(m_Config, m_UserManagement);
|
||||||
// Also, if local, create the endpoint for the HGGroupsService
|
// Also, if local, create the endpoint for the HGGroupsService
|
||||||
new HGGroupsServiceRobustConnector(m_Config, MainServer.Instance, string.Empty,
|
new HGGroupsServiceRobustConnector(m_Config, MainServer.Instance, string.Empty,
|
||||||
scene.RequestModuleInterface<IOfflineIMService>(), scene.RequestModuleInterface<IUserAccountService>());
|
scene.RequestModuleInterface<IOfflineIMService>(), scene.RequestModuleInterface<IUserAccountService>());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -170,7 +170,7 @@ namespace OpenSim.Groups
|
||||||
if (sp is ScenePresence && ((ScenePresence)sp).PresenceType != PresenceType.Npc)
|
if (sp is ScenePresence && ((ScenePresence)sp).PresenceType != PresenceType.Npc)
|
||||||
{
|
{
|
||||||
AgentCircuitData aCircuit = ((ScenePresence)sp).Scene.AuthenticateHandler.GetAgentCircuitData(client.AgentId);
|
AgentCircuitData aCircuit = ((ScenePresence)sp).Scene.AuthenticateHandler.GetAgentCircuitData(client.AgentId);
|
||||||
if (aCircuit != null && (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0 &&
|
if (aCircuit != null && (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0 &&
|
||||||
m_OfflineIM != null && m_Messaging != null)
|
m_OfflineIM != null && m_Messaging != null)
|
||||||
{
|
{
|
||||||
List<GridInstantMessage> ims = m_OfflineIM.GetMessages(aCircuit.AgentID);
|
List<GridInstantMessage> ims = m_OfflineIM.GetMessages(aCircuit.AgentID);
|
||||||
|
@ -184,12 +184,12 @@ namespace OpenSim.Groups
|
||||||
|
|
||||||
#region IGroupsServicesConnector
|
#region IGroupsServicesConnector
|
||||||
|
|
||||||
public UUID CreateGroup(UUID RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment,
|
public UUID CreateGroup(UUID RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment,
|
||||||
bool allowPublish, bool maturePublish, UUID founderID, out string reason)
|
bool allowPublish, bool maturePublish, UUID founderID, out string reason)
|
||||||
{
|
{
|
||||||
reason = string.Empty;
|
reason = string.Empty;
|
||||||
if (m_UserManagement.IsLocalGridUser(RequestingAgentID))
|
if (m_UserManagement.IsLocalGridUser(RequestingAgentID))
|
||||||
return m_LocalGroupsConnector.CreateGroup(RequestingAgentID, name, charter, showInList, insigniaID,
|
return m_LocalGroupsConnector.CreateGroup(RequestingAgentID, name, charter, showInList, insigniaID,
|
||||||
membershipFee, openEnrollment, allowPublish, maturePublish, founderID, out reason);
|
membershipFee, openEnrollment, allowPublish, maturePublish, founderID, out reason);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -198,14 +198,14 @@ namespace OpenSim.Groups
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool UpdateGroup(string RequestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee,
|
public bool UpdateGroup(string RequestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee,
|
||||||
bool openEnrollment, bool allowPublish, bool maturePublish, out string reason)
|
bool openEnrollment, bool allowPublish, bool maturePublish, out string reason)
|
||||||
{
|
{
|
||||||
reason = string.Empty;
|
reason = string.Empty;
|
||||||
string url = string.Empty;
|
string url = string.Empty;
|
||||||
string name = string.Empty;
|
string name = string.Empty;
|
||||||
if (IsLocal(groupID, out url, out name))
|
if (IsLocal(groupID, out url, out name))
|
||||||
return m_LocalGroupsConnector.UpdateGroup(AgentUUI(RequestingAgentID), groupID, charter, showInList, insigniaID, membershipFee,
|
return m_LocalGroupsConnector.UpdateGroup(AgentUUI(RequestingAgentID), groupID, charter, showInList, insigniaID, membershipFee,
|
||||||
openEnrollment, allowPublish, maturePublish, out reason);
|
openEnrollment, allowPublish, maturePublish, out reason);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -246,9 +246,9 @@ namespace OpenSim.Groups
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<DirGroupsReplyData> FindGroups(string RequestingAgentIDstr, string search)
|
public List<DirGroupsReplyData> FindGroups(string RequestingAgentID, string search)
|
||||||
{
|
{
|
||||||
return m_LocalGroupsConnector.FindGroups(RequestingAgentIDstr, search);
|
return m_LocalGroupsConnector.FindGroups(AgentUUI(RequestingAgentID), search);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<GroupMembersData> GetGroupMembers(string RequestingAgentID, UUID GroupID)
|
public List<GroupMembersData> GetGroupMembers(string RequestingAgentID, UUID GroupID)
|
||||||
|
@ -374,7 +374,7 @@ namespace OpenSim.Groups
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new List<GroupRoleMembersData>();
|
return new List<GroupRoleMembersData>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -605,8 +605,14 @@ namespace OpenSim.Groups
|
||||||
private string AgentUUI(string AgentIDStr)
|
private string AgentUUI(string AgentIDStr)
|
||||||
{
|
{
|
||||||
UUID AgentID = UUID.Zero;
|
UUID AgentID = UUID.Zero;
|
||||||
if (!UUID.TryParse(AgentIDStr, out AgentID) || AgentID == UUID.Zero)
|
try
|
||||||
return UUID.Zero.ToString();
|
{
|
||||||
|
AgentID = new UUID(AgentIDStr);
|
||||||
|
}
|
||||||
|
catch (FormatException)
|
||||||
|
{
|
||||||
|
return AgentID.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
if (m_UserManagement.IsLocalGridUser(AgentID))
|
if (m_UserManagement.IsLocalGridUser(AgentID))
|
||||||
return AgentID.ToString();
|
return AgentID.ToString();
|
||||||
|
@ -620,7 +626,7 @@ namespace OpenSim.Groups
|
||||||
}
|
}
|
||||||
if (agent != null)
|
if (agent != null)
|
||||||
return Util.ProduceUserUniversalIdentifier(agent);
|
return Util.ProduceUserUniversalIdentifier(agent);
|
||||||
|
|
||||||
// we don't know anything about this foreign user
|
// we don't know anything about this foreign user
|
||||||
// try asking the user management module, which may know more
|
// try asking the user management module, which may know more
|
||||||
return m_UserManagement.GetUserUUI(AgentID);
|
return m_UserManagement.GetUserUUI(AgentID);
|
||||||
|
@ -630,8 +636,14 @@ namespace OpenSim.Groups
|
||||||
private string AgentUUIForOutside(string AgentIDStr)
|
private string AgentUUIForOutside(string AgentIDStr)
|
||||||
{
|
{
|
||||||
UUID AgentID = UUID.Zero;
|
UUID AgentID = UUID.Zero;
|
||||||
if (!UUID.TryParse(AgentIDStr, out AgentID) || AgentID == UUID.Zero)
|
try
|
||||||
return UUID.Zero.ToString();
|
{
|
||||||
|
AgentID = new UUID(AgentIDStr);
|
||||||
|
}
|
||||||
|
catch (FormatException)
|
||||||
|
{
|
||||||
|
return AgentID.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
AgentCircuitData agent = null;
|
AgentCircuitData agent = null;
|
||||||
foreach (Scene scene in m_Scenes)
|
foreach (Scene scene in m_Scenes)
|
||||||
|
@ -652,7 +664,7 @@ namespace OpenSim.Groups
|
||||||
string url = string.Empty, first = string.Empty, last = string.Empty, tmp = string.Empty;
|
string url = string.Empty, first = string.Empty, last = string.Empty, tmp = string.Empty;
|
||||||
if (Util.ParseUniversalUserIdentifier(uID, out userID, out url, out first, out last, out tmp))
|
if (Util.ParseUniversalUserIdentifier(uID, out userID, out url, out first, out last, out tmp))
|
||||||
m_UserManagement.AddUser(userID, first, last, url);
|
m_UserManagement.AddUser(userID, first, last, url);
|
||||||
|
|
||||||
return userID;
|
return userID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,8 +64,8 @@ namespace OpenSim.Groups
|
||||||
|
|
||||||
m_log.DebugFormat("[Groups.RobustHGConnector]: Starting with config name {0}", m_ConfigName);
|
m_log.DebugFormat("[Groups.RobustHGConnector]: Starting with config name {0}", m_ConfigName);
|
||||||
|
|
||||||
string homeURI = Util.GetConfigVarFromSections<string>(config, "HomeURI",
|
string homeURI = Util.GetConfigVarFromSections<string>(config, "HomeURI",
|
||||||
new string[] { "Startup", "Hypergrid", m_ConfigName}, string.Empty);
|
new string[] { "Startup", "Hypergrid", m_ConfigName}, string.Empty);
|
||||||
if (homeURI == string.Empty)
|
if (homeURI == string.Empty)
|
||||||
throw new Exception(String.Format("[Groups.RobustHGConnector]: please provide the HomeURI [Startup] or in section {0}", m_ConfigName));
|
throw new Exception(String.Format("[Groups.RobustHGConnector]: please provide the HomeURI [Startup] or in section {0}", m_ConfigName));
|
||||||
|
|
||||||
|
@ -115,10 +115,9 @@ namespace OpenSim.Groups
|
||||||
protected override byte[] ProcessRequest(string path, Stream requestData,
|
protected override byte[] ProcessRequest(string path, Stream requestData,
|
||||||
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
||||||
{
|
{
|
||||||
string body;
|
StreamReader sr = new StreamReader(requestData);
|
||||||
using(StreamReader sr = new StreamReader(requestData))
|
string body = sr.ReadToEnd();
|
||||||
body = sr.ReadToEnd();
|
sr.Close();
|
||||||
|
|
||||||
body = body.Trim();
|
body = body.Trim();
|
||||||
|
|
||||||
//m_log.DebugFormat("[XXX]: query String: {0}", body);
|
//m_log.DebugFormat("[XXX]: query String: {0}", body);
|
||||||
|
|
|
@ -34,12 +34,12 @@ namespace OpenSim.Groups
|
||||||
{
|
{
|
||||||
public interface IGroupsServicesConnector
|
public interface IGroupsServicesConnector
|
||||||
{
|
{
|
||||||
UUID CreateGroup(UUID RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee,
|
UUID CreateGroup(UUID RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee,
|
||||||
bool openEnrollment, bool allowPublish, bool maturePublish, UUID founderID, out string reason);
|
bool openEnrollment, bool allowPublish, bool maturePublish, UUID founderID, out string reason);
|
||||||
bool UpdateGroup(string RequestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee,
|
bool UpdateGroup(string RequestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee,
|
||||||
bool openEnrollment, bool allowPublish, bool maturePublish, out string reason);
|
bool openEnrollment, bool allowPublish, bool maturePublish, out string reason);
|
||||||
ExtendedGroupRecord GetGroupRecord(string RequestingAgentID, UUID GroupID, string GroupName);
|
ExtendedGroupRecord GetGroupRecord(string RequestingAgentID, UUID GroupID, string GroupName);
|
||||||
List<DirGroupsReplyData> FindGroups(string RequestingAgentIDstr, string search);
|
List<DirGroupsReplyData> FindGroups(string RequestingAgentID, string search);
|
||||||
List<GroupMembersData> GetGroupMembers(string RequestingAgentID, UUID GroupID);
|
List<GroupMembersData> GetGroupMembers(string RequestingAgentID, UUID GroupID);
|
||||||
|
|
||||||
bool AddGroupRole(string RequestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers, out string reason);
|
bool AddGroupRole(string RequestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers, out string reason);
|
||||||
|
@ -75,7 +75,7 @@ namespace OpenSim.Groups
|
||||||
/// If the user is a member of the group then the data structure is returned. If not, then null is returned.
|
/// If the user is a member of the group then the data structure is returned. If not, then null is returned.
|
||||||
/// </returns>
|
/// </returns>
|
||||||
ExtendedGroupMembershipData GetAgentGroupMembership(string RequestingAgentID, string AgentID, UUID GroupID);
|
ExtendedGroupMembershipData GetAgentGroupMembership(string RequestingAgentID, string AgentID, UUID GroupID);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get information about the groups to which a user belongs.
|
/// Get information about the groups to which a user belongs.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -87,7 +87,7 @@ namespace OpenSim.Groups
|
||||||
/// </returns>
|
/// </returns>
|
||||||
List<GroupMembershipData> GetAgentGroupMemberships(string RequestingAgentID, string AgentID);
|
List<GroupMembershipData> GetAgentGroupMemberships(string RequestingAgentID, string AgentID);
|
||||||
|
|
||||||
bool AddGroupNotice(string RequestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message,
|
bool AddGroupNotice(string RequestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message,
|
||||||
bool hasAttachment, byte attType, string attName, UUID attItemID, string attOwnerID);
|
bool hasAttachment, byte attType, string attName, UUID attItemID, string attOwnerID);
|
||||||
GroupNoticeInfo GetGroupNotice(string RequestingAgentID, UUID noticeID);
|
GroupNoticeInfo GetGroupNotice(string RequestingAgentID, UUID noticeID);
|
||||||
List<ExtendedGroupNoticeData> GetGroupNotices(string RequestingAgentID, UUID GroupID);
|
List<ExtendedGroupNoticeData> GetGroupNotices(string RequestingAgentID, UUID GroupID);
|
||||||
|
|
|
@ -108,7 +108,7 @@ namespace OpenSim.Groups
|
||||||
if (!m_Enabled)
|
if (!m_Enabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_log.DebugFormat("[Groups]: Registering {0} with {1}", this.Name, scene.RegionInfo.RegionName);
|
m_log.DebugFormat("[Groups]: Registering {0} with {1}", this.Name, scene.RegionInfo.RegionName);
|
||||||
scene.RegisterModuleInterface<IGroupsServicesConnector>(this);
|
scene.RegisterModuleInterface<IGroupsServicesConnector>(this);
|
||||||
m_Scenes.Add(scene);
|
m_Scenes.Add(scene);
|
||||||
}
|
}
|
||||||
|
@ -146,16 +146,16 @@ namespace OpenSim.Groups
|
||||||
|
|
||||||
#region IGroupsServicesConnector
|
#region IGroupsServicesConnector
|
||||||
|
|
||||||
public UUID CreateGroup(UUID RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment,
|
public UUID CreateGroup(UUID RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment,
|
||||||
bool allowPublish, bool maturePublish, UUID founderID, out string reason)
|
bool allowPublish, bool maturePublish, UUID founderID, out string reason)
|
||||||
{
|
{
|
||||||
m_log.DebugFormat("[Groups]: Creating group {0}", name);
|
m_log.DebugFormat("[Groups]: Creating group {0}", name);
|
||||||
reason = string.Empty;
|
reason = string.Empty;
|
||||||
return m_GroupsService.CreateGroup(RequestingAgentID.ToString(), name, charter, showInList, insigniaID,
|
return m_GroupsService.CreateGroup(RequestingAgentID.ToString(), name, charter, showInList, insigniaID,
|
||||||
membershipFee, openEnrollment, allowPublish, maturePublish, founderID, out reason);
|
membershipFee, openEnrollment, allowPublish, maturePublish, founderID, out reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool UpdateGroup(string RequestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee,
|
public bool UpdateGroup(string RequestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee,
|
||||||
bool openEnrollment, bool allowPublish, bool maturePublish, out string reason)
|
bool openEnrollment, bool allowPublish, bool maturePublish, out string reason)
|
||||||
{
|
{
|
||||||
reason = string.Empty;
|
reason = string.Empty;
|
||||||
|
@ -173,9 +173,9 @@ namespace OpenSim.Groups
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<DirGroupsReplyData> FindGroups(string RequestingAgentIDstr, string search)
|
public List<DirGroupsReplyData> FindGroups(string RequestingAgentID, string search)
|
||||||
{
|
{
|
||||||
return m_GroupsService.FindGroups(RequestingAgentIDstr, search);
|
return m_GroupsService.FindGroups(RequestingAgentID, search);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<GroupMembersData> GetGroupMembers(string RequestingAgentID, UUID GroupID)
|
public List<GroupMembersData> GetGroupMembers(string RequestingAgentID, UUID GroupID)
|
||||||
|
@ -296,7 +296,7 @@ namespace OpenSim.Groups
|
||||||
public bool AddGroupNotice(string RequestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message,
|
public bool AddGroupNotice(string RequestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message,
|
||||||
bool hasAttachment, byte attType, string attName, UUID attItemID, string attOwnerID)
|
bool hasAttachment, byte attType, string attName, UUID attItemID, string attOwnerID)
|
||||||
{
|
{
|
||||||
return m_GroupsService.AddGroupNotice(RequestingAgentID, groupID, noticeID, fromName, subject, message,
|
return m_GroupsService.AddGroupNotice(RequestingAgentID, groupID, noticeID, fromName, subject, message,
|
||||||
hasAttachment, attType, attName, attItemID, attOwnerID);
|
hasAttachment, attType, attName, attItemID, attOwnerID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using Mono.Addins;
|
using Mono.Addins;
|
||||||
|
|
||||||
// General Information about an assembly is controlled through the following
|
// General Information about an assembly is controlled through the following
|
||||||
// set of attributes. Change these attribute values to modify the information
|
// set of attributes. Change these attribute values to modify the information
|
||||||
// associated with an assembly.
|
// associated with an assembly.
|
||||||
[assembly: AssemblyTitle("OpenSim.Addons.Groups")]
|
[assembly: AssemblyTitle("OpenSim.Addons.Groups")]
|
||||||
|
@ -15,8 +15,8 @@ using Mono.Addins;
|
||||||
[assembly: AssemblyTrademark("")]
|
[assembly: AssemblyTrademark("")]
|
||||||
[assembly: AssemblyCulture("")]
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
// Setting ComVisible to false makes the types in this assembly not visible
|
// Setting ComVisible to false makes the types in this assembly not visible
|
||||||
// to COM components. If you need to access a type in this assembly from
|
// to COM components. If you need to access a type in this assembly from
|
||||||
// COM, set the ComVisible attribute to true on that type.
|
// COM, set the ComVisible attribute to true on that type.
|
||||||
[assembly: ComVisible(false)]
|
[assembly: ComVisible(false)]
|
||||||
|
|
||||||
|
@ -26,11 +26,11 @@ using Mono.Addins;
|
||||||
// Version information for an assembly consists of the following four values:
|
// Version information for an assembly consists of the following four values:
|
||||||
//
|
//
|
||||||
// Major Version
|
// Major Version
|
||||||
// Minor Version
|
// Minor Version
|
||||||
// Build Number
|
// Build Number
|
||||||
// Revision
|
// Revision
|
||||||
//
|
//
|
||||||
[assembly: AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)]
|
[assembly: AssemblyVersion("0.8.1.*")]
|
||||||
|
|
||||||
[assembly: Addin("OpenSim.Groups", OpenSim.VersionInfo.VersionNumber)]
|
[assembly: Addin("OpenSim.Groups", OpenSim.VersionInfo.VersionNumber)]
|
||||||
[assembly: AddinDependency("OpenSim.Region.Framework", OpenSim.VersionInfo.VersionNumber)]
|
[assembly: AddinDependency("OpenSim.Region.Framework", OpenSim.VersionInfo.VersionNumber)]
|
||||||
|
|
|
@ -41,7 +41,7 @@ using Nini.Config;
|
||||||
|
|
||||||
namespace OpenSim.Groups
|
namespace OpenSim.Groups
|
||||||
{
|
{
|
||||||
public class GroupsServiceRemoteConnector
|
public class GroupsServiceRemoteConnector
|
||||||
{
|
{
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ namespace OpenSim.Groups
|
||||||
}
|
}
|
||||||
///
|
///
|
||||||
|
|
||||||
m_log.DebugFormat("[Groups.RemoteConnector]: Groups server at {0}, authentication {1}",
|
m_log.DebugFormat("[Groups.RemoteConnector]: Groups server at {0}, authentication {1}",
|
||||||
m_ServerURI, (m_Auth == null ? "None" : m_Auth.GetType().ToString()));
|
m_ServerURI, (m_Auth == null ? "None" : m_Auth.GetType().ToString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,7 +153,7 @@ namespace OpenSim.Groups
|
||||||
return GroupsDataUtils.GroupRecord((Dictionary<string, object>)ret["RESULT"]);
|
return GroupsDataUtils.GroupRecord((Dictionary<string, object>)ret["RESULT"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<DirGroupsReplyData> FindGroups(string RequestingAgentIDstr, string query)
|
public List<DirGroupsReplyData> FindGroups(string RequestingAgentID, string query)
|
||||||
{
|
{
|
||||||
List<DirGroupsReplyData> hits = new List<DirGroupsReplyData>();
|
List<DirGroupsReplyData> hits = new List<DirGroupsReplyData>();
|
||||||
if (string.IsNullOrEmpty(query))
|
if (string.IsNullOrEmpty(query))
|
||||||
|
@ -161,7 +161,7 @@ namespace OpenSim.Groups
|
||||||
|
|
||||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
||||||
sendData["Query"] = query;
|
sendData["Query"] = query;
|
||||||
sendData["RequestingAgentID"] = RequestingAgentIDstr;
|
sendData["RequestingAgentID"] = RequestingAgentID;
|
||||||
|
|
||||||
Dictionary<string, object> ret = MakeRequest("FINDGROUPS", sendData);
|
Dictionary<string, object> ret = MakeRequest("FINDGROUPS", sendData);
|
||||||
|
|
||||||
|
|
|
@ -113,7 +113,7 @@ namespace OpenSim.Groups
|
||||||
if (!m_Enabled)
|
if (!m_Enabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_log.DebugFormat("[Groups.RemoteConnector]: Registering {0} with {1}", this.Name, scene.RegionInfo.RegionName);
|
m_log.DebugFormat("[Groups.RemoteConnector]: Registering {0} with {1}", this.Name, scene.RegionInfo.RegionName);
|
||||||
scene.RegisterModuleInterface<IGroupsServicesConnector>(this);
|
scene.RegisterModuleInterface<IGroupsServicesConnector>(this);
|
||||||
m_Scenes.Add(scene);
|
m_Scenes.Add(scene);
|
||||||
}
|
}
|
||||||
|
@ -151,7 +151,7 @@ namespace OpenSim.Groups
|
||||||
|
|
||||||
#region IGroupsServicesConnector
|
#region IGroupsServicesConnector
|
||||||
|
|
||||||
public UUID CreateGroup(UUID RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment,
|
public UUID CreateGroup(UUID RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment,
|
||||||
bool allowPublish, bool maturePublish, UUID founderID, out string reason)
|
bool allowPublish, bool maturePublish, UUID founderID, out string reason)
|
||||||
{
|
{
|
||||||
m_log.DebugFormat("[Groups.RemoteConnector]: Creating group {0}", name);
|
m_log.DebugFormat("[Groups.RemoteConnector]: Creating group {0}", name);
|
||||||
|
@ -167,7 +167,7 @@ namespace OpenSim.Groups
|
||||||
return groupID;
|
return groupID;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool UpdateGroup(string RequestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee,
|
public bool UpdateGroup(string RequestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee,
|
||||||
bool openEnrollment, bool allowPublish, bool maturePublish, out string reason)
|
bool openEnrollment, bool allowPublish, bool maturePublish, out string reason)
|
||||||
{
|
{
|
||||||
string r = string.Empty;
|
string r = string.Empty;
|
||||||
|
@ -186,16 +186,16 @@ namespace OpenSim.Groups
|
||||||
if (GroupID == UUID.Zero && (GroupName == null || GroupName != null && GroupName == string.Empty))
|
if (GroupID == UUID.Zero && (GroupName == null || GroupName != null && GroupName == string.Empty))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
return m_CacheWrapper.GetGroupRecord(RequestingAgentID,GroupID,GroupName, delegate
|
return m_CacheWrapper.GetGroupRecord(RequestingAgentID,GroupID,GroupName, delegate
|
||||||
{
|
{
|
||||||
return m_GroupsService.GetGroupRecord(RequestingAgentID, GroupID, GroupName);
|
return m_GroupsService.GetGroupRecord(RequestingAgentID, GroupID, GroupName);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<DirGroupsReplyData> FindGroups(string RequestingAgentIDstr, string search)
|
public List<DirGroupsReplyData> FindGroups(string RequestingAgentID, string search)
|
||||||
{
|
{
|
||||||
// TODO!
|
// TODO!
|
||||||
return m_GroupsService.FindGroups(RequestingAgentIDstr, search);
|
return m_GroupsService.FindGroups(RequestingAgentID, search);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool AddAgentToGroup(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID, string token, out string reason)
|
public bool AddAgentToGroup(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID, string token, out string reason)
|
||||||
|
@ -362,7 +362,7 @@ namespace OpenSim.Groups
|
||||||
m_GroupsService.RemoveAgentToGroupInvite(RequestingAgentID, inviteID);
|
m_GroupsService.RemoveAgentToGroupInvite(RequestingAgentID, inviteID);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool AddGroupNotice(string RequestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message,
|
public bool AddGroupNotice(string RequestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message,
|
||||||
bool hasAttachment, byte attType, string attName, UUID attItemID, string attOwnerID)
|
bool hasAttachment, byte attType, string attName, UUID attItemID, string attOwnerID)
|
||||||
{
|
{
|
||||||
GroupNoticeInfo notice = new GroupNoticeInfo();
|
GroupNoticeInfo notice = new GroupNoticeInfo();
|
||||||
|
|
|
@ -91,10 +91,9 @@ namespace OpenSim.Groups
|
||||||
protected override byte[] ProcessRequest(string path, Stream requestData,
|
protected override byte[] ProcessRequest(string path, Stream requestData,
|
||||||
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
||||||
{
|
{
|
||||||
string body;
|
StreamReader sr = new StreamReader(requestData);
|
||||||
using(StreamReader sr = new StreamReader(requestData))
|
string body = sr.ReadToEnd();
|
||||||
body = sr.ReadToEnd();
|
sr.Close();
|
||||||
|
|
||||||
body = body.Trim();
|
body = body.Trim();
|
||||||
|
|
||||||
//m_log.DebugFormat("[XXX]: query String: {0}", body);
|
//m_log.DebugFormat("[XXX]: query String: {0}", body);
|
||||||
|
@ -287,7 +286,7 @@ namespace OpenSim.Groups
|
||||||
string requestingAgentID = request["RequestingAgentID"].ToString();
|
string requestingAgentID = request["RequestingAgentID"].ToString();
|
||||||
|
|
||||||
if (!m_GroupsService.RemoveAgentFromGroup(requestingAgentID, agentID, groupID))
|
if (!m_GroupsService.RemoveAgentFromGroup(requestingAgentID, agentID, groupID))
|
||||||
NullResult(result, string.Format("Insufficient permissions. {0}", agentID));
|
NullResult(result, string.Format("Insufficient permissions.", agentID));
|
||||||
else
|
else
|
||||||
result["RESULT"] = "true";
|
result["RESULT"] = "true";
|
||||||
}
|
}
|
||||||
|
@ -394,7 +393,7 @@ namespace OpenSim.Groups
|
||||||
|
|
||||||
if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("GroupID") || !request.ContainsKey("RoleID") ||
|
if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("GroupID") || !request.ContainsKey("RoleID") ||
|
||||||
!request.ContainsKey("Name") || !request.ContainsKey("Description") || !request.ContainsKey("Title") ||
|
!request.ContainsKey("Name") || !request.ContainsKey("Description") || !request.ContainsKey("Title") ||
|
||||||
!request.ContainsKey("Powers") || !request.ContainsKey("OP"))
|
!request.ContainsKey("Powers") || !request.ContainsKey("OP"))
|
||||||
NullResult(result, "Bad network data");
|
NullResult(result, "Bad network data");
|
||||||
|
|
||||||
else
|
else
|
||||||
|
@ -520,11 +519,11 @@ namespace OpenSim.Groups
|
||||||
|
|
||||||
bool success = false;
|
bool success = false;
|
||||||
if (op == "ADD")
|
if (op == "ADD")
|
||||||
success = m_GroupsService.AddAgentToGroupRole(request["RequestingAgentID"].ToString(), request["AgentID"].ToString(),
|
success = m_GroupsService.AddAgentToGroupRole(request["RequestingAgentID"].ToString(), request["AgentID"].ToString(),
|
||||||
new UUID(request["GroupID"].ToString()), new UUID(request["RoleID"].ToString()));
|
new UUID(request["GroupID"].ToString()), new UUID(request["RoleID"].ToString()));
|
||||||
|
|
||||||
else if (op == "DELETE")
|
else if (op == "DELETE")
|
||||||
success = m_GroupsService.RemoveAgentFromGroupRole(request["RequestingAgentID"].ToString(), request["AgentID"].ToString(),
|
success = m_GroupsService.RemoveAgentFromGroupRole(request["RequestingAgentID"].ToString(), request["AgentID"].ToString(),
|
||||||
new UUID(request["GroupID"].ToString()), new UUID(request["RoleID"].ToString()));
|
new UUID(request["GroupID"].ToString()), new UUID(request["RoleID"].ToString()));
|
||||||
|
|
||||||
result["RESULT"] = success.ToString();
|
result["RESULT"] = success.ToString();
|
||||||
|
@ -648,8 +647,8 @@ namespace OpenSim.Groups
|
||||||
string op = request["OP"].ToString();
|
string op = request["OP"].ToString();
|
||||||
|
|
||||||
if (op == "ADD" && request.ContainsKey("GroupID") && request.ContainsKey("RoleID") && request.ContainsKey("AgentID"))
|
if (op == "ADD" && request.ContainsKey("GroupID") && request.ContainsKey("RoleID") && request.ContainsKey("AgentID"))
|
||||||
{
|
{
|
||||||
bool success = m_GroupsService.AddAgentToGroupInvite(request["RequestingAgentID"].ToString(),
|
bool success = m_GroupsService.AddAgentToGroupInvite(request["RequestingAgentID"].ToString(),
|
||||||
new UUID(request["InviteID"].ToString()), new UUID(request["GroupID"].ToString()),
|
new UUID(request["InviteID"].ToString()), new UUID(request["GroupID"].ToString()),
|
||||||
new UUID(request["RoleID"].ToString()), request["AgentID"].ToString());
|
new UUID(request["RoleID"].ToString()), request["AgentID"].ToString());
|
||||||
|
|
||||||
|
@ -665,7 +664,7 @@ namespace OpenSim.Groups
|
||||||
}
|
}
|
||||||
else if (op == "GET")
|
else if (op == "GET")
|
||||||
{
|
{
|
||||||
GroupInviteInfo invite = m_GroupsService.GetAgentToGroupInvite(request["RequestingAgentID"].ToString(),
|
GroupInviteInfo invite = m_GroupsService.GetAgentToGroupInvite(request["RequestingAgentID"].ToString(),
|
||||||
new UUID(request["InviteID"].ToString()));
|
new UUID(request["InviteID"].ToString()));
|
||||||
|
|
||||||
if (invite != null)
|
if (invite != null)
|
||||||
|
|
|
@ -43,63 +43,60 @@ namespace OpenSim.Groups
|
||||||
{
|
{
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
public const GroupPowers DefaultEveryonePowers =
|
public const GroupPowers DefaultEveryonePowers = GroupPowers.AllowSetHome |
|
||||||
GroupPowers.AllowSetHome |
|
GroupPowers.Accountable |
|
||||||
GroupPowers.Accountable |
|
GroupPowers.JoinChat |
|
||||||
GroupPowers.JoinChat |
|
GroupPowers.AllowVoiceChat |
|
||||||
GroupPowers.AllowVoiceChat |
|
GroupPowers.ReceiveNotices |
|
||||||
GroupPowers.ReceiveNotices |
|
GroupPowers.StartProposal |
|
||||||
GroupPowers.StartProposal |
|
GroupPowers.VoteOnProposal;
|
||||||
GroupPowers.VoteOnProposal;
|
|
||||||
|
|
||||||
public const GroupPowers OfficersPowers = DefaultEveryonePowers |
|
public const GroupPowers OwnerPowers = GroupPowers.Accountable |
|
||||||
GroupPowers.AllowFly |
|
GroupPowers.AllowEditLand |
|
||||||
GroupPowers.AllowLandmark |
|
GroupPowers.AllowFly |
|
||||||
GroupPowers.AllowRez |
|
GroupPowers.AllowLandmark |
|
||||||
GroupPowers.AssignMemberLimited |
|
GroupPowers.AllowRez |
|
||||||
GroupPowers.ChangeIdentity |
|
GroupPowers.AllowSetHome |
|
||||||
GroupPowers.ChangeMedia |
|
GroupPowers.AllowVoiceChat |
|
||||||
GroupPowers.ChangeOptions |
|
GroupPowers.AssignMember |
|
||||||
GroupPowers.DeedObject |
|
GroupPowers.AssignMemberLimited |
|
||||||
GroupPowers.Eject |
|
GroupPowers.ChangeActions |
|
||||||
GroupPowers.FindPlaces |
|
GroupPowers.ChangeIdentity |
|
||||||
GroupPowers.Invite |
|
GroupPowers.ChangeMedia |
|
||||||
GroupPowers.LandChangeIdentity |
|
GroupPowers.ChangeOptions |
|
||||||
GroupPowers.LandDeed |
|
GroupPowers.CreateRole |
|
||||||
GroupPowers.LandDivideJoin |
|
GroupPowers.DeedObject |
|
||||||
GroupPowers.LandEdit |
|
GroupPowers.DeleteRole |
|
||||||
GroupPowers.AllowEnvironment |
|
GroupPowers.Eject |
|
||||||
GroupPowers.LandEjectAndFreeze |
|
GroupPowers.FindPlaces |
|
||||||
GroupPowers.LandGardening |
|
GroupPowers.HostEvent |
|
||||||
GroupPowers.LandManageAllowed |
|
GroupPowers.Invite |
|
||||||
GroupPowers.LandManageBanned |
|
GroupPowers.JoinChat |
|
||||||
GroupPowers.LandManagePasses |
|
GroupPowers.LandChangeIdentity |
|
||||||
GroupPowers.LandOptions |
|
GroupPowers.LandDeed |
|
||||||
GroupPowers.LandRelease |
|
GroupPowers.LandDivideJoin |
|
||||||
GroupPowers.LandSetSale |
|
GroupPowers.LandEdit |
|
||||||
GroupPowers.MemberVisible |
|
GroupPowers.LandEjectAndFreeze |
|
||||||
GroupPowers.ModerateChat |
|
GroupPowers.LandGardening |
|
||||||
GroupPowers.ObjectManipulate |
|
GroupPowers.LandManageAllowed |
|
||||||
GroupPowers.ObjectSetForSale |
|
GroupPowers.LandManageBanned |
|
||||||
GroupPowers.ReturnGroupOwned |
|
GroupPowers.LandManagePasses |
|
||||||
GroupPowers.ReturnGroupSet |
|
GroupPowers.LandOptions |
|
||||||
GroupPowers.ReturnNonGroup |
|
GroupPowers.LandRelease |
|
||||||
GroupPowers.RoleProperties |
|
GroupPowers.LandSetSale |
|
||||||
GroupPowers.SendNotices |
|
GroupPowers.ModerateChat |
|
||||||
GroupPowers.SetLandingPoint;
|
GroupPowers.ObjectManipulate |
|
||||||
|
GroupPowers.ObjectSetForSale |
|
||||||
public const GroupPowers OwnerPowers = OfficersPowers |
|
GroupPowers.ReceiveNotices |
|
||||||
GroupPowers.Accountable |
|
GroupPowers.RemoveMember |
|
||||||
GroupPowers.AllowEditLand |
|
GroupPowers.ReturnGroupOwned |
|
||||||
GroupPowers.AssignMember |
|
GroupPowers.ReturnGroupSet |
|
||||||
GroupPowers.ChangeActions |
|
GroupPowers.ReturnNonGroup |
|
||||||
GroupPowers.CreateRole |
|
GroupPowers.RoleProperties |
|
||||||
GroupPowers.DeleteRole |
|
GroupPowers.SendNotices |
|
||||||
GroupPowers.ExperienceAdmin |
|
GroupPowers.SetLandingPoint |
|
||||||
GroupPowers.ExperienceCreator |
|
GroupPowers.StartProposal |
|
||||||
GroupPowers.GroupBanAccess |
|
GroupPowers.VoteOnProposal;
|
||||||
GroupPowers.HostEvent |
|
|
||||||
GroupPowers.RemoveMember;
|
|
||||||
|
|
||||||
#region Daily Cleanup
|
#region Daily Cleanup
|
||||||
|
|
||||||
|
@ -129,7 +126,7 @@ namespace OpenSim.Groups
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
public UUID CreateGroup(string RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment,
|
public UUID CreateGroup(string RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment,
|
||||||
bool allowPublish, bool maturePublish, UUID founderID, out string reason)
|
bool allowPublish, bool maturePublish, UUID founderID, out string reason)
|
||||||
{
|
{
|
||||||
reason = string.Empty;
|
reason = string.Empty;
|
||||||
|
@ -154,25 +151,20 @@ namespace OpenSim.Groups
|
||||||
data.Data["ShowInList"] = showInList ? "1" : "0";
|
data.Data["ShowInList"] = showInList ? "1" : "0";
|
||||||
data.Data["AllowPublish"] = allowPublish ? "1" : "0";
|
data.Data["AllowPublish"] = allowPublish ? "1" : "0";
|
||||||
data.Data["MaturePublish"] = maturePublish ? "1" : "0";
|
data.Data["MaturePublish"] = maturePublish ? "1" : "0";
|
||||||
UUID ownerRoleID = UUID.Random();
|
UUID roleID = UUID.Random();
|
||||||
data.Data["OwnerRoleID"] = ownerRoleID.ToString();
|
data.Data["OwnerRoleID"] = roleID.ToString();
|
||||||
|
|
||||||
if (!m_Database.StoreGroup(data))
|
if (!m_Database.StoreGroup(data))
|
||||||
return UUID.Zero;
|
return UUID.Zero;
|
||||||
|
|
||||||
// Create Everyone role
|
// Create Everyone role
|
||||||
_AddOrUpdateGroupRole(RequestingAgentID, data.GroupID, UUID.Zero, "Everyone", "Everyone in the group is in the everyone role.", "Member of " + name, (ulong)DefaultEveryonePowers, true);
|
_AddOrUpdateGroupRole(RequestingAgentID, data.GroupID, UUID.Zero, "Everyone", "Everyone in the group", "Member of " + name, (ulong)DefaultEveryonePowers, true);
|
||||||
|
|
||||||
// Create Officers role
|
|
||||||
UUID officersRoleID = UUID.Random();
|
|
||||||
_AddOrUpdateGroupRole(RequestingAgentID, data.GroupID, officersRoleID, "Officers", "The officers of the group, with more powers than regular members.", "Officer of " + name, (ulong)OfficersPowers, true);
|
|
||||||
|
|
||||||
// Create Owner role
|
// Create Owner role
|
||||||
_AddOrUpdateGroupRole(RequestingAgentID, data.GroupID, ownerRoleID, "Owners", "Owners of the group", "Owner of " + name, (ulong)OwnerPowers, true);
|
_AddOrUpdateGroupRole(RequestingAgentID, data.GroupID, roleID, "Owners", "Owners of the group", "Owner of " + name, (ulong)OwnerPowers, true);
|
||||||
|
|
||||||
// Add founder to group
|
// Add founder to group
|
||||||
_AddAgentToGroup(RequestingAgentID, founderID.ToString(), data.GroupID, ownerRoleID);
|
_AddAgentToGroup(RequestingAgentID, founderID.ToString(), data.GroupID, roleID);
|
||||||
_AddAgentToGroup(RequestingAgentID, founderID.ToString(), data.GroupID, officersRoleID);
|
|
||||||
|
|
||||||
return data.GroupID;
|
return data.GroupID;
|
||||||
}
|
}
|
||||||
|
@ -231,22 +223,15 @@ namespace OpenSim.Groups
|
||||||
if (d.Data.ContainsKey("Location") && d.Data["Location"] != string.Empty)
|
if (d.Data.ContainsKey("Location") && d.Data["Location"] != string.Empty)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
int nmembers = m_Database.MemberCount(d.GroupID);
|
|
||||||
if(nmembers == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
DirGroupsReplyData g = new DirGroupsReplyData();
|
DirGroupsReplyData g = new DirGroupsReplyData();
|
||||||
|
g.groupID = d.GroupID;
|
||||||
|
|
||||||
if (d.Data.ContainsKey("Name"))
|
if (d.Data.ContainsKey("Name"))
|
||||||
g.groupName = d.Data["Name"];
|
g.groupName = d.Data["Name"];
|
||||||
else
|
else
|
||||||
{
|
|
||||||
m_log.DebugFormat("[Groups]: Key Name not found");
|
m_log.DebugFormat("[Groups]: Key Name not found");
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
g.groupID = d.GroupID;
|
g.members = m_Database.MemberCount(d.GroupID);
|
||||||
g.members = nmembers;
|
|
||||||
|
|
||||||
groups.Add(g);
|
groups.Add(g);
|
||||||
}
|
}
|
||||||
|
@ -279,7 +264,7 @@ namespace OpenSim.Groups
|
||||||
if (ownerRole != null)
|
if (ownerRole != null)
|
||||||
ownerRoleID = ownerRole.RoleID;
|
ownerRoleID = ownerRole.RoleID;
|
||||||
|
|
||||||
// Check visibility?
|
// Check visibility?
|
||||||
// When we don't want to check visibility, we pass it "all" as the requestingAgentID
|
// When we don't want to check visibility, we pass it "all" as the requestingAgentID
|
||||||
bool checkVisibility = !RequestingAgentID.Equals(UUID.Zero.ToString());
|
bool checkVisibility = !RequestingAgentID.Equals(UUID.Zero.ToString());
|
||||||
|
|
||||||
|
@ -322,21 +307,6 @@ namespace OpenSim.Groups
|
||||||
m.Contribution = Int32.Parse(d.Data["Contribution"]);
|
m.Contribution = Int32.Parse(d.Data["Contribution"]);
|
||||||
m.ListInProfile = d.Data["ListInProfile"] == "1" ? true : false;
|
m.ListInProfile = d.Data["ListInProfile"] == "1" ? true : false;
|
||||||
|
|
||||||
GridUserData gud = m_GridUserService.Get(d.PrincipalID);
|
|
||||||
if (gud != null)
|
|
||||||
{
|
|
||||||
if (bool.Parse(gud.Data["Online"]))
|
|
||||||
{
|
|
||||||
m.OnlineStatus = @"Online";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int unixtime = int.Parse(gud.Data["Login"]);
|
|
||||||
// The viewer is very picky about how these strings are formed. Eg. it will crash on malformed dates!
|
|
||||||
m.OnlineStatus = (unixtime == 0) ? @"unknown" : Util.ToDateTime(unixtime).ToString("MM/dd/yyyy");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Is this person an owner of the group?
|
// Is this person an owner of the group?
|
||||||
m.IsOwner = (rolemembershipsList.Find(r => r.RoleID == ownerRoleID) != null) ? true : false;
|
m.IsOwner = (rolemembershipsList.Find(r => r.RoleID == ownerRoleID) != null) ? true : false;
|
||||||
|
|
||||||
|
@ -500,8 +470,8 @@ namespace OpenSim.Groups
|
||||||
|
|
||||||
// check permissions
|
// check permissions
|
||||||
bool limited = HasPower(RequestingAgentID, GroupID, GroupPowers.AssignMemberLimited);
|
bool limited = HasPower(RequestingAgentID, GroupID, GroupPowers.AssignMemberLimited);
|
||||||
bool unlimited = HasPower(RequestingAgentID, GroupID, GroupPowers.AssignMember) || IsOwner(RequestingAgentID, GroupID);
|
bool unlimited = HasPower(RequestingAgentID, GroupID, GroupPowers.AssignMember) | IsOwner(RequestingAgentID, GroupID);
|
||||||
if (!limited && !unlimited)
|
if (!limited || !unlimited)
|
||||||
{
|
{
|
||||||
m_log.DebugFormat("[Groups]: ({0}) Attempt at assigning {1} to role {2} denied because of lack of permission", RequestingAgentID, AgentID, RoleID);
|
m_log.DebugFormat("[Groups]: ({0}) Attempt at assigning {1} to role {2} denied because of lack of permission", RequestingAgentID, AgentID, RoleID);
|
||||||
return false;
|
return false;
|
||||||
|
@ -511,7 +481,7 @@ namespace OpenSim.Groups
|
||||||
if (!unlimited && limited)
|
if (!unlimited && limited)
|
||||||
{
|
{
|
||||||
// check whether person's has this role
|
// check whether person's has this role
|
||||||
RoleMembershipData rolemembership = m_Database.RetrieveRoleMember(GroupID, RoleID, RequestingAgentID);
|
RoleMembershipData rolemembership = m_Database.RetrieveRoleMember(GroupID, RoleID, AgentID);
|
||||||
if (rolemembership == null)
|
if (rolemembership == null)
|
||||||
{
|
{
|
||||||
m_log.DebugFormat("[Groups]: ({0}) Attempt at assigning {1} to role {2} denied because of limited permission", RequestingAgentID, AgentID, RoleID);
|
m_log.DebugFormat("[Groups]: ({0}) Attempt at assigning {1} to role {2} denied because of limited permission", RequestingAgentID, AgentID, RoleID);
|
||||||
|
@ -531,26 +501,13 @@ namespace OpenSim.Groups
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// check permissions
|
// check permissions
|
||||||
bool limited = HasPower(RequestingAgentID, GroupID, GroupPowers.AssignMemberLimited);
|
|
||||||
bool unlimited = HasPower(RequestingAgentID, GroupID, GroupPowers.AssignMember) || IsOwner(RequestingAgentID, GroupID);
|
bool unlimited = HasPower(RequestingAgentID, GroupID, GroupPowers.AssignMember) || IsOwner(RequestingAgentID, GroupID);
|
||||||
if (!limited && !unlimited)
|
if (!unlimited)
|
||||||
{
|
{
|
||||||
m_log.DebugFormat("[Groups]: ({0}) Attempt at removing {1} from role {2} denied because of lack of permission", RequestingAgentID, AgentID, RoleID);
|
m_log.DebugFormat("[Groups]: ({0}) Attempt at removing {1} from role {2} denied because of lack of permission", RequestingAgentID, AgentID, RoleID);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// AssignMemberLimited means that the person can assign another person to the same roles that she has in the group
|
|
||||||
if (!unlimited && limited)
|
|
||||||
{
|
|
||||||
// check whether person's has this role
|
|
||||||
RoleMembershipData rolemembership = m_Database.RetrieveRoleMember(GroupID, RoleID, RequestingAgentID);
|
|
||||||
if (rolemembership == null)
|
|
||||||
{
|
|
||||||
m_log.DebugFormat("[Groups]: ({0}) Attempt at removing {1} from role {2} denied because of limited permission", RequestingAgentID, AgentID, RoleID);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RoleMembershipData rolemember = m_Database.RetrieveRoleMember(GroupID, RoleID, AgentID);
|
RoleMembershipData rolemember = m_Database.RetrieveRoleMember(GroupID, RoleID, AgentID);
|
||||||
|
|
||||||
if (rolemember == null)
|
if (rolemember == null)
|
||||||
|
@ -568,8 +525,8 @@ namespace OpenSim.Groups
|
||||||
{
|
{
|
||||||
newRoleID = r.RoleID;
|
newRoleID = r.RoleID;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MembershipData member = m_Database.RetrieveMember(GroupID, AgentID);
|
MembershipData member = m_Database.RetrieveMember(GroupID, AgentID);
|
||||||
if (member != null)
|
if (member != null)
|
||||||
|
@ -727,7 +684,7 @@ namespace OpenSim.Groups
|
||||||
m_Database.StoreMember(membership);
|
m_Database.StoreMember(membership);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool AddGroupNotice(string RequestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message,
|
public bool AddGroupNotice(string RequestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message,
|
||||||
bool hasAttachment, byte attType, string attName, UUID attItemID, string attOwnerID)
|
bool hasAttachment, byte attType, string attName, UUID attItemID, string attOwnerID)
|
||||||
{
|
{
|
||||||
// Check perms
|
// Check perms
|
||||||
|
@ -840,7 +797,7 @@ namespace OpenSim.Groups
|
||||||
if (RoleID != UUID.Zero)
|
if (RoleID != UUID.Zero)
|
||||||
_AddAgentToGroupRole(RequestingAgentID, AgentID, GroupID, RoleID);
|
_AddAgentToGroupRole(RequestingAgentID, AgentID, GroupID, RoleID);
|
||||||
|
|
||||||
// Make this the active group
|
// Make thit this active group
|
||||||
PrincipalData pdata = new PrincipalData();
|
PrincipalData pdata = new PrincipalData();
|
||||||
pdata.PrincipalID = AgentID;
|
pdata.PrincipalID = AgentID;
|
||||||
pdata.ActiveGroupID = GroupID;
|
pdata.ActiveGroupID = GroupID;
|
||||||
|
@ -858,7 +815,7 @@ namespace OpenSim.Groups
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!add && data == null) // it doesn't exist, can't update
|
if (!add && data == null) // it deosn't exist, can't update
|
||||||
{
|
{
|
||||||
m_log.DebugFormat("[Groups]: Group {0} doesn't exist. Can't update it", groupID);
|
m_log.DebugFormat("[Groups]: Group {0} doesn't exist. Can't update it", groupID);
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
*
|
*
|
||||||
|
@ -38,7 +38,6 @@ namespace OpenSim.Groups
|
||||||
public class GroupsServiceBase : ServiceBase
|
public class GroupsServiceBase : ServiceBase
|
||||||
{
|
{
|
||||||
protected IGroupsData m_Database = null;
|
protected IGroupsData m_Database = null;
|
||||||
protected IGridUserData m_GridUserService = null;
|
|
||||||
|
|
||||||
public GroupsServiceBase(IConfigSource config, string cName)
|
public GroupsServiceBase(IConfigSource config, string cName)
|
||||||
: base(config)
|
: base(config)
|
||||||
|
@ -46,7 +45,6 @@ namespace OpenSim.Groups
|
||||||
string dllName = String.Empty;
|
string dllName = String.Empty;
|
||||||
string connString = String.Empty;
|
string connString = String.Empty;
|
||||||
string realm = "os_groups";
|
string realm = "os_groups";
|
||||||
string usersRealm = "GridUser";
|
|
||||||
string configName = (cName == string.Empty) ? "Groups" : cName;
|
string configName = (cName == string.Empty) ? "Groups" : cName;
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -81,21 +79,6 @@ namespace OpenSim.Groups
|
||||||
m_Database = LoadPlugin<IGroupsData>(dllName, new Object[] { connString, realm });
|
m_Database = LoadPlugin<IGroupsData>(dllName, new Object[] { connString, realm });
|
||||||
if (m_Database == null)
|
if (m_Database == null)
|
||||||
throw new Exception("Could not find a storage interface in the given module " + dllName);
|
throw new Exception("Could not find a storage interface in the given module " + dllName);
|
||||||
|
|
||||||
//
|
|
||||||
// [GridUserService] section overrides [DatabaseService], if it exists
|
|
||||||
//
|
|
||||||
IConfig usersConfig = config.Configs["GridUserService"];
|
|
||||||
if (usersConfig != null)
|
|
||||||
{
|
|
||||||
dllName = usersConfig.GetString("StorageProvider", dllName);
|
|
||||||
connString = usersConfig.GetString("ConnectionString", connString);
|
|
||||||
usersRealm = usersConfig.GetString("Realm", usersRealm);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_GridUserService = LoadPlugin<IGridUserData>(dllName, new Object[] { connString, usersRealm });
|
|
||||||
if (m_GridUserService == null)
|
|
||||||
throw new Exception("Could not find a storage inferface for the given users module " + dllName);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -76,7 +76,7 @@ namespace OpenSim.Groups
|
||||||
|
|
||||||
// Check if it already exists
|
// Check if it already exists
|
||||||
GroupData grec = m_Database.RetrieveGroup(groupID);
|
GroupData grec = m_Database.RetrieveGroup(groupID);
|
||||||
if (grec == null ||
|
if (grec == null ||
|
||||||
(grec != null && grec.Data["Location"] != string.Empty && grec.Data["Location"].ToLower() != serviceLocation.ToLower()))
|
(grec != null && grec.Data["Location"] != string.Empty && grec.Data["Location"].ToLower() != serviceLocation.ToLower()))
|
||||||
{
|
{
|
||||||
// Create the group
|
// Create the group
|
||||||
|
|
|
@ -114,6 +114,7 @@ namespace OpenSim.OfflineIM
|
||||||
scene.ForEachClient(delegate(IClientAPI client)
|
scene.ForEachClient(delegate(IClientAPI client)
|
||||||
{
|
{
|
||||||
client.OnRetrieveInstantMessages -= RetrieveInstantMessages;
|
client.OnRetrieveInstantMessages -= RetrieveInstantMessages;
|
||||||
|
client.OnMuteListRequest -= OnMuteListRequest;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,6 +162,7 @@ namespace OpenSim.OfflineIM
|
||||||
private void OnNewClient(IClientAPI client)
|
private void OnNewClient(IClientAPI client)
|
||||||
{
|
{
|
||||||
client.OnRetrieveInstantMessages += RetrieveInstantMessages;
|
client.OnRetrieveInstantMessages += RetrieveInstantMessages;
|
||||||
|
client.OnMuteListRequest += OnMuteListRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RetrieveInstantMessages(IClientAPI client)
|
private void RetrieveInstantMessages(IClientAPI client)
|
||||||
|
@ -192,6 +194,20 @@ namespace OpenSim.OfflineIM
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Apparently this is needed in order for the viewer to request the IMs.
|
||||||
|
private void OnMuteListRequest(IClientAPI client, uint crc)
|
||||||
|
{
|
||||||
|
m_log.DebugFormat("[OfflineIM.V2] Got mute list request for crc {0}", crc);
|
||||||
|
string filename = "mutes" + client.AgentId.ToString();
|
||||||
|
|
||||||
|
IXfer xfer = client.Scene.RequestModuleInterface<IXfer>();
|
||||||
|
if (xfer != null)
|
||||||
|
{
|
||||||
|
xfer.AddNewFile(filename, new Byte[0]);
|
||||||
|
client.SendMuteListUpdate(filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void UndeliveredMessage(GridInstantMessage im)
|
private void UndeliveredMessage(GridInstantMessage im)
|
||||||
{
|
{
|
||||||
if (im.dialog != (byte)InstantMessageDialog.MessageFromObject &&
|
if (im.dialog != (byte)InstantMessageDialog.MessageFromObject &&
|
||||||
|
|
|
@ -3,7 +3,7 @@ using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using Mono.Addins;
|
using Mono.Addins;
|
||||||
|
|
||||||
// General Information about an assembly is controlled through the following
|
// General Information about an assembly is controlled through the following
|
||||||
// set of attributes. Change these attribute values to modify the information
|
// set of attributes. Change these attribute values to modify the information
|
||||||
// associated with an assembly.
|
// associated with an assembly.
|
||||||
[assembly: AssemblyTitle("OpenSim.Addons.OfflineIM")]
|
[assembly: AssemblyTitle("OpenSim.Addons.OfflineIM")]
|
||||||
|
@ -15,8 +15,8 @@ using Mono.Addins;
|
||||||
[assembly: AssemblyTrademark("")]
|
[assembly: AssemblyTrademark("")]
|
||||||
[assembly: AssemblyCulture("")]
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
// Setting ComVisible to false makes the types in this assembly not visible
|
// Setting ComVisible to false makes the types in this assembly not visible
|
||||||
// to COM components. If you need to access a type in this assembly from
|
// to COM components. If you need to access a type in this assembly from
|
||||||
// COM, set the ComVisible attribute to true on that type.
|
// COM, set the ComVisible attribute to true on that type.
|
||||||
[assembly: ComVisible(false)]
|
[assembly: ComVisible(false)]
|
||||||
|
|
||||||
|
@ -26,11 +26,11 @@ using Mono.Addins;
|
||||||
// Version information for an assembly consists of the following four values:
|
// Version information for an assembly consists of the following four values:
|
||||||
//
|
//
|
||||||
// Major Version
|
// Major Version
|
||||||
// Minor Version
|
// Minor Version
|
||||||
// Build Number
|
// Build Number
|
||||||
// Revision
|
// Revision
|
||||||
//
|
//
|
||||||
[assembly: AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)]
|
[assembly: AssemblyVersion("0.8.1.*")]
|
||||||
|
|
||||||
[assembly: Addin("OpenSim.OfflineIM", OpenSim.VersionInfo.VersionNumber)]
|
[assembly: Addin("OpenSim.OfflineIM", OpenSim.VersionInfo.VersionNumber)]
|
||||||
[assembly: AddinDependency("OpenSim.Region.Framework", OpenSim.VersionInfo.VersionNumber)]
|
[assembly: AddinDependency("OpenSim.Region.Framework", OpenSim.VersionInfo.VersionNumber)]
|
||||||
|
|
|
@ -77,7 +77,7 @@ namespace OpenSim.OfflineIM
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
///
|
///
|
||||||
m_log.DebugFormat("[OfflineIM.V2.RemoteConnector]: Offline IM server at {0} with auth {1}",
|
m_log.DebugFormat("[OfflineIM.V2.RemoteConnector]: Offline IM server at {0} with auth {1}",
|
||||||
m_ServerURI, (m_Auth == null ? "None" : m_Auth.GetType().ToString()));
|
m_ServerURI, (m_Auth == null ? "None" : m_Auth.GetType().ToString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,7 +140,7 @@ namespace OpenSim.OfflineIM
|
||||||
{
|
{
|
||||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
||||||
sendData["UserID"] = userID;
|
sendData["UserID"] = userID;
|
||||||
|
|
||||||
MakeRequest("DELETE", sendData);
|
MakeRequest("DELETE", sendData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -90,7 +90,7 @@ namespace OpenSim.OfflineIM
|
||||||
public bool StoreMessage(GridInstantMessage im, out string reason)
|
public bool StoreMessage(GridInstantMessage im, out string reason)
|
||||||
{
|
{
|
||||||
reason = string.Empty;
|
reason = string.Empty;
|
||||||
|
|
||||||
// Check limits
|
// Check limits
|
||||||
UUID principalID = new UUID(im.toAgentID);
|
UUID principalID = new UUID(im.toAgentID);
|
||||||
long count = m_Database.GetCount("PrincipalID", principalID.ToString());
|
long count = m_Database.GetCount("PrincipalID", principalID.ToString());
|
||||||
|
@ -110,8 +110,9 @@ namespace OpenSim.OfflineIM
|
||||||
{
|
{
|
||||||
m_serializer.Serialize(writer, im);
|
m_serializer.Serialize(writer, im);
|
||||||
writer.Flush();
|
writer.Flush();
|
||||||
imXml = Util.UTF8NoBomEncoding.GetString(mstream.ToArray());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
imXml = Util.UTF8NoBomEncoding.GetString(mstream.ToArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
OfflineIMData data = new OfflineIMData();
|
OfflineIMData data = new OfflineIMData();
|
||||||
|
|
|
@ -32,6 +32,8 @@ using System.Threading;
|
||||||
using log4net;
|
using log4net;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Framework.RegionLoader.Filesystem;
|
||||||
|
using OpenSim.Framework.RegionLoader.Web;
|
||||||
using OpenSim.Region.CoreModules.Agent.AssetTransaction;
|
using OpenSim.Region.CoreModules.Agent.AssetTransaction;
|
||||||
using OpenSim.Region.CoreModules.Avatar.InstantMessage;
|
using OpenSim.Region.CoreModules.Avatar.InstantMessage;
|
||||||
using OpenSim.Region.CoreModules.Scripting.DynamicTexture;
|
using OpenSim.Region.CoreModules.Scripting.DynamicTexture;
|
||||||
|
@ -124,7 +126,7 @@ namespace OpenSim.ApplicationPlugins.LoadRegions
|
||||||
m_log.Debug("[LOAD REGIONS PLUGIN]: Creating Region: " + regionsToLoad[i].RegionName + " (ThreadID: " +
|
m_log.Debug("[LOAD REGIONS PLUGIN]: Creating Region: " + regionsToLoad[i].RegionName + " (ThreadID: " +
|
||||||
Thread.CurrentThread.ManagedThreadId.ToString() +
|
Thread.CurrentThread.ManagedThreadId.ToString() +
|
||||||
")");
|
")");
|
||||||
|
|
||||||
bool changed = m_openSim.PopulateRegionEstateInfo(regionsToLoad[i]);
|
bool changed = m_openSim.PopulateRegionEstateInfo(regionsToLoad[i]);
|
||||||
|
|
||||||
m_openSim.CreateRegion(regionsToLoad[i], true, out scene);
|
m_openSim.CreateRegion(regionsToLoad[i], true, out scene);
|
||||||
|
|
|
@ -61,8 +61,9 @@ using Mono.Addins;
|
||||||
//
|
//
|
||||||
// You can specify all the values or you can default the Build and Revision Numbers
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
// by using the '*' as shown below:
|
// by using the '*' as shown below:
|
||||||
|
// [assembly: AssemblyVersion("0.7.6.*")]
|
||||||
|
|
||||||
[assembly : AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)]
|
[assembly : AssemblyVersion("0.8.1.*")]
|
||||||
|
|
||||||
[assembly: Addin("OpenSim.ApplicationPlugins.LoadRegions", OpenSim.VersionInfo.VersionNumber)]
|
[assembly: Addin("OpenSim.ApplicationPlugins.LoadRegions", OpenSim.VersionInfo.VersionNumber)]
|
||||||
[assembly: AddinDependency("OpenSim", OpenSim.VersionInfo.VersionNumber)]
|
[assembly: AddinDependency("OpenSim", OpenSim.VersionInfo.VersionNumber)]
|
||||||
|
|
|
@ -3,7 +3,7 @@ using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using Mono.Addins;
|
using Mono.Addins;
|
||||||
|
|
||||||
// General Information about an assembly is controlled through the following
|
// General Information about an assembly is controlled through the following
|
||||||
// set of attributes. Change these attribute values to modify the information
|
// set of attributes. Change these attribute values to modify the information
|
||||||
// associated with an assembly.
|
// associated with an assembly.
|
||||||
[assembly: AssemblyTitle("OpenSim.ApplicationPlugins.RegionModulesController")]
|
[assembly: AssemblyTitle("OpenSim.ApplicationPlugins.RegionModulesController")]
|
||||||
|
@ -15,8 +15,8 @@ using Mono.Addins;
|
||||||
[assembly: AssemblyTrademark("")]
|
[assembly: AssemblyTrademark("")]
|
||||||
[assembly: AssemblyCulture("")]
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
// Setting ComVisible to false makes the types in this assembly not visible
|
// Setting ComVisible to false makes the types in this assembly not visible
|
||||||
// to COM components. If you need to access a type in this assembly from
|
// to COM components. If you need to access a type in this assembly from
|
||||||
// COM, set the ComVisible attribute to true on that type.
|
// COM, set the ComVisible attribute to true on that type.
|
||||||
[assembly: ComVisible(false)]
|
[assembly: ComVisible(false)]
|
||||||
|
|
||||||
|
@ -26,11 +26,11 @@ using Mono.Addins;
|
||||||
// Version information for an assembly consists of the following four values:
|
// Version information for an assembly consists of the following four values:
|
||||||
//
|
//
|
||||||
// Major Version
|
// Major Version
|
||||||
// Minor Version
|
// Minor Version
|
||||||
// Build Number
|
// Build Number
|
||||||
// Revision
|
// Revision
|
||||||
//
|
//
|
||||||
[assembly: AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)]
|
[assembly: AssemblyVersion("0.8.1.*")]
|
||||||
|
|
||||||
[assembly: Addin("OpenSim.ApplicationPlugins.RegionModulesController", OpenSim.VersionInfo.VersionNumber)]
|
[assembly: Addin("OpenSim.ApplicationPlugins.RegionModulesController", OpenSim.VersionInfo.VersionNumber)]
|
||||||
[assembly: AddinDependency("OpenSim", OpenSim.VersionInfo.VersionNumber)]
|
[assembly: AddinDependency("OpenSim", OpenSim.VersionInfo.VersionNumber)]
|
||||||
|
|
|
@ -75,7 +75,7 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
|
||||||
}
|
}
|
||||||
|
|
||||||
#region IApplicationPlugin implementation
|
#region IApplicationPlugin implementation
|
||||||
|
|
||||||
public void Initialise (OpenSimBase openSim)
|
public void Initialise (OpenSimBase openSim)
|
||||||
{
|
{
|
||||||
m_openSim = openSim;
|
m_openSim = openSim;
|
||||||
|
@ -111,7 +111,7 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
|
||||||
{
|
{
|
||||||
m_log.InfoFormat(
|
m_log.InfoFormat(
|
||||||
"[REGIONMODULES]: From plugin {0}, (version {1}), loaded {2} modules, {3} shared, {4} non-shared {5} unknown",
|
"[REGIONMODULES]: From plugin {0}, (version {1}), loaded {2} modules, {3} shared, {4} non-shared {5} unknown",
|
||||||
loadedModuleData.Key.Id,
|
loadedModuleData.Key.Id,
|
||||||
loadedModuleData.Key.Version,
|
loadedModuleData.Key.Version,
|
||||||
loadedModuleData.Value[0] + loadedModuleData.Value[1] + loadedModuleData.Value[2],
|
loadedModuleData.Value[0] + loadedModuleData.Value[1] + loadedModuleData.Value[2],
|
||||||
loadedModuleData.Value[0], loadedModuleData.Value[1], loadedModuleData.Value[2]);
|
loadedModuleData.Value[0], loadedModuleData.Value[1], loadedModuleData.Value[2]);
|
||||||
|
@ -131,9 +131,6 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
|
||||||
// Read the config again
|
// Read the config again
|
||||||
string moduleString =
|
string moduleString =
|
||||||
modulesConfig.GetString("Setup_" + node.Id, String.Empty);
|
modulesConfig.GetString("Setup_" + node.Id, String.Empty);
|
||||||
// Test to see if we want this module
|
|
||||||
if (moduleString == "disabled")
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Get the port number, if there is one
|
// Get the port number, if there is one
|
||||||
if (moduleString != String.Empty)
|
if (moduleString != String.Empty)
|
||||||
|
@ -261,7 +258,7 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Region Module interfacesController implementation
|
#region Region Module interfacesController implementation
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Check that the given module is no disabled in the [Modules] section of the config files.
|
/// Check that the given module is no disabled in the [Modules] section of the config files.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -293,10 +290,10 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
|
||||||
if (className != String.Empty &&
|
if (className != String.Empty &&
|
||||||
node.Type.ToString() != className)
|
node.Type.ToString() != className)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The root of all evil.
|
// The root of all evil.
|
||||||
// This is where we handle adding the modules to scenes when they
|
// This is where we handle adding the modules to scenes when they
|
||||||
|
@ -368,10 +365,6 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
|
||||||
string moduleString =
|
string moduleString =
|
||||||
modulesConfig.GetString("Setup_" + node.Id, String.Empty);
|
modulesConfig.GetString("Setup_" + node.Id, String.Empty);
|
||||||
|
|
||||||
// We may not want to load this at all
|
|
||||||
if (moduleString == "disabled")
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Get the port number, if there is one
|
// Get the port number, if there is one
|
||||||
if (moduleString != String.Empty)
|
if (moduleString != String.Empty)
|
||||||
{
|
{
|
||||||
|
@ -509,8 +502,6 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
|
||||||
{
|
{
|
||||||
module.RegionLoaded(scene);
|
module.RegionLoaded(scene);
|
||||||
}
|
}
|
||||||
|
|
||||||
scene.AllModulesLoaded();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveRegionFromModules (Scene scene)
|
public void RemoveRegionFromModules (Scene scene)
|
||||||
|
|
|
@ -3,7 +3,7 @@ using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using Mono.Addins;
|
using Mono.Addins;
|
||||||
|
|
||||||
// General Information about an assembly is controlled through the following
|
// General Information about an assembly is controlled through the following
|
||||||
// set of attributes. Change these attribute values to modify the information
|
// set of attributes. Change these attribute values to modify the information
|
||||||
// associated with an assembly.
|
// associated with an assembly.
|
||||||
[assembly: AssemblyTitle("OpenSim.ApplicationPlugins.RemoteController")]
|
[assembly: AssemblyTitle("OpenSim.ApplicationPlugins.RemoteController")]
|
||||||
|
@ -15,8 +15,8 @@ using Mono.Addins;
|
||||||
[assembly: AssemblyTrademark("")]
|
[assembly: AssemblyTrademark("")]
|
||||||
[assembly: AssemblyCulture("")]
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
// Setting ComVisible to false makes the types in this assembly not visible
|
// Setting ComVisible to false makes the types in this assembly not visible
|
||||||
// to COM components. If you need to access a type in this assembly from
|
// to COM components. If you need to access a type in this assembly from
|
||||||
// COM, set the ComVisible attribute to true on that type.
|
// COM, set the ComVisible attribute to true on that type.
|
||||||
[assembly: ComVisible(false)]
|
[assembly: ComVisible(false)]
|
||||||
|
|
||||||
|
@ -26,11 +26,11 @@ using Mono.Addins;
|
||||||
// Version information for an assembly consists of the following four values:
|
// Version information for an assembly consists of the following four values:
|
||||||
//
|
//
|
||||||
// Major Version
|
// Major Version
|
||||||
// Minor Version
|
// Minor Version
|
||||||
// Build Number
|
// Build Number
|
||||||
// Revision
|
// Revision
|
||||||
//
|
//
|
||||||
[assembly: AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)]
|
[assembly: AssemblyVersion("0.8.1.*")]
|
||||||
|
|
||||||
[assembly: Addin("OpenSim.ApplicationPlugins.RemoteController", OpenSim.VersionInfo.VersionNumber)]
|
[assembly: Addin("OpenSim.ApplicationPlugins.RemoteController", OpenSim.VersionInfo.VersionNumber)]
|
||||||
[assembly: AddinDependency("OpenSim", OpenSim.VersionInfo.VersionNumber)]
|
[assembly: AddinDependency("OpenSim", OpenSim.VersionInfo.VersionNumber)]
|
||||||
|
|
|
@ -42,6 +42,7 @@ using OpenMetaverse;
|
||||||
using Mono.Addins;
|
using Mono.Addins;
|
||||||
using OpenSim;
|
using OpenSim;
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Framework.Communications;
|
||||||
using OpenSim.Framework.Console;
|
using OpenSim.Framework.Console;
|
||||||
using OpenSim.Framework.Servers;
|
using OpenSim.Framework.Servers;
|
||||||
using OpenSim.Framework.Servers.HttpServer;
|
using OpenSim.Framework.Servers.HttpServer;
|
||||||
|
@ -74,7 +75,6 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||||
|
|
||||||
private string m_name = "RemoteAdminPlugin";
|
private string m_name = "RemoteAdminPlugin";
|
||||||
private string m_version = "0.0";
|
private string m_version = "0.0";
|
||||||
private string m_openSimVersion;
|
|
||||||
|
|
||||||
public string Version
|
public string Version
|
||||||
{
|
{
|
||||||
|
@ -94,8 +94,6 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||||
|
|
||||||
public void Initialise(OpenSimBase openSim)
|
public void Initialise(OpenSimBase openSim)
|
||||||
{
|
{
|
||||||
m_openSimVersion = openSim.GetVersionText();
|
|
||||||
|
|
||||||
m_configSource = openSim.ConfigSource.Source;
|
m_configSource = openSim.ConfigSource.Source;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -138,13 +136,10 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||||
availableMethods["admin_region_query"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcRegionQueryMethod);
|
availableMethods["admin_region_query"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcRegionQueryMethod);
|
||||||
availableMethods["admin_shutdown"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcShutdownMethod);
|
availableMethods["admin_shutdown"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcShutdownMethod);
|
||||||
availableMethods["admin_broadcast"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcAlertMethod);
|
availableMethods["admin_broadcast"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcAlertMethod);
|
||||||
availableMethods["admin_dialog"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcDialogMethod);
|
|
||||||
availableMethods["admin_restart"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcRestartMethod);
|
availableMethods["admin_restart"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcRestartMethod);
|
||||||
availableMethods["admin_load_heightmap"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcLoadHeightmapMethod);
|
availableMethods["admin_load_heightmap"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcLoadHeightmapMethod);
|
||||||
availableMethods["admin_save_heightmap"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcSaveHeightmapMethod);
|
availableMethods["admin_save_heightmap"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcSaveHeightmapMethod);
|
||||||
|
|
||||||
availableMethods["admin_reset_land"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcResetLand);
|
|
||||||
|
|
||||||
// Agent management
|
// Agent management
|
||||||
availableMethods["admin_get_agents"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcGetAgentsMethod);
|
availableMethods["admin_get_agents"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcGetAgentsMethod);
|
||||||
availableMethods["admin_teleport_agent"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcTeleportAgentMethod);
|
availableMethods["admin_teleport_agent"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcTeleportAgentMethod);
|
||||||
|
@ -169,11 +164,8 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||||
availableMethods["admin_acl_list"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcAccessListList);
|
availableMethods["admin_acl_list"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcAccessListList);
|
||||||
availableMethods["admin_estate_reload"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcEstateReload);
|
availableMethods["admin_estate_reload"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcEstateReload);
|
||||||
|
|
||||||
// Misc
|
// Land management
|
||||||
availableMethods["admin_refresh_search"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcRefreshSearch);
|
availableMethods["admin_reset_land"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcResetLand);
|
||||||
availableMethods["admin_refresh_map"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcRefreshMap);
|
|
||||||
availableMethods["admin_get_opensim_version"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcGetOpenSimVersion);
|
|
||||||
availableMethods["admin_get_agent_count"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcGetAgentCount);
|
|
||||||
|
|
||||||
// Either enable full remote functionality or just selected features
|
// Either enable full remote functionality or just selected features
|
||||||
string enabledMethods = m_config.GetString("enabled_methods", "all");
|
string enabledMethods = m_config.GetString("enabled_methods", "all");
|
||||||
|
@ -274,148 +266,32 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
m_log.Info("[RADMIN]: Request to restart Region.");
|
||||||
|
|
||||||
|
CheckRegionParams(requestData, responseData);
|
||||||
|
|
||||||
Scene rebootedScene = null;
|
Scene rebootedScene = null;
|
||||||
bool restartAll = false;
|
GetSceneFromRegionParams(requestData, responseData, out rebootedScene);
|
||||||
|
|
||||||
IConfig startupConfig = m_configSource.Configs["Startup"];
|
|
||||||
if (startupConfig != null)
|
|
||||||
{
|
|
||||||
if (startupConfig.GetBoolean("InworldRestartShutsDown", false))
|
|
||||||
{
|
|
||||||
rebootedScene = m_application.SceneManager.CurrentOrFirstScene;
|
|
||||||
restartAll = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rebootedScene == null)
|
|
||||||
{
|
|
||||||
CheckRegionParams(requestData, responseData);
|
|
||||||
|
|
||||||
GetSceneFromRegionParams(requestData, responseData, out rebootedScene);
|
|
||||||
}
|
|
||||||
|
|
||||||
IRestartModule restartModule = rebootedScene.RequestModuleInterface<IRestartModule>();
|
|
||||||
|
|
||||||
responseData["success"] = false;
|
responseData["success"] = false;
|
||||||
responseData["accepted"] = true;
|
responseData["accepted"] = true;
|
||||||
responseData["rebooting"] = true;
|
responseData["rebooting"] = true;
|
||||||
|
|
||||||
string message;
|
IRestartModule restartModule = rebootedScene.RequestModuleInterface<IRestartModule>();
|
||||||
List<int> times = new List<int>();
|
if (restartModule != null)
|
||||||
|
|
||||||
if (requestData.ContainsKey("alerts"))
|
|
||||||
{
|
{
|
||||||
string[] alertTimes = requestData["alerts"].ToString().Split( new char[] {','});
|
List<int> times = new List<int> { 30, 15 };
|
||||||
if (alertTimes.Length == 1 && Convert.ToInt32(alertTimes[0]) == -1)
|
|
||||||
{
|
|
||||||
m_log.Info("[RADMIN]: Request to cancel restart.");
|
|
||||||
|
|
||||||
if (restartModule != null)
|
restartModule.ScheduleRestart(UUID.Zero, "Region will restart in {0}", times.ToArray(), true);
|
||||||
{
|
responseData["success"] = true;
|
||||||
message = "Restart has been cancelled";
|
|
||||||
|
|
||||||
if (requestData.ContainsKey("message"))
|
|
||||||
message = requestData["message"].ToString();
|
|
||||||
|
|
||||||
restartModule.AbortRestart(message);
|
|
||||||
|
|
||||||
responseData["success"] = true;
|
|
||||||
responseData["rebooting"] = false;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
foreach (string a in alertTimes)
|
|
||||||
times.Add(Convert.ToInt32(a));
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
int timeout = 30;
|
|
||||||
if (requestData.ContainsKey("milliseconds"))
|
|
||||||
timeout = Int32.Parse(requestData["milliseconds"].ToString()) / 1000;
|
|
||||||
while (timeout > 0)
|
|
||||||
{
|
|
||||||
times.Add(timeout);
|
|
||||||
if (timeout > 300)
|
|
||||||
timeout -= 120;
|
|
||||||
else if (timeout > 30)
|
|
||||||
timeout -= 30;
|
|
||||||
else
|
|
||||||
timeout -= 15;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_log.Info("[RADMIN]: Request to restart Region.");
|
|
||||||
|
|
||||||
message = "Region is restarting in {0}. Please save what you are doing and log out.";
|
|
||||||
|
|
||||||
if (requestData.ContainsKey("message"))
|
|
||||||
message = requestData["message"].ToString();
|
|
||||||
|
|
||||||
bool notice = true;
|
|
||||||
if (requestData.ContainsKey("noticetype")
|
|
||||||
&& ((string)requestData["noticetype"] == "dialog"))
|
|
||||||
{
|
|
||||||
notice = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (startupConfig.GetBoolean("SkipDelayOnEmptyRegion", false))
|
|
||||||
{
|
|
||||||
m_log.Info("[RADMIN]: Counting affected avatars");
|
|
||||||
int agents = 0;
|
|
||||||
|
|
||||||
if (restartAll)
|
|
||||||
{
|
|
||||||
foreach (Scene s in m_application.SceneManager.Scenes)
|
|
||||||
{
|
|
||||||
foreach (ScenePresence sp in s.GetScenePresences())
|
|
||||||
{
|
|
||||||
if (!sp.IsChildAgent && !sp.IsNPC)
|
|
||||||
agents++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
foreach (ScenePresence sp in rebootedScene.GetScenePresences())
|
|
||||||
{
|
|
||||||
if (!sp.IsChildAgent && !sp.IsNPC)
|
|
||||||
agents++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_log.InfoFormat("[RADMIN]: Avatars in region: {0}", agents);
|
|
||||||
|
|
||||||
if (agents == 0)
|
|
||||||
{
|
|
||||||
m_log.Info("[RADMIN]: No avatars detected, shutting down without delay");
|
|
||||||
|
|
||||||
times.Clear();
|
|
||||||
times.Add(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Scene> restartList;
|
|
||||||
|
|
||||||
if (restartAll)
|
|
||||||
restartList = m_application.SceneManager.Scenes;
|
|
||||||
else
|
|
||||||
restartList = new List<Scene>() { rebootedScene };
|
|
||||||
|
|
||||||
foreach (Scene s in m_application.SceneManager.Scenes)
|
|
||||||
{
|
|
||||||
restartModule = s.RequestModuleInterface<IRestartModule>();
|
|
||||||
if (restartModule != null)
|
|
||||||
restartModule.ScheduleRestart(UUID.Zero, message, times.ToArray(), notice);
|
|
||||||
}
|
|
||||||
responseData["success"] = true;
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
m_log.ErrorFormat("[RADMIN]: Restart region: failed: {0} {1}", e.Message, e.StackTrace);
|
// m_log.ErrorFormat("[RADMIN]: Restart region: failed: {0} {1}", e.Message, e.StackTrace);
|
||||||
responseData["rebooting"] = false;
|
responseData["rebooting"] = false;
|
||||||
|
|
||||||
throw;
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_log.Info("[RADMIN]: Restart Region request complete");
|
m_log.Info("[RADMIN]: Restart Region request complete");
|
||||||
|
@ -445,32 +321,6 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||||
m_log.Info("[RADMIN]: Alert request complete");
|
m_log.Info("[RADMIN]: Alert request complete");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void XmlRpcDialogMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
|
|
||||||
{
|
|
||||||
Hashtable responseData = (Hashtable)response.Value;
|
|
||||||
|
|
||||||
m_log.Info("[RADMIN]: Dialog request started");
|
|
||||||
|
|
||||||
Hashtable requestData = (Hashtable)request.Params[0];
|
|
||||||
|
|
||||||
string message = (string)requestData["message"];
|
|
||||||
string fromuuid = (string)requestData["from"];
|
|
||||||
m_log.InfoFormat("[RADMIN]: Broadcasting: {0}", message);
|
|
||||||
|
|
||||||
responseData["accepted"] = true;
|
|
||||||
responseData["success"] = true;
|
|
||||||
|
|
||||||
m_application.SceneManager.ForEachScene(
|
|
||||||
delegate(Scene scene)
|
|
||||||
{
|
|
||||||
IDialogModule dialogModule = scene.RequestModuleInterface<IDialogModule>();
|
|
||||||
if (dialogModule != null)
|
|
||||||
dialogModule.SendNotificationToUsersInRegion(UUID.Zero, fromuuid, message);
|
|
||||||
});
|
|
||||||
|
|
||||||
m_log.Info("[RADMIN]: Dialog request complete");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void XmlRpcLoadHeightmapMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
|
private void XmlRpcLoadHeightmapMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
|
||||||
{
|
{
|
||||||
m_log.Info("[RADMIN]: Load height maps request started");
|
m_log.Info("[RADMIN]: Load height maps request started");
|
||||||
|
@ -574,32 +424,13 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||||
message = "Region is going down now.";
|
message = "Region is going down now.";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (requestData.ContainsKey("noticetype")
|
m_application.SceneManager.ForEachScene(
|
||||||
&& ((string) requestData["noticetype"] == "dialog"))
|
|
||||||
{
|
|
||||||
m_application.SceneManager.ForEachScene(
|
|
||||||
|
|
||||||
delegate(Scene scene)
|
delegate(Scene scene)
|
||||||
{
|
|
||||||
IDialogModule dialogModule = scene.RequestModuleInterface<IDialogModule>();
|
|
||||||
if (dialogModule != null)
|
|
||||||
dialogModule.SendNotificationToUsersInRegion(UUID.Zero, "System", message);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!requestData.ContainsKey("noticetype")
|
|
||||||
|| ((string)requestData["noticetype"] != "none"))
|
|
||||||
{
|
|
||||||
m_application.SceneManager.ForEachScene(
|
|
||||||
delegate(Scene scene)
|
|
||||||
{
|
{
|
||||||
IDialogModule dialogModule = scene.RequestModuleInterface<IDialogModule>();
|
IDialogModule dialogModule = scene.RequestModuleInterface<IDialogModule>();
|
||||||
if (dialogModule != null)
|
if (dialogModule != null)
|
||||||
dialogModule.SendGeneralAlert(message);
|
dialogModule.SendGeneralAlert(message);
|
||||||
});
|
});
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Perform shutdown
|
// Perform shutdown
|
||||||
System.Timers.Timer shutdownTimer = new System.Timers.Timer(timeout); // Wait before firing
|
System.Timers.Timer shutdownTimer = new System.Timers.Timer(timeout); // Wait before firing
|
||||||
|
@ -611,7 +442,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||||
}
|
}
|
||||||
|
|
||||||
responseData["success"] = true;
|
responseData["success"] = true;
|
||||||
|
|
||||||
m_log.Info("[RADMIN]: Shutdown Administrator Request complete");
|
m_log.Info("[RADMIN]: Shutdown Administrator Request complete");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -783,9 +614,9 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||||
{
|
{
|
||||||
// No INI setting recorded.
|
// No INI setting recorded.
|
||||||
}
|
}
|
||||||
|
|
||||||
string regionIniPath;
|
string regionIniPath;
|
||||||
|
|
||||||
if (requestData.Contains("region_file"))
|
if (requestData.Contains("region_file"))
|
||||||
{
|
{
|
||||||
// Make sure that the file to be created is in a subdirectory of the region storage directory.
|
// Make sure that the file to be created is in a subdirectory of the region storage directory.
|
||||||
|
@ -809,7 +640,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||||
region.RegionName.Replace(" ", "_").Replace(":", "_").
|
region.RegionName.Replace(" ", "_").Replace(":", "_").
|
||||||
Replace("/", "_")));
|
Replace("/", "_")));
|
||||||
}
|
}
|
||||||
|
|
||||||
m_log.DebugFormat("[RADMIN] CreateRegion: persisting region {0} to {1}",
|
m_log.DebugFormat("[RADMIN] CreateRegion: persisting region {0} to {1}",
|
||||||
region.RegionID, regionIniPath);
|
region.RegionID, regionIniPath);
|
||||||
region.SaveRegionToFile("dynamic region", regionIniPath);
|
region.SaveRegionToFile("dynamic region", regionIniPath);
|
||||||
|
@ -818,9 +649,9 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||||
{
|
{
|
||||||
region.Persistent = false;
|
region.Persistent = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the estate
|
// Set the estate
|
||||||
|
|
||||||
// Check for an existing estate
|
// Check for an existing estate
|
||||||
List<int> estateIDs = m_application.EstateDataService.GetEstates((string) requestData["estate_name"]);
|
List<int> estateIDs = m_application.EstateDataService.GetEstates((string) requestData["estate_name"]);
|
||||||
if (estateIDs.Count < 1)
|
if (estateIDs.Count < 1)
|
||||||
|
@ -831,12 +662,12 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||||
// ok, client wants us to use an explicit UUID
|
// ok, client wants us to use an explicit UUID
|
||||||
// regardless of what the avatar name provided
|
// regardless of what the avatar name provided
|
||||||
userID = new UUID((string) requestData["estate_owner_uuid"]);
|
userID = new UUID((string) requestData["estate_owner_uuid"]);
|
||||||
|
|
||||||
// Check that the specified user exists
|
// Check that the specified user exists
|
||||||
Scene currentOrFirst = m_application.SceneManager.CurrentOrFirstScene;
|
Scene currentOrFirst = m_application.SceneManager.CurrentOrFirstScene;
|
||||||
IUserAccountService accountService = currentOrFirst.UserAccountService;
|
IUserAccountService accountService = currentOrFirst.UserAccountService;
|
||||||
UserAccount user = accountService.GetUserAccount(currentOrFirst.RegionInfo.ScopeID, userID);
|
UserAccount user = accountService.GetUserAccount(currentOrFirst.RegionInfo.ScopeID, userID);
|
||||||
|
|
||||||
if (user == null)
|
if (user == null)
|
||||||
throw new Exception("Specified user was not found.");
|
throw new Exception("Specified user was not found.");
|
||||||
}
|
}
|
||||||
|
@ -845,23 +676,23 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||||
// We need to look up the UUID for the avatar with the provided name.
|
// We need to look up the UUID for the avatar with the provided name.
|
||||||
string ownerFirst = (string) requestData["estate_owner_first"];
|
string ownerFirst = (string) requestData["estate_owner_first"];
|
||||||
string ownerLast = (string) requestData["estate_owner_last"];
|
string ownerLast = (string) requestData["estate_owner_last"];
|
||||||
|
|
||||||
Scene currentOrFirst = m_application.SceneManager.CurrentOrFirstScene;
|
Scene currentOrFirst = m_application.SceneManager.CurrentOrFirstScene;
|
||||||
IUserAccountService accountService = currentOrFirst.UserAccountService;
|
IUserAccountService accountService = currentOrFirst.UserAccountService;
|
||||||
UserAccount user = accountService.GetUserAccount(currentOrFirst.RegionInfo.ScopeID,
|
UserAccount user = accountService.GetUserAccount(currentOrFirst.RegionInfo.ScopeID,
|
||||||
ownerFirst, ownerLast);
|
ownerFirst, ownerLast);
|
||||||
|
|
||||||
// Check that the specified user exists
|
// Check that the specified user exists
|
||||||
if (user == null)
|
if (user == null)
|
||||||
throw new Exception("Specified user was not found.");
|
throw new Exception("Specified user was not found.");
|
||||||
|
|
||||||
userID = user.PrincipalID;
|
userID = user.PrincipalID;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw new Exception("Estate owner details not provided.");
|
throw new Exception("Estate owner details not provided.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new estate with the name provided
|
// Create a new estate with the name provided
|
||||||
region.EstateSettings = m_application.EstateDataService.CreateNewEstate();
|
region.EstateSettings = m_application.EstateDataService.CreateNewEstate();
|
||||||
|
|
||||||
|
@ -888,7 +719,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||||
throw new Exception("Failed to join estate.");
|
throw new Exception("Failed to join estate.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the region and perform any initial initialization
|
// Create the region and perform any initial initialization
|
||||||
|
|
||||||
IScene newScene;
|
IScene newScene;
|
||||||
|
@ -1195,7 +1026,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||||
|
|
||||||
// Set home position
|
// Set home position
|
||||||
|
|
||||||
GridRegion home = scene.GridService.GetRegionByPosition(scopeID,
|
GridRegion home = scene.GridService.GetRegionByPosition(scopeID,
|
||||||
(int)Util.RegionToWorldLoc(regionXLocation), (int)Util.RegionToWorldLoc(regionYLocation));
|
(int)Util.RegionToWorldLoc(regionXLocation), (int)Util.RegionToWorldLoc(regionYLocation));
|
||||||
if (null == home)
|
if (null == home)
|
||||||
{
|
{
|
||||||
|
@ -1425,7 +1256,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||||
|
|
||||||
if ((null != regionXLocation) && (null != regionYLocation))
|
if ((null != regionXLocation) && (null != regionYLocation))
|
||||||
{
|
{
|
||||||
GridRegion home = scene.GridService.GetRegionByPosition(scopeID,
|
GridRegion home = scene.GridService.GetRegionByPosition(scopeID,
|
||||||
(int)Util.RegionToWorldLoc((uint)regionXLocation), (int)Util.RegionToWorldLoc((uint)regionYLocation));
|
(int)Util.RegionToWorldLoc((uint)regionXLocation), (int)Util.RegionToWorldLoc((uint)regionYLocation));
|
||||||
if (null == home) {
|
if (null == home) {
|
||||||
m_log.WarnFormat("[RADMIN]: Unable to set home region for updated user account {0} {1}", firstName, lastName);
|
m_log.WarnFormat("[RADMIN]: Unable to set home region for updated user account {0} {1}", firstName, lastName);
|
||||||
|
@ -1452,7 +1283,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||||
|
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_log.Info("[RADMIN]: UpdateUserAccount: request complete");
|
m_log.Info("[RADMIN]: UpdateUserAccount: request complete");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1644,7 +1475,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||||
GetSceneFromRegionParams(requestData, responseData, out scene);
|
GetSceneFromRegionParams(requestData, responseData, out scene);
|
||||||
|
|
||||||
string filename = (string) requestData["filename"];
|
string filename = (string) requestData["filename"];
|
||||||
|
|
||||||
bool mergeOar = false;
|
bool mergeOar = false;
|
||||||
bool skipAssets = false;
|
bool skipAssets = false;
|
||||||
|
|
||||||
|
@ -1658,7 +1489,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||||
}
|
}
|
||||||
|
|
||||||
IRegionArchiverModule archiver = scene.RequestModuleInterface<IRegionArchiverModule>();
|
IRegionArchiverModule archiver = scene.RequestModuleInterface<IRegionArchiverModule>();
|
||||||
Dictionary<string, object> archiveOptions = new Dictionary<string, object>();
|
Dictionary<string, object> archiveOptions = new Dictionary<string,object>();
|
||||||
if (mergeOar) archiveOptions.Add("merge", null);
|
if (mergeOar) archiveOptions.Add("merge", null);
|
||||||
if (skipAssets) archiveOptions.Add("skipAssets", null);
|
if (skipAssets) archiveOptions.Add("skipAssets", null);
|
||||||
if (archiver != null)
|
if (archiver != null)
|
||||||
|
@ -1771,7 +1602,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||||
scene.EventManager.OnOarFileSaved += RemoteAdminOarSaveCompleted;
|
scene.EventManager.OnOarFileSaved += RemoteAdminOarSaveCompleted;
|
||||||
|
|
||||||
m_log.InfoFormat(
|
m_log.InfoFormat(
|
||||||
"[RADMIN]: Submitting save OAR request for {0} to file {1}, request ID {2}",
|
"[RADMIN]: Submitting save OAR request for {0} to file {1}, request ID {2}",
|
||||||
scene.Name, filename, requestId);
|
scene.Name, filename, requestId);
|
||||||
|
|
||||||
archiver.ArchiveRegion(filename, requestId, options);
|
archiver.ArchiveRegion(filename, requestId, options);
|
||||||
|
@ -1918,31 +1749,21 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||||
|
|
||||||
private void XmlRpcRegionQueryMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
|
private void XmlRpcRegionQueryMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
|
||||||
{
|
{
|
||||||
|
m_log.Info("[RADMIN]: Received Query XML Administrator Request");
|
||||||
|
|
||||||
Hashtable responseData = (Hashtable)response.Value;
|
Hashtable responseData = (Hashtable)response.Value;
|
||||||
Hashtable requestData = (Hashtable)request.Params[0];
|
Hashtable requestData = (Hashtable)request.Params[0];
|
||||||
|
|
||||||
int flags = 0;
|
|
||||||
string text = String.Empty;
|
|
||||||
int health = 0;
|
|
||||||
responseData["success"] = true;
|
|
||||||
|
|
||||||
CheckRegionParams(requestData, responseData);
|
CheckRegionParams(requestData, responseData);
|
||||||
|
|
||||||
Scene scene = null;
|
Scene scene = null;
|
||||||
try
|
GetSceneFromRegionParams(requestData, responseData, out scene);
|
||||||
{
|
|
||||||
GetSceneFromRegionParams(requestData, responseData, out scene);
|
int health = scene.GetHealth();
|
||||||
health = scene.GetHealth(out flags, out text);
|
responseData["health"] = health;
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
responseData["error"] = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
responseData["success"] = true;
|
responseData["success"] = true;
|
||||||
responseData["health"] = health;
|
m_log.Info("[RADMIN]: Query XML Administrator Request complete");
|
||||||
responseData["flags"] = flags;
|
|
||||||
responseData["message"] = text;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void XmlRpcConsoleCommandMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
|
private void XmlRpcConsoleCommandMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
|
||||||
|
@ -2118,8 +1939,8 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||||
Hashtable responseData = (Hashtable)response.Value;
|
Hashtable responseData = (Hashtable)response.Value;
|
||||||
// Hashtable requestData = (Hashtable)request.Params[0];
|
// Hashtable requestData = (Hashtable)request.Params[0];
|
||||||
|
|
||||||
m_application.SceneManager.ForEachScene(s =>
|
m_application.SceneManager.ForEachScene(s =>
|
||||||
s.RegionInfo.EstateSettings = m_application.EstateDataService.LoadEstateSettings(s.RegionInfo.RegionID, false)
|
s.RegionInfo.EstateSettings = m_application.EstateDataService.LoadEstateSettings(s.RegionInfo.RegionID, false)
|
||||||
);
|
);
|
||||||
|
|
||||||
responseData["success"] = true;
|
responseData["success"] = true;
|
||||||
|
@ -2251,6 +2072,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||||
{
|
{
|
||||||
Hashtable requestData = (Hashtable)request.Params[0];
|
Hashtable requestData = (Hashtable)request.Params[0];
|
||||||
Hashtable responseData = (Hashtable)response.Value;
|
Hashtable responseData = (Hashtable)response.Value;
|
||||||
|
|
||||||
string musicURL = string.Empty;
|
string musicURL = string.Empty;
|
||||||
UUID groupID = UUID.Zero;
|
UUID groupID = UUID.Zero;
|
||||||
uint flags = 0;
|
uint flags = 0;
|
||||||
|
@ -2260,129 +2082,41 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||||
set_group = UUID.TryParse(requestData["group"].ToString(), out groupID);
|
set_group = UUID.TryParse(requestData["group"].ToString(), out groupID);
|
||||||
if (requestData.Contains("music") && requestData["music"] != null)
|
if (requestData.Contains("music") && requestData["music"] != null)
|
||||||
{
|
{
|
||||||
|
|
||||||
musicURL = requestData["music"].ToString();
|
musicURL = requestData["music"].ToString();
|
||||||
set_music = true;
|
set_music = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (requestData.Contains("flags") && requestData["flags"] != null)
|
if (requestData.Contains("flags") && requestData["flags"] != null)
|
||||||
set_flags = UInt32.TryParse(requestData["flags"].ToString(), out flags);
|
set_flags = UInt32.TryParse(requestData["flags"].ToString(), out flags);
|
||||||
|
|
||||||
m_log.InfoFormat("[RADMIN]: Received Reset Land Request group={0} musicURL={1} flags={2}",
|
m_log.InfoFormat("[RADMIN]: Received Reset Land Request group={0} musicURL={1} flags={2}",
|
||||||
(set_group ? groupID.ToString() : "unchanged"),
|
(set_group ? groupID.ToString() : "unchanged"),
|
||||||
(set_music ? musicURL : "unchanged"),
|
(set_music ? musicURL : "unchanged"),
|
||||||
(set_flags ? flags.ToString() : "unchanged"));
|
(set_flags ? flags.ToString() : "unchanged"));
|
||||||
|
|
||||||
m_application.SceneManager.ForEachScene(delegate (Scene s)
|
m_application.SceneManager.ForEachScene(delegate(Scene s)
|
||||||
{
|
{
|
||||||
List<ILandObject> parcels = s.LandChannel.AllParcels();
|
List<ILandObject> parcels = s.LandChannel.AllParcels();
|
||||||
foreach (ILandObject p in parcels)
|
foreach (ILandObject p in parcels)
|
||||||
{
|
{
|
||||||
if (set_music)
|
if (set_music)
|
||||||
p.LandData.MusicURL = musicURL;
|
p.LandData.MusicURL = musicURL;
|
||||||
|
|
||||||
if (set_group)
|
if (set_group)
|
||||||
p.LandData.GroupID = groupID;
|
p.LandData.GroupID = groupID;
|
||||||
|
|
||||||
if (set_flags)
|
if (set_flags)
|
||||||
p.LandData.Flags = flags;
|
p.LandData.Flags = flags;
|
||||||
|
|
||||||
s.LandChannel.UpdateLandObject(p.LandData.LocalID, p.LandData);
|
s.LandChannel.UpdateLandObject(p.LandData.LocalID, p.LandData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
responseData["success"] = true;
|
responseData["success"] = true;
|
||||||
|
|
||||||
m_log.Info("[RADMIN]: Reset Land Request complete");
|
m_log.Info("[RADMIN]: Reset Land Request complete");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void XmlRpcRefreshSearch(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
|
|
||||||
{
|
|
||||||
m_log.Info("[RADMIN]: Received Refresh Search Request");
|
|
||||||
|
|
||||||
Hashtable responseData = (Hashtable)response.Value;
|
|
||||||
Hashtable requestData = (Hashtable)request.Params[0];
|
|
||||||
|
|
||||||
CheckRegionParams(requestData, responseData);
|
|
||||||
|
|
||||||
Scene scene = null;
|
|
||||||
GetSceneFromRegionParams(requestData, responseData, out scene);
|
|
||||||
|
|
||||||
ISearchModule searchModule = scene.RequestModuleInterface<ISearchModule>();
|
|
||||||
if (searchModule != null)
|
|
||||||
{
|
|
||||||
searchModule.Refresh();
|
|
||||||
responseData["success"] = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
responseData["success"] = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_log.Info("[RADMIN]: Refresh Search Request complete");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void XmlRpcRefreshMap(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
|
|
||||||
{
|
|
||||||
m_log.Info("[RADMIN]: Received Refresh Map Request");
|
|
||||||
|
|
||||||
Hashtable responseData = (Hashtable)response.Value;
|
|
||||||
Hashtable requestData = (Hashtable)request.Params[0];
|
|
||||||
|
|
||||||
CheckRegionParams(requestData, responseData);
|
|
||||||
|
|
||||||
Scene scene = null;
|
|
||||||
GetSceneFromRegionParams(requestData, responseData, out scene);
|
|
||||||
|
|
||||||
IMapImageUploadModule mapTileModule = scene.RequestModuleInterface<IMapImageUploadModule>();
|
|
||||||
if (mapTileModule != null)
|
|
||||||
{
|
|
||||||
Util.FireAndForget((x) =>
|
|
||||||
{
|
|
||||||
mapTileModule.UploadMapTile(scene);
|
|
||||||
});
|
|
||||||
responseData["success"] = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
responseData["success"] = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_log.Info("[RADMIN]: Refresh Map Request complete");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void XmlRpcGetOpenSimVersion(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
|
|
||||||
{
|
|
||||||
m_log.Info("[RADMIN]: Received Get OpenSim Version Request");
|
|
||||||
|
|
||||||
Hashtable responseData = (Hashtable)response.Value;
|
|
||||||
|
|
||||||
responseData["version"] = m_openSimVersion;
|
|
||||||
responseData["success"] = true;
|
|
||||||
|
|
||||||
m_log.Info("[RADMIN]: Get OpenSim Version Request complete");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void XmlRpcGetAgentCount(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
|
|
||||||
{
|
|
||||||
m_log.Info("[RADMIN]: Received Get Agent Count Request");
|
|
||||||
|
|
||||||
Hashtable responseData = (Hashtable)response.Value;
|
|
||||||
Hashtable requestData = (Hashtable)request.Params[0];
|
|
||||||
|
|
||||||
CheckRegionParams(requestData, responseData);
|
|
||||||
|
|
||||||
Scene scene = null;
|
|
||||||
GetSceneFromRegionParams(requestData, responseData, out scene);
|
|
||||||
|
|
||||||
if (scene == null)
|
|
||||||
{
|
|
||||||
responseData["success"] = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
responseData["count"] = scene.GetRootAgentCount();
|
|
||||||
responseData["success"] = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_log.Info("[RADMIN]: Get Agent Count Request complete");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Parse a float with the given parameter name from a request data hash table.
|
/// Parse a float with the given parameter name from a request data hash table.
|
||||||
|
@ -2805,8 +2539,8 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Dictionary<UUID,UUID> inventoryMap = new Dictionary<UUID,UUID>();
|
Dictionary<UUID,UUID> inventoryMap = new Dictionary<UUID,UUID>();
|
||||||
CopyInventoryFolders(destination, source, FolderType.Clothing, inventoryMap, avatarAppearance);
|
CopyInventoryFolders(destination, source, AssetType.Clothing, inventoryMap, avatarAppearance);
|
||||||
CopyInventoryFolders(destination, source, FolderType.BodyPart, inventoryMap, avatarAppearance);
|
CopyInventoryFolders(destination, source, AssetType.Bodypart, inventoryMap, avatarAppearance);
|
||||||
|
|
||||||
AvatarWearable[] wearables = avatarAppearance.Wearables;
|
AvatarWearable[] wearables = avatarAppearance.Wearables;
|
||||||
|
|
||||||
|
@ -2842,20 +2576,20 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||||
IInventoryService inventoryService = m_application.SceneManager.CurrentOrFirstScene.InventoryService;
|
IInventoryService inventoryService = m_application.SceneManager.CurrentOrFirstScene.InventoryService;
|
||||||
|
|
||||||
// Get Clothing folder of receiver
|
// Get Clothing folder of receiver
|
||||||
InventoryFolderBase destinationFolder = inventoryService.GetFolderForType(destination, FolderType.Clothing);
|
InventoryFolderBase destinationFolder = inventoryService.GetFolderForType(destination, AssetType.Clothing);
|
||||||
|
|
||||||
if (destinationFolder == null)
|
if (destinationFolder == null)
|
||||||
throw new Exception("Cannot locate folder(s)");
|
throw new Exception("Cannot locate folder(s)");
|
||||||
|
|
||||||
// Missing destination folder? This should *never* be the case
|
// Missing destination folder? This should *never* be the case
|
||||||
if (destinationFolder.Type != (short)FolderType.Clothing)
|
if (destinationFolder.Type != (short)AssetType.Clothing)
|
||||||
{
|
{
|
||||||
destinationFolder = new InventoryFolderBase();
|
destinationFolder = new InventoryFolderBase();
|
||||||
|
|
||||||
destinationFolder.ID = UUID.Random();
|
destinationFolder.ID = UUID.Random();
|
||||||
destinationFolder.Name = "Clothing";
|
destinationFolder.Name = "Clothing";
|
||||||
destinationFolder.Owner = destination;
|
destinationFolder.Owner = destination;
|
||||||
destinationFolder.Type = (short)FolderType.Clothing;
|
destinationFolder.Type = (short)AssetType.Clothing;
|
||||||
destinationFolder.ParentID = inventoryService.GetRootFolder(destination).ID;
|
destinationFolder.ParentID = inventoryService.GetRootFolder(destination).ID;
|
||||||
destinationFolder.Version = 1;
|
destinationFolder.Version = 1;
|
||||||
inventoryService.AddFolder(destinationFolder); // store base record
|
inventoryService.AddFolder(destinationFolder); // store base record
|
||||||
|
@ -2872,7 +2606,8 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||||
if (wearable[0].ItemID != UUID.Zero)
|
if (wearable[0].ItemID != UUID.Zero)
|
||||||
{
|
{
|
||||||
// Get inventory item and copy it
|
// Get inventory item and copy it
|
||||||
InventoryItemBase item = inventoryService.GetItem(source, wearable[0].ItemID);
|
InventoryItemBase item = new InventoryItemBase(wearable[0].ItemID, source);
|
||||||
|
item = inventoryService.GetItem(item);
|
||||||
|
|
||||||
if (item != null)
|
if (item != null)
|
||||||
{
|
{
|
||||||
|
@ -2925,7 +2660,8 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||||
if (itemID != UUID.Zero)
|
if (itemID != UUID.Zero)
|
||||||
{
|
{
|
||||||
// Get inventory item and copy it
|
// Get inventory item and copy it
|
||||||
InventoryItemBase item = inventoryService.GetItem(source, itemID);
|
InventoryItemBase item = new InventoryItemBase(itemID, source);
|
||||||
|
item = inventoryService.GetItem(item);
|
||||||
|
|
||||||
if (item != null)
|
if (item != null)
|
||||||
{
|
{
|
||||||
|
@ -2971,7 +2707,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||||
/// This method is called by establishAppearance to copy inventory folders to make
|
/// This method is called by establishAppearance to copy inventory folders to make
|
||||||
/// copies of Clothing and Bodyparts inventory folders and attaches worn attachments
|
/// copies of Clothing and Bodyparts inventory folders and attaches worn attachments
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void CopyInventoryFolders(UUID destination, UUID source, FolderType assetType, Dictionary<UUID, UUID> inventoryMap,
|
private void CopyInventoryFolders(UUID destination, UUID source, AssetType assetType, Dictionary<UUID,UUID> inventoryMap,
|
||||||
AvatarAppearance avatarAppearance)
|
AvatarAppearance avatarAppearance)
|
||||||
{
|
{
|
||||||
IInventoryService inventoryService = m_application.SceneManager.CurrentOrFirstScene.InventoryService;
|
IInventoryService inventoryService = m_application.SceneManager.CurrentOrFirstScene.InventoryService;
|
||||||
|
@ -2987,12 +2723,9 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||||
{
|
{
|
||||||
sourceFolder = new InventoryFolderBase();
|
sourceFolder = new InventoryFolderBase();
|
||||||
sourceFolder.ID = UUID.Random();
|
sourceFolder.ID = UUID.Random();
|
||||||
if (assetType == FolderType.Clothing)
|
if (assetType == AssetType.Clothing) {
|
||||||
{
|
|
||||||
sourceFolder.Name = "Clothing";
|
sourceFolder.Name = "Clothing";
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
sourceFolder.Name = "Body Parts";
|
sourceFolder.Name = "Body Parts";
|
||||||
}
|
}
|
||||||
sourceFolder.Owner = source;
|
sourceFolder.Owner = source;
|
||||||
|
@ -3008,7 +2741,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||||
{
|
{
|
||||||
destinationFolder = new InventoryFolderBase();
|
destinationFolder = new InventoryFolderBase();
|
||||||
destinationFolder.ID = UUID.Random();
|
destinationFolder.ID = UUID.Random();
|
||||||
if (assetType == FolderType.Clothing)
|
if (assetType == AssetType.Clothing)
|
||||||
{
|
{
|
||||||
destinationFolder.Name = "Clothing";
|
destinationFolder.Name = "Clothing";
|
||||||
}
|
}
|
||||||
|
@ -3204,7 +2937,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||||
|
|
||||||
// Set home position
|
// Set home position
|
||||||
|
|
||||||
GridRegion home = scene.GridService.GetRegionByPosition(scopeID,
|
GridRegion home = scene.GridService.GetRegionByPosition(scopeID,
|
||||||
(int)Util.RegionToWorldLoc(regionXLocation), (int)Util.RegionToWorldLoc(regionYLocation));
|
(int)Util.RegionToWorldLoc(regionXLocation), (int)Util.RegionToWorldLoc(regionYLocation));
|
||||||
if (null == home) {
|
if (null == home) {
|
||||||
m_log.WarnFormat("[RADMIN]: Unable to set home region for newly created user account {0} {1}", names[0], names[1]);
|
m_log.WarnFormat("[RADMIN]: Unable to set home region for newly created user account {0} {1}", names[0], names[1]);
|
||||||
|
@ -3247,16 +2980,16 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||||
// m_log.DebugFormat("[RADMIN] {0} folders, {1} items in inventory",
|
// m_log.DebugFormat("[RADMIN] {0} folders, {1} items in inventory",
|
||||||
// uic.folders.Count, uic.items.Count);
|
// uic.folders.Count, uic.items.Count);
|
||||||
|
|
||||||
InventoryFolderBase clothingFolder = inventoryService.GetFolderForType(ID, FolderType.Clothing);
|
InventoryFolderBase clothingFolder = inventoryService.GetFolderForType(ID, AssetType.Clothing);
|
||||||
|
|
||||||
// This should *never* be the case
|
// This should *never* be the case
|
||||||
if (clothingFolder == null || clothingFolder.Type != (short)FolderType.Clothing)
|
if (clothingFolder == null || clothingFolder.Type != (short)AssetType.Clothing)
|
||||||
{
|
{
|
||||||
clothingFolder = new InventoryFolderBase();
|
clothingFolder = new InventoryFolderBase();
|
||||||
clothingFolder.ID = UUID.Random();
|
clothingFolder.ID = UUID.Random();
|
||||||
clothingFolder.Name = "Clothing";
|
clothingFolder.Name = "Clothing";
|
||||||
clothingFolder.Owner = ID;
|
clothingFolder.Owner = ID;
|
||||||
clothingFolder.Type = (short)FolderType.Clothing;
|
clothingFolder.Type = (short)AssetType.Clothing;
|
||||||
clothingFolder.ParentID = inventoryService.GetRootFolder(ID).ID;
|
clothingFolder.ParentID = inventoryService.GetRootFolder(ID).ID;
|
||||||
clothingFolder.Version = 1;
|
clothingFolder.Version = 1;
|
||||||
inventoryService.AddFolder(clothingFolder); // store base record
|
inventoryService.AddFolder(clothingFolder); // store base record
|
||||||
|
@ -3302,7 +3035,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
|
||||||
extraFolder.ID = UUID.Random();
|
extraFolder.ID = UUID.Random();
|
||||||
extraFolder.Name = outfitName;
|
extraFolder.Name = outfitName;
|
||||||
extraFolder.Owner = ID;
|
extraFolder.Owner = ID;
|
||||||
extraFolder.Type = (short)FolderType.Clothing;
|
extraFolder.Type = (short)AssetType.Clothing;
|
||||||
extraFolder.Version = 1;
|
extraFolder.Version = 1;
|
||||||
extraFolder.ParentID = clothingFolder.ID;
|
extraFolder.ParentID = clothingFolder.ID;
|
||||||
inventoryService.AddFolder(extraFolder);
|
inventoryService.AddFolder(extraFolder);
|
||||||
|
|
|
@ -28,10 +28,8 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Concurrent;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Threading;
|
|
||||||
using log4net;
|
using log4net;
|
||||||
using Nini.Config;
|
using Nini.Config;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
|
@ -50,9 +48,9 @@ namespace OpenSim.Framework.Capabilities
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public delegate IClientAPI GetClientDelegate(UUID agentID);
|
public delegate IClientAPI GetClientDelegate(UUID agentID);
|
||||||
|
|
||||||
public class Caps : IDisposable
|
public class Caps
|
||||||
{
|
{
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
private string m_httpListenerHostName;
|
private string m_httpListenerHostName;
|
||||||
private uint m_httpListenPort;
|
private uint m_httpListenPort;
|
||||||
|
@ -65,15 +63,14 @@ namespace OpenSim.Framework.Capabilities
|
||||||
|
|
||||||
private CapsHandlers m_capsHandlers;
|
private CapsHandlers m_capsHandlers;
|
||||||
|
|
||||||
private ConcurrentDictionary<string, PollServiceEventArgs> m_pollServiceHandlers
|
private Dictionary<string, PollServiceEventArgs> m_pollServiceHandlers
|
||||||
= new ConcurrentDictionary<string, PollServiceEventArgs>();
|
= new Dictionary<string, PollServiceEventArgs>();
|
||||||
|
|
||||||
private Dictionary<string, string> m_externalCapsHandlers = new Dictionary<string, string>();
|
private Dictionary<string, string> m_externalCapsHandlers = new Dictionary<string, string>();
|
||||||
|
|
||||||
private IHttpServer m_httpListener;
|
private IHttpServer m_httpListener;
|
||||||
private UUID m_agentID;
|
private UUID m_agentID;
|
||||||
private string m_regionName;
|
private string m_regionName;
|
||||||
private ManualResetEvent m_capsActive = new ManualResetEvent(false);
|
|
||||||
|
|
||||||
public UUID AgentID
|
public UUID AgentID
|
||||||
{
|
{
|
||||||
|
@ -120,19 +117,6 @@ namespace OpenSim.Framework.Capabilities
|
||||||
get { return m_externalCapsHandlers; }
|
get { return m_externalCapsHandlers; }
|
||||||
}
|
}
|
||||||
|
|
||||||
[Flags]
|
|
||||||
public enum CapsFlags:uint
|
|
||||||
{
|
|
||||||
None = 0,
|
|
||||||
SentSeeds = 1,
|
|
||||||
|
|
||||||
ObjectAnim = 0x100,
|
|
||||||
WLEnv = 0x200,
|
|
||||||
AdvEnv = 0x400
|
|
||||||
}
|
|
||||||
|
|
||||||
public CapsFlags Flags { get; set;}
|
|
||||||
|
|
||||||
public Caps(IHttpServer httpServer, string httpListen, uint httpPort, string capsPath,
|
public Caps(IHttpServer httpServer, string httpListen, uint httpPort, string capsPath,
|
||||||
UUID agent, string regionName)
|
UUID agent, string regionName)
|
||||||
{
|
{
|
||||||
|
@ -150,37 +134,8 @@ namespace OpenSim.Framework.Capabilities
|
||||||
}
|
}
|
||||||
|
|
||||||
m_agentID = agent;
|
m_agentID = agent;
|
||||||
m_capsHandlers = new CapsHandlers(httpServer, httpListen, httpPort);
|
m_capsHandlers = new CapsHandlers(httpServer, httpListen, httpPort, (httpServer == null) ? false : httpServer.UseSSL);
|
||||||
m_regionName = regionName;
|
m_regionName = regionName;
|
||||||
Flags = CapsFlags.None;
|
|
||||||
m_capsActive.Reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
~Caps()
|
|
||||||
{
|
|
||||||
Flags = CapsFlags.None;
|
|
||||||
if (m_capsActive!= null)
|
|
||||||
{
|
|
||||||
m_capsActive.Dispose();
|
|
||||||
m_capsActive = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
Dispose(true);
|
|
||||||
GC.SuppressFinalize(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose(bool disposing)
|
|
||||||
{
|
|
||||||
Flags = CapsFlags.None;
|
|
||||||
if (m_capsActive != null)
|
|
||||||
{
|
|
||||||
DeregisterHandlers();
|
|
||||||
m_capsActive.Dispose();
|
|
||||||
m_capsActive = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -194,32 +149,20 @@ namespace OpenSim.Framework.Capabilities
|
||||||
m_capsHandlers[capName] = handler;
|
m_capsHandlers[capName] = handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RegisterSimpleHandler(string capName, ISimpleStreamHandler handler, bool addToListener = true)
|
|
||||||
{
|
|
||||||
//m_log.DebugFormat("[CAPS]: Registering handler for \"{0}\": path {1}", capName, handler.Path);
|
|
||||||
m_capsHandlers.AddSimpleHandler(capName, handler, addToListener);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RegisterPollHandler(string capName, PollServiceEventArgs pollServiceHandler)
|
public void RegisterPollHandler(string capName, PollServiceEventArgs pollServiceHandler)
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat(
|
// m_log.DebugFormat(
|
||||||
// "[CAPS]: Registering handler with name {0}, url {1} for {2}",
|
// "[CAPS]: Registering handler with name {0}, url {1} for {2}",
|
||||||
// capName, pollServiceHandler.Url, m_agentID, m_regionName);
|
// capName, pollServiceHandler.Url, m_agentID, m_regionName);
|
||||||
|
|
||||||
if(!m_pollServiceHandlers.TryAdd(capName, pollServiceHandler))
|
m_pollServiceHandlers.Add(capName, pollServiceHandler);
|
||||||
{
|
|
||||||
m_log.ErrorFormat(
|
|
||||||
"[CAPS]: Handler with name {0} already registered (ulr {1}, agent {2}, region {3}",
|
|
||||||
capName, pollServiceHandler.Url, m_agentID, m_regionName);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_httpListener.AddPollServiceHTTPHandler(pollServiceHandler);
|
m_httpListener.AddPollServiceHTTPHandler(pollServiceHandler.Url, pollServiceHandler);
|
||||||
|
|
||||||
// uint port = (MainServer.Instance == null) ? 0 : MainServer.Instance.Port;
|
// uint port = (MainServer.Instance == null) ? 0 : MainServer.Instance.Port;
|
||||||
// string protocol = "http";
|
// string protocol = "http";
|
||||||
// string hostName = m_httpListenerHostName;
|
// string hostName = m_httpListenerHostName;
|
||||||
//
|
//
|
||||||
// if (MainServer.Instance.UseSSL)
|
// if (MainServer.Instance.UseSSL)
|
||||||
// {
|
// {
|
||||||
// hostName = MainServer.Instance.SSLCommonName;
|
// hostName = MainServer.Instance.SSLCommonName;
|
||||||
|
@ -254,9 +197,8 @@ namespace OpenSim.Framework.Capabilities
|
||||||
|
|
||||||
foreach (PollServiceEventArgs handler in m_pollServiceHandlers.Values)
|
foreach (PollServiceEventArgs handler in m_pollServiceHandlers.Values)
|
||||||
{
|
{
|
||||||
m_httpListener.RemovePollServiceHTTPHandler(handler.Url);
|
m_httpListener.RemovePollServiceHTTPHandler("", handler.Url);
|
||||||
}
|
}
|
||||||
m_pollServiceHandlers.Clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool TryGetPollHandler(string name, out PollServiceEventArgs pollHandler)
|
public bool TryGetPollHandler(string name, out PollServiceEventArgs pollHandler)
|
||||||
|
@ -288,13 +230,16 @@ namespace OpenSim.Framework.Capabilities
|
||||||
string hostName = m_httpListenerHostName;
|
string hostName = m_httpListenerHostName;
|
||||||
uint port = (MainServer.Instance == null) ? 0 : MainServer.Instance.Port;
|
uint port = (MainServer.Instance == null) ? 0 : MainServer.Instance.Port;
|
||||||
string protocol = "http";
|
string protocol = "http";
|
||||||
|
|
||||||
if (MainServer.Instance.UseSSL)
|
if (MainServer.Instance.UseSSL)
|
||||||
{
|
{
|
||||||
hostName = MainServer.Instance.SSLCommonName;
|
hostName = MainServer.Instance.SSLCommonName;
|
||||||
port = MainServer.Instance.SSLPort;
|
port = MainServer.Instance.SSLPort;
|
||||||
protocol = "https";
|
protocol = "https";
|
||||||
}
|
}
|
||||||
|
//
|
||||||
|
// caps.RegisterHandler("FetchInventoryDescendents2", String.Format("{0}://{1}:{2}{3}", protocol, hostName, port, capUrl));
|
||||||
|
|
||||||
caps[kvp.Key] = string.Format("{0}://{1}:{2}{3}", protocol, hostName, port, kvp.Value.Url);
|
caps[kvp.Key] = string.Format("{0}://{1}:{2}{3}", protocol, hostName, port, kvp.Value.Url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -308,19 +253,7 @@ namespace OpenSim.Framework.Capabilities
|
||||||
caps[kvp.Key] = kvp.Value;
|
caps[kvp.Key] = kvp.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return caps;
|
return caps;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Activate()
|
|
||||||
{
|
|
||||||
m_capsActive.Set();
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool WaitForActivation()
|
|
||||||
{
|
|
||||||
// Wait for 30s. If that elapses, return false and run without caps
|
|
||||||
return m_capsActive.WaitOne(120000);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -27,7 +27,6 @@
|
||||||
|
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Concurrent;
|
|
||||||
using OpenSim.Framework.Servers;
|
using OpenSim.Framework.Servers;
|
||||||
using OpenSim.Framework.Servers.HttpServer;
|
using OpenSim.Framework.Servers.HttpServer;
|
||||||
|
|
||||||
|
@ -41,7 +40,6 @@ namespace OpenSim.Framework.Capabilities
|
||||||
public class CapsHandlers
|
public class CapsHandlers
|
||||||
{
|
{
|
||||||
private Dictionary<string, IRequestHandler> m_capsHandlers = new Dictionary<string, IRequestHandler>();
|
private Dictionary<string, IRequestHandler> m_capsHandlers = new Dictionary<string, IRequestHandler>();
|
||||||
private ConcurrentDictionary<string, ISimpleStreamHandler> m_capsSimpleHandlers = new ConcurrentDictionary<string, ISimpleStreamHandler>();
|
|
||||||
private IHttpServer m_httpListener;
|
private IHttpServer m_httpListener;
|
||||||
private string m_httpListenerHostName;
|
private string m_httpListenerHostName;
|
||||||
private uint m_httpListenerPort;
|
private uint m_httpListenerPort;
|
||||||
|
@ -55,15 +53,31 @@ namespace OpenSim.Framework.Capabilities
|
||||||
/// <param name="httpListener">base HTTP server</param>
|
/// <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>
|
/// <param name="httpListenerPort">HTTP port</param>
|
||||||
public CapsHandlers(IHttpServer httpListener, string httpListenerHostname, uint httpListenerPort)
|
public CapsHandlers(BaseHttpServer httpListener, string httpListenerHostname, uint httpListenerPort)
|
||||||
{
|
: this(httpListener,httpListenerHostname,httpListenerPort, false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary></summary>
|
||||||
|
/// CapsHandlers is a cap handler container but also takes
|
||||||
|
/// care of adding and removing cap handlers to and from the
|
||||||
|
/// supplied BaseHttpServer.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="httpListener">base HTTP server</param>
|
||||||
|
/// <param name="httpListenerHostname">host name of the HTTP
|
||||||
|
/// server</param>
|
||||||
|
/// <param name="httpListenerPort">HTTP port</param>
|
||||||
|
public CapsHandlers(IHttpServer httpListener, string httpListenerHostname, uint httpListenerPort, bool https)
|
||||||
|
{
|
||||||
m_httpListener = httpListener;
|
m_httpListener = httpListener;
|
||||||
m_httpListenerHostName = httpListenerHostname;
|
m_httpListenerHostName = httpListenerHostname;
|
||||||
m_httpListenerPort = httpListenerPort;
|
m_httpListenerPort = httpListenerPort;
|
||||||
if (httpListener != null && httpListener.UseSSL)
|
m_useSSL = https;
|
||||||
m_useSSL = true;
|
if (httpListener != null && m_useSSL)
|
||||||
else
|
{
|
||||||
m_useSSL = false;
|
m_httpListenerHostName = httpListener.SSLCommonName;
|
||||||
|
m_httpListenerPort = httpListener.SSLPort;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -75,35 +89,16 @@ namespace OpenSim.Framework.Capabilities
|
||||||
{
|
{
|
||||||
lock (m_capsHandlers)
|
lock (m_capsHandlers)
|
||||||
{
|
{
|
||||||
if(m_capsHandlers.ContainsKey(capsName))
|
m_httpListener.RemoveStreamHandler("POST", m_capsHandlers[capsName].Path);
|
||||||
{
|
m_httpListener.RemoveStreamHandler("GET", m_capsHandlers[capsName].Path);
|
||||||
m_httpListener.RemoveStreamHandler("POST", m_capsHandlers[capsName].Path);
|
m_capsHandlers.Remove(capsName);
|
||||||
m_httpListener.RemoveStreamHandler("PUT", m_capsHandlers[capsName].Path);
|
|
||||||
m_httpListener.RemoveStreamHandler("GET", m_capsHandlers[capsName].Path);
|
|
||||||
m_httpListener.RemoveStreamHandler("DELETE", m_capsHandlers[capsName].Path);
|
|
||||||
m_capsHandlers.Remove(capsName);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if(m_capsSimpleHandlers.TryRemove(capsName, out ISimpleStreamHandler hdr))
|
|
||||||
{
|
|
||||||
m_httpListener.RemoveSimpleStreamHandler(hdr.Path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void AddSimpleHandler(string capName, ISimpleStreamHandler handler, bool addToListener = true)
|
|
||||||
{
|
|
||||||
if(ContainsCap(capName))
|
|
||||||
Remove(capName);
|
|
||||||
if(m_capsSimpleHandlers.TryAdd(capName, handler) && addToListener)
|
|
||||||
m_httpListener.AddSimpleStreamHandler(handler);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool ContainsCap(string cap)
|
public bool ContainsCap(string cap)
|
||||||
{
|
{
|
||||||
lock (m_capsHandlers)
|
lock (m_capsHandlers)
|
||||||
if (m_capsHandlers.ContainsKey(cap))
|
return m_capsHandlers.ContainsKey(cap);
|
||||||
return true;
|
|
||||||
return m_capsSimpleHandlers.ContainsKey(cap);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -130,14 +125,11 @@ namespace OpenSim.Framework.Capabilities
|
||||||
if (m_capsHandlers.ContainsKey(idx))
|
if (m_capsHandlers.ContainsKey(idx))
|
||||||
{
|
{
|
||||||
m_httpListener.RemoveStreamHandler("POST", m_capsHandlers[idx].Path);
|
m_httpListener.RemoveStreamHandler("POST", m_capsHandlers[idx].Path);
|
||||||
m_httpListener.RemoveStreamHandler("PUT", m_capsHandlers[idx].Path);
|
|
||||||
m_httpListener.RemoveStreamHandler("GET", m_capsHandlers[idx].Path);
|
|
||||||
m_httpListener.RemoveStreamHandler("DELETE", m_capsHandlers[idx].Path);
|
|
||||||
m_capsHandlers.Remove(idx);
|
m_capsHandlers.Remove(idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (null == value) return;
|
if (null == value) return;
|
||||||
|
|
||||||
m_capsHandlers[idx] = value;
|
m_capsHandlers[idx] = value;
|
||||||
m_httpListener.AddStreamHandler(value);
|
m_httpListener.AddStreamHandler(value);
|
||||||
}
|
}
|
||||||
|
@ -154,9 +146,8 @@ namespace OpenSim.Framework.Capabilities
|
||||||
{
|
{
|
||||||
lock (m_capsHandlers)
|
lock (m_capsHandlers)
|
||||||
{
|
{
|
||||||
string[] __keys = new string[m_capsHandlers.Keys.Count + m_capsSimpleHandlers.Keys.Count];
|
string[] __keys = new string[m_capsHandlers.Keys.Count];
|
||||||
m_capsHandlers.Keys.CopyTo(__keys, 0);
|
m_capsHandlers.Keys.CopyTo(__keys, 0);
|
||||||
m_capsSimpleHandlers.Keys.CopyTo(__keys, m_capsHandlers.Keys.Count);
|
|
||||||
return __keys;
|
return __keys;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -170,39 +161,24 @@ namespace OpenSim.Framework.Capabilities
|
||||||
public Hashtable GetCapsDetails(bool excludeSeed, List<string> requestedCaps)
|
public Hashtable GetCapsDetails(bool excludeSeed, List<string> requestedCaps)
|
||||||
{
|
{
|
||||||
Hashtable caps = new Hashtable();
|
Hashtable caps = new Hashtable();
|
||||||
|
string protocol = "http://";
|
||||||
|
|
||||||
|
if (m_useSSL)
|
||||||
|
protocol = "https://";
|
||||||
|
|
||||||
string protocol = m_useSSL ? "https://" : "http://";
|
|
||||||
string baseUrl = protocol + m_httpListenerHostName + ":" + m_httpListenerPort.ToString();
|
string baseUrl = protocol + m_httpListenerHostName + ":" + m_httpListenerPort.ToString();
|
||||||
|
|
||||||
if (requestedCaps == null)
|
|
||||||
{
|
|
||||||
lock (m_capsHandlers)
|
|
||||||
{
|
|
||||||
foreach (KeyValuePair<string, ISimpleStreamHandler> kvp in m_capsSimpleHandlers)
|
|
||||||
caps[kvp.Key] = baseUrl + kvp.Value.Path;
|
|
||||||
foreach (KeyValuePair<string, IRequestHandler> kvp in m_capsHandlers)
|
|
||||||
caps[kvp.Key] = baseUrl + kvp.Value.Path;
|
|
||||||
}
|
|
||||||
return caps;
|
|
||||||
}
|
|
||||||
|
|
||||||
lock (m_capsHandlers)
|
lock (m_capsHandlers)
|
||||||
{
|
{
|
||||||
for(int i = 0; i < requestedCaps.Count; ++i)
|
foreach (string capsName in m_capsHandlers.Keys)
|
||||||
{
|
{
|
||||||
string capsName = requestedCaps[i];
|
|
||||||
if (excludeSeed && "SEED" == capsName)
|
if (excludeSeed && "SEED" == capsName)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (m_capsSimpleHandlers.TryGetValue(capsName, out ISimpleStreamHandler shdr))
|
if (requestedCaps != null && !requestedCaps.Contains(capsName))
|
||||||
{
|
|
||||||
caps[capsName] = baseUrl + shdr.Path;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
if (m_capsHandlers.TryGetValue(capsName, out IRequestHandler chdr))
|
caps[capsName] = baseUrl + m_capsHandlers[capsName].Path;
|
||||||
{
|
|
||||||
caps[capsName] = baseUrl + chdr.Path;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,116 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSimulator Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.Specialized;
|
||||||
|
using System.IO;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Web;
|
||||||
|
using log4net;
|
||||||
|
using Nini.Config;
|
||||||
|
using OpenMetaverse;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Framework.Capabilities;
|
||||||
|
using OpenSim.Framework.Servers;
|
||||||
|
using OpenSim.Framework.Servers.HttpServer;
|
||||||
|
//using OpenSim.Region.Framework.Interfaces;
|
||||||
|
using OpenSim.Services.Interfaces;
|
||||||
|
using Caps = OpenSim.Framework.Capabilities.Caps;
|
||||||
|
|
||||||
|
namespace OpenSim.Capabilities.Handlers
|
||||||
|
{
|
||||||
|
public class AvatarPickerSearchHandler : BaseStreamHandler
|
||||||
|
{
|
||||||
|
private static readonly ILog m_log =
|
||||||
|
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
private IPeople m_PeopleService;
|
||||||
|
|
||||||
|
public AvatarPickerSearchHandler(string path, IPeople peopleService, string name, string description)
|
||||||
|
: base("GET", path, name, description)
|
||||||
|
{
|
||||||
|
m_PeopleService = peopleService;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
||||||
|
{
|
||||||
|
// Try to parse the texture ID from the request URL
|
||||||
|
NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query);
|
||||||
|
string names = query.GetOne("names");
|
||||||
|
string psize = query.GetOne("page_size");
|
||||||
|
string pnumber = query.GetOne("page");
|
||||||
|
|
||||||
|
if (m_PeopleService == null)
|
||||||
|
return FailureResponse(names, (int)System.Net.HttpStatusCode.InternalServerError, httpResponse);
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(names) || names.Length < 3)
|
||||||
|
return FailureResponse(names, (int)System.Net.HttpStatusCode.BadRequest, httpResponse);
|
||||||
|
|
||||||
|
m_log.DebugFormat("[AVATAR PICKER SEARCH]: search for {0}", names);
|
||||||
|
|
||||||
|
int page_size = (string.IsNullOrEmpty(psize) ? 500 : Int32.Parse(psize));
|
||||||
|
int page_number = (string.IsNullOrEmpty(pnumber) ? 1 : Int32.Parse(pnumber));
|
||||||
|
|
||||||
|
// Full content request
|
||||||
|
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.OK;
|
||||||
|
//httpResponse.ContentLength = ??;
|
||||||
|
httpResponse.ContentType = "application/llsd+xml";
|
||||||
|
|
||||||
|
List<UserData> users = m_PeopleService.GetUserData(names, page_size, page_number);
|
||||||
|
|
||||||
|
LLSDAvatarPicker osdReply = new LLSDAvatarPicker();
|
||||||
|
osdReply.next_page_url = httpRequest.RawUrl;
|
||||||
|
foreach (UserData u in users)
|
||||||
|
osdReply.agents.Array.Add(ConvertUserData(u));
|
||||||
|
|
||||||
|
string reply = LLSDHelpers.SerialiseLLSDReply(osdReply);
|
||||||
|
return System.Text.Encoding.UTF8.GetBytes(reply);
|
||||||
|
}
|
||||||
|
|
||||||
|
private LLSDPerson ConvertUserData(UserData user)
|
||||||
|
{
|
||||||
|
LLSDPerson p = new LLSDPerson();
|
||||||
|
p.legacy_first_name = user.FirstName;
|
||||||
|
p.legacy_last_name = user.LastName;
|
||||||
|
p.display_name = user.FirstName + " " + user.LastName;
|
||||||
|
if (user.LastName.StartsWith("@"))
|
||||||
|
p.username = user.FirstName.ToLower() + user.LastName.ToLower();
|
||||||
|
else
|
||||||
|
p.username = user.FirstName.ToLower() + "." + user.LastName.ToLower();
|
||||||
|
p.id = user.Id;
|
||||||
|
p.is_display_name_default = false;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] FailureResponse(string names, int statuscode, IOSHttpResponse httpResponse)
|
||||||
|
{
|
||||||
|
m_log.Error("[AVATAR PICKER SEARCH]: Error searching for " + names);
|
||||||
|
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
|
||||||
|
return System.Text.Encoding.UTF8.GetBytes(string.Empty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,449 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
* * Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* * Neither the name of the OpenSimulator Project nor the
|
|
||||||
* names of its contributors may be used to endorse or promote products
|
|
||||||
* derived from this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
|
||||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Text;
|
|
||||||
using log4net;
|
|
||||||
using Nini.Config;
|
|
||||||
using OpenMetaverse;
|
|
||||||
using OpenMetaverse.StructuredData;
|
|
||||||
using OpenSim.Framework;
|
|
||||||
using OpenSim.Framework.Capabilities;
|
|
||||||
using OpenSim.Framework.Servers.HttpServer;
|
|
||||||
using OpenSim.Services.Interfaces;
|
|
||||||
using OSDMap = OpenMetaverse.StructuredData.OSDMap;
|
|
||||||
using OSDArray = OpenMetaverse.StructuredData.OSDArray;
|
|
||||||
|
|
||||||
namespace OpenSim.Capabilities.Handlers
|
|
||||||
{
|
|
||||||
public class FetchInvDescHandler
|
|
||||||
{
|
|
||||||
private static readonly ILog m_log =
|
|
||||||
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
|
||||||
|
|
||||||
private static byte[] EmptyResponse = Util.UTF8NBGetbytes("<llsd><map><key>folders</key><array /></map></llsd>");
|
|
||||||
private IInventoryService m_InventoryService;
|
|
||||||
private ILibraryService m_LibraryService;
|
|
||||||
private IScene m_Scene;
|
|
||||||
|
|
||||||
public FetchInvDescHandler(IInventoryService invService, ILibraryService libService, IScene s)
|
|
||||||
{
|
|
||||||
m_InventoryService = invService;
|
|
||||||
m_LibraryService = libService;
|
|
||||||
m_Scene = s;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void FetchInventoryDescendentsRequest(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, ExpiringKey<UUID> BadRequests)
|
|
||||||
{
|
|
||||||
//m_log.DebugFormat("[XXX]: FetchInventoryDescendentsRequest in {0}, {1}", (m_Scene == null) ? "none" : m_Scene.Name, request);
|
|
||||||
|
|
||||||
List<LLSDFetchInventoryDescendents> folders = null;
|
|
||||||
List<UUID> bad_folders = new List<UUID>();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
OSDArray foldersrequested = null;
|
|
||||||
OSD tmp = OSDParser.DeserializeLLSDXml(httpRequest.InputStream);
|
|
||||||
OSDMap map = (OSDMap)tmp;
|
|
||||||
if(map.TryGetValue("folders", out tmp) && tmp is OSDArray)
|
|
||||||
foldersrequested = tmp as OSDArray;
|
|
||||||
|
|
||||||
if (foldersrequested == null || foldersrequested.Count == 0)
|
|
||||||
{
|
|
||||||
httpResponse.RawBuffer = EmptyResponse;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
folders = new List<LLSDFetchInventoryDescendents>(foldersrequested.Count);
|
|
||||||
for (int i = 0; i < foldersrequested.Count; i++)
|
|
||||||
{
|
|
||||||
OSDMap mfolder = foldersrequested[i] as OSDMap;
|
|
||||||
UUID id = mfolder["folder_id"].AsUUID();
|
|
||||||
if(BadRequests.ContainsKey(id))
|
|
||||||
{
|
|
||||||
bad_folders.Add(id);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LLSDFetchInventoryDescendents llsdRequest = new LLSDFetchInventoryDescendents();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
llsdRequest.folder_id = id;
|
|
||||||
llsdRequest.owner_id = mfolder["owner_id"].AsUUID();
|
|
||||||
llsdRequest.sort_order = mfolder["sort_order"].AsInteger();
|
|
||||||
llsdRequest.fetch_folders = mfolder["fetch_folders"].AsBoolean();
|
|
||||||
llsdRequest.fetch_items = mfolder["fetch_items"].AsBoolean();
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
m_log.Debug("[WEB FETCH INV DESC HANDLER]: caught exception doing OSD deserialize" + e.Message);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
folders.Add(llsdRequest);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
foldersrequested = null;
|
|
||||||
tmp = null;
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
m_log.ErrorFormat("[FETCH INV DESC]: fail parsing request: {0}", e.Message);
|
|
||||||
httpResponse.RawBuffer = EmptyResponse;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (folders == null || folders.Count == 0)
|
|
||||||
{
|
|
||||||
if(bad_folders.Count == 0)
|
|
||||||
{
|
|
||||||
httpResponse.RawBuffer = EmptyResponse;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
StringBuilder sb = osStringBuilderCache.Acquire();
|
|
||||||
sb.Append("<llsd><map><key>folders</key><array /></map><map><key>bad_folders</key><array>");
|
|
||||||
foreach (UUID bad in bad_folders)
|
|
||||||
{
|
|
||||||
sb.Append("<map><key>folder_id</key><uuid>");
|
|
||||||
sb.Append(bad.ToString());
|
|
||||||
sb.Append("</uuid><key>error</key><string>Unknown</string></map>");
|
|
||||||
}
|
|
||||||
sb.Append("</array></map></llsd>");
|
|
||||||
httpResponse.RawBuffer = Util.UTF8NBGetbytes(osStringBuilderCache.GetStringAndRelease(sb));
|
|
||||||
}
|
|
||||||
|
|
||||||
int total_folders = 0;
|
|
||||||
int total_items = 0;
|
|
||||||
|
|
||||||
List<InventoryCollection> invcollSet = Fetch(folders, bad_folders, ref total_folders, ref total_items);
|
|
||||||
//m_log.DebugFormat("[XXX]: Got {0} folders from a request of {1}", invcollSet.Count, folders.Count);
|
|
||||||
|
|
||||||
int invcollSetCount = 0;
|
|
||||||
if (invcollSet != null)
|
|
||||||
invcollSetCount = invcollSet.Count;
|
|
||||||
|
|
||||||
int mem = 8192 + ((256 * invcollSetCount +
|
|
||||||
384 * total_folders +
|
|
||||||
1024 * total_items +
|
|
||||||
128 * bad_folders.Count) & 0x7ffff000);
|
|
||||||
|
|
||||||
StringBuilder lastresponse = new StringBuilder(mem);
|
|
||||||
lastresponse.Append("<llsd>");
|
|
||||||
|
|
||||||
if (invcollSetCount > 0)
|
|
||||||
{
|
|
||||||
lastresponse.Append("<map><key>folders</key><array>");
|
|
||||||
int i = 0;
|
|
||||||
InventoryCollection thiscoll;
|
|
||||||
for (i = 0; i < invcollSetCount; i++)
|
|
||||||
{
|
|
||||||
thiscoll = invcollSet[i];
|
|
||||||
invcollSet[i] = null;
|
|
||||||
|
|
||||||
LLSDxmlEncode.AddMap(lastresponse);
|
|
||||||
LLSDxmlEncode.AddElem("agent_id", thiscoll.OwnerID, lastresponse);
|
|
||||||
LLSDxmlEncode.AddElem("descendents", thiscoll.Descendents, lastresponse);
|
|
||||||
LLSDxmlEncode.AddElem("folder_id", thiscoll.FolderID, lastresponse);
|
|
||||||
|
|
||||||
if (thiscoll.Folders == null || thiscoll.Folders.Count == 0)
|
|
||||||
LLSDxmlEncode.AddEmptyArray("categories", lastresponse);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LLSDxmlEncode.AddArray("categories", lastresponse);
|
|
||||||
foreach (InventoryFolderBase invFolder in thiscoll.Folders)
|
|
||||||
{
|
|
||||||
LLSDxmlEncode.AddMap(lastresponse);
|
|
||||||
|
|
||||||
LLSDxmlEncode.AddElem("folder_id", invFolder.ID, lastresponse);
|
|
||||||
LLSDxmlEncode.AddElem("parent_id", invFolder.ParentID, lastresponse);
|
|
||||||
LLSDxmlEncode.AddElem("name", invFolder.Name, lastresponse);
|
|
||||||
LLSDxmlEncode.AddElem("type", invFolder.Type, lastresponse);
|
|
||||||
LLSDxmlEncode.AddElem("preferred_type", (int)-1, lastresponse);
|
|
||||||
LLSDxmlEncode.AddElem("version", invFolder.Version, lastresponse);
|
|
||||||
|
|
||||||
LLSDxmlEncode.AddEndMap(lastresponse);
|
|
||||||
}
|
|
||||||
LLSDxmlEncode.AddEndArray(lastresponse);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (thiscoll.Items == null || thiscoll.Items.Count == 0)
|
|
||||||
LLSDxmlEncode.AddEmptyArray("items", lastresponse);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LLSDxmlEncode.AddArray("items", lastresponse);
|
|
||||||
foreach (InventoryItemBase invItem in thiscoll.Items)
|
|
||||||
{
|
|
||||||
invItem.ToLLSDxml(lastresponse);
|
|
||||||
}
|
|
||||||
|
|
||||||
LLSDxmlEncode.AddEndArray(lastresponse);
|
|
||||||
}
|
|
||||||
|
|
||||||
LLSDxmlEncode.AddElem("owner_id", thiscoll.OwnerID, lastresponse);
|
|
||||||
LLSDxmlEncode.AddElem("version", thiscoll.Version, lastresponse);
|
|
||||||
|
|
||||||
LLSDxmlEncode.AddEndMap(lastresponse);
|
|
||||||
invcollSet[i] = null;
|
|
||||||
}
|
|
||||||
lastresponse.Append("</array></map>");
|
|
||||||
thiscoll = null;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
lastresponse.Append("<map><key>folders</key><array /></map>");
|
|
||||||
}
|
|
||||||
|
|
||||||
//m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Bad folders {0}", string.Join(", ", bad_folders));
|
|
||||||
if (bad_folders.Count > 0)
|
|
||||||
{
|
|
||||||
lastresponse.Append("<map><key>bad_folders</key><array>");
|
|
||||||
foreach (UUID bad in bad_folders)
|
|
||||||
{
|
|
||||||
BadRequests.Add(bad);
|
|
||||||
lastresponse.Append("<map><key>folder_id</key><uuid>");
|
|
||||||
lastresponse.Append(bad.ToString());
|
|
||||||
lastresponse.Append("</uuid><key>error</key><string>Unknown</string></map>");
|
|
||||||
}
|
|
||||||
lastresponse.Append("</array></map>");
|
|
||||||
}
|
|
||||||
lastresponse.Append("</llsd>");
|
|
||||||
|
|
||||||
httpResponse.RawBuffer = Util.UTF8NBGetbytes(lastresponse.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AddLibraryFolders(List<LLSDFetchInventoryDescendents> libFolders, List<InventoryCollection> result, ref int total_folders, ref int total_items)
|
|
||||||
{
|
|
||||||
InventoryFolderImpl fold;
|
|
||||||
if (m_LibraryService == null || m_LibraryService.LibraryRootFolder == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
foreach (LLSDFetchInventoryDescendents f in libFolders)
|
|
||||||
{
|
|
||||||
if ((fold = m_LibraryService.LibraryRootFolder.FindFolder(f.folder_id)) != null)
|
|
||||||
{
|
|
||||||
InventoryCollection Collection = new InventoryCollection();
|
|
||||||
// ret.Collection.Folders = new List<InventoryFolderBase>();
|
|
||||||
Collection.Folders = fold.RequestListOfFolders();
|
|
||||||
Collection.Items = fold.RequestListOfItems();
|
|
||||||
Collection.OwnerID = m_LibraryService.LibraryRootFolder.Owner;
|
|
||||||
Collection.FolderID = f.folder_id;
|
|
||||||
Collection.Version = fold.Version;
|
|
||||||
|
|
||||||
Collection.Descendents = Collection.Items.Count + Collection.Folders.Count;
|
|
||||||
total_folders += Collection.Folders.Count;
|
|
||||||
total_items += Collection.Items.Count;
|
|
||||||
result.Add(Collection);
|
|
||||||
|
|
||||||
//m_log.DebugFormat("[XXX]: Added libfolder {0} ({1}) {2}", ret.Collection.FolderID, ret.Collection.OwnerID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<InventoryCollection> Fetch(List<LLSDFetchInventoryDescendents> fetchFolders, List<UUID> bad_folders, ref int total_folders, ref int total_items)
|
|
||||||
{
|
|
||||||
//m_log.DebugFormat(
|
|
||||||
// "[WEB FETCH INV DESC HANDLER]: Fetching {0} folders for owner {1}", fetchFolders.Count, fetchFolders[0].owner_id);
|
|
||||||
|
|
||||||
// FIXME MAYBE: We're not handling sortOrder!
|
|
||||||
|
|
||||||
List<InventoryCollection> result = new List<InventoryCollection>(32);
|
|
||||||
List<LLSDFetchInventoryDescendents> libFolders = new List<LLSDFetchInventoryDescendents>(32);
|
|
||||||
List<LLSDFetchInventoryDescendents> otherFolders = new List<LLSDFetchInventoryDescendents>(32);
|
|
||||||
HashSet<UUID> libIDs = new HashSet<UUID>();
|
|
||||||
HashSet<UUID> otherIDs = new HashSet<UUID>();
|
|
||||||
|
|
||||||
bool dolib = (m_LibraryService != null && m_LibraryService.LibraryRootFolder != null);
|
|
||||||
UUID libOwner = UUID.Zero;
|
|
||||||
if(dolib)
|
|
||||||
libOwner = m_LibraryService.LibraryRootFolder.Owner;
|
|
||||||
|
|
||||||
// Filter folder Zero right here. Some viewers (Firestorm) send request for folder Zero, which doesn't make sense
|
|
||||||
// and can kill the sim (all root folders have parent_id Zero)
|
|
||||||
// send something.
|
|
||||||
bool doneZeroID = false;
|
|
||||||
foreach(LLSDFetchInventoryDescendents f in fetchFolders)
|
|
||||||
{
|
|
||||||
if (f.folder_id == UUID.Zero)
|
|
||||||
{
|
|
||||||
if(doneZeroID)
|
|
||||||
continue;
|
|
||||||
doneZeroID = true;
|
|
||||||
InventoryCollection Collection = new InventoryCollection();
|
|
||||||
Collection.OwnerID = f.owner_id;
|
|
||||||
Collection.Version = 0;
|
|
||||||
Collection.FolderID = f.folder_id;
|
|
||||||
Collection.Descendents = 0;
|
|
||||||
result.Add(Collection);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if(dolib && f.owner_id == libOwner)
|
|
||||||
{
|
|
||||||
if(libIDs.Contains(f.folder_id))
|
|
||||||
continue;
|
|
||||||
libIDs.Add(f.folder_id);
|
|
||||||
libFolders.Add(f);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if(otherIDs.Contains(f.folder_id))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
otherIDs.Add(f.folder_id);
|
|
||||||
otherFolders.Add(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
fetchFolders.Clear();
|
|
||||||
|
|
||||||
if(otherFolders.Count > 0)
|
|
||||||
{
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
//m_log.DebugFormat("[XXX]: {0}", string.Join(",", fids));
|
|
||||||
|
|
||||||
InventoryCollection[] fetchedContents = m_InventoryService.GetMultipleFoldersContent(otherFolders[0].owner_id, otherIDs.ToArray());
|
|
||||||
|
|
||||||
if (fetchedContents == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
if (fetchedContents.Length == 0)
|
|
||||||
{
|
|
||||||
foreach (LLSDFetchInventoryDescendents freq in otherFolders)
|
|
||||||
BadFolder(freq, null, bad_folders);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
i = 0;
|
|
||||||
// Do some post-processing. May need to fetch more from inv server for links
|
|
||||||
foreach (InventoryCollection contents in fetchedContents)
|
|
||||||
{
|
|
||||||
// Find the original request
|
|
||||||
LLSDFetchInventoryDescendents freq = otherFolders[i];
|
|
||||||
otherFolders[i]=null;
|
|
||||||
i++;
|
|
||||||
|
|
||||||
if (BadFolder(freq, contents, bad_folders))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if(!freq.fetch_folders)
|
|
||||||
contents.Folders.Clear();
|
|
||||||
if(!freq.fetch_items)
|
|
||||||
contents.Items.Clear();
|
|
||||||
|
|
||||||
contents.Descendents = contents.Items.Count + contents.Folders.Count;
|
|
||||||
|
|
||||||
// Next: link management
|
|
||||||
ProcessLinks(freq, contents);
|
|
||||||
|
|
||||||
total_folders += contents.Folders.Count;
|
|
||||||
total_items += contents.Items.Count;
|
|
||||||
result.Add(contents);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(dolib && libFolders.Count > 0)
|
|
||||||
{
|
|
||||||
AddLibraryFolders(libFolders, result, ref total_folders, ref total_items);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool BadFolder(LLSDFetchInventoryDescendents freq, InventoryCollection contents, List<UUID> bad_folders)
|
|
||||||
{
|
|
||||||
if (contents == null)
|
|
||||||
{
|
|
||||||
bad_folders.Add(freq.folder_id);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The inventory server isn't sending FolderID in the collection...
|
|
||||||
// Must fetch it individually
|
|
||||||
if (contents.FolderID == UUID.Zero)
|
|
||||||
{
|
|
||||||
InventoryFolderBase containingFolder = m_InventoryService.GetFolder(freq.owner_id, freq.folder_id);
|
|
||||||
if (containingFolder == null)
|
|
||||||
{
|
|
||||||
m_log.WarnFormat("[WEB FETCH INV DESC HANDLER]: Unable to fetch folder {0}", freq.folder_id);
|
|
||||||
bad_folders.Add(freq.folder_id);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
contents.FolderID = containingFolder.ID;
|
|
||||||
contents.OwnerID = containingFolder.Owner;
|
|
||||||
contents.Version = containingFolder.Version;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ProcessLinks(LLSDFetchInventoryDescendents freq, InventoryCollection contents)
|
|
||||||
{
|
|
||||||
if (contents.Items == null || contents.Items.Count == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// viewers are lasy and want a copy of the linked item sent before the link to it
|
|
||||||
|
|
||||||
// look for item links
|
|
||||||
List<UUID> itemIDs = new List<UUID>();
|
|
||||||
foreach (InventoryItemBase item in contents.Items)
|
|
||||||
{
|
|
||||||
//m_log.DebugFormat("[XXX]: {0} {1}", item.Name, item.AssetType);
|
|
||||||
if (item.AssetType == (int)AssetType.Link)
|
|
||||||
itemIDs.Add(item.AssetID);
|
|
||||||
}
|
|
||||||
|
|
||||||
// get the linked if any
|
|
||||||
if (itemIDs.Count > 0)
|
|
||||||
{
|
|
||||||
InventoryItemBase[] linked = m_InventoryService.GetMultipleItems(freq.owner_id, itemIDs.ToArray());
|
|
||||||
|
|
||||||
if (linked != null)
|
|
||||||
{
|
|
||||||
List<InventoryItemBase> linkedItems = new List<InventoryItemBase>(linked.Length);
|
|
||||||
// check for broken
|
|
||||||
foreach (InventoryItemBase linkedItem in linked)
|
|
||||||
{
|
|
||||||
// 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)
|
|
||||||
{
|
|
||||||
linkedItems.Add(linkedItem);
|
|
||||||
//m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Added {0} {1} {2}", linkedItem.Name, linkedItem.AssetType, linkedItem.Folder);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// insert them
|
|
||||||
if(linkedItems.Count > 0)
|
|
||||||
contents.Items.InsertRange(0, linkedItems);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,166 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
* * Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* * Neither the name of the OpenSimulator Project nor the
|
|
||||||
* names of its contributors may be used to endorse or promote products
|
|
||||||
* derived from this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
|
||||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
using System.Net;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Text;
|
|
||||||
using OpenMetaverse;
|
|
||||||
using OpenMetaverse.StructuredData;
|
|
||||||
using OpenSim.Framework;
|
|
||||||
using OpenSim.Framework.Servers.HttpServer;
|
|
||||||
using OpenSim.Services.Interfaces;
|
|
||||||
using OSDArray = OpenMetaverse.StructuredData.OSDArray;
|
|
||||||
using OSDMap = OpenMetaverse.StructuredData.OSDMap;
|
|
||||||
|
|
||||||
using log4net;
|
|
||||||
|
|
||||||
namespace OpenSim.Capabilities.Handlers
|
|
||||||
{
|
|
||||||
public class FetchInventory2Handler
|
|
||||||
{
|
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
|
||||||
|
|
||||||
private IInventoryService m_inventoryService;
|
|
||||||
private UUID m_agentID;
|
|
||||||
|
|
||||||
public FetchInventory2Handler(IInventoryService invService, UUID agentId)
|
|
||||||
{
|
|
||||||
m_inventoryService = invService;
|
|
||||||
m_agentID = agentId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string FetchInventoryRequest(string request, string path, string param, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
|
||||||
{
|
|
||||||
//m_log.DebugFormat("[FETCH INVENTORY HANDLER]: Received FetchInventory capability request {0}", request);
|
|
||||||
|
|
||||||
OSDMap requestmap = (OSDMap)OSDParser.DeserializeLLSDXml(Utils.StringToBytes(request));
|
|
||||||
OSDArray itemsRequested = (OSDArray)requestmap["items"];
|
|
||||||
|
|
||||||
UUID[] itemIDs = new UUID[itemsRequested.Count];
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
foreach (OSDMap osdItemId in itemsRequested)
|
|
||||||
{
|
|
||||||
itemIDs[i++] = osdItemId["item_id"].AsUUID();
|
|
||||||
}
|
|
||||||
|
|
||||||
InventoryItemBase[] items = null;
|
|
||||||
|
|
||||||
if (m_agentID != UUID.Zero)
|
|
||||||
{
|
|
||||||
items = m_inventoryService.GetMultipleItems(m_agentID, itemIDs);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
items = new InventoryItemBase[itemsRequested.Count];
|
|
||||||
foreach (UUID id in itemIDs)
|
|
||||||
items[i++] = m_inventoryService.GetItem(UUID.Zero, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
StringBuilder lsl = LLSDxmlEncode.Start(4096);
|
|
||||||
LLSDxmlEncode.AddMap(lsl);
|
|
||||||
|
|
||||||
if(m_agentID == UUID.Zero && items.Length > 0)
|
|
||||||
LLSDxmlEncode.AddElem("agent_id", items[0].Owner, lsl);
|
|
||||||
else
|
|
||||||
LLSDxmlEncode.AddElem("agent_id", m_agentID, lsl);
|
|
||||||
|
|
||||||
if(items == null || items.Length == 0)
|
|
||||||
{
|
|
||||||
LLSDxmlEncode.AddEmptyArray("items", lsl);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LLSDxmlEncode.AddArray("items", lsl);
|
|
||||||
foreach (InventoryItemBase item in items)
|
|
||||||
{
|
|
||||||
if (item != null)
|
|
||||||
item.ToLLSDxml(lsl, 0xff);
|
|
||||||
}
|
|
||||||
LLSDxmlEncode.AddEndArray(lsl);
|
|
||||||
}
|
|
||||||
|
|
||||||
LLSDxmlEncode.AddEndMap(lsl);
|
|
||||||
return LLSDxmlEncode.End(lsl);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void FetchInventorySimpleRequest(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, OSDMap requestmap, ExpiringKey<UUID> BadRequests)
|
|
||||||
{
|
|
||||||
//m_log.DebugFormat("[FETCH INVENTORY HANDLER]: Received FetchInventory capability request {0}", request);
|
|
||||||
|
|
||||||
if(BadRequests == null)
|
|
||||||
{
|
|
||||||
httpResponse.StatusCode = (int)HttpStatusCode.NotFound;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
OSDArray itemsRequested = (OSDArray)requestmap["items"];
|
|
||||||
|
|
||||||
UUID[] itemIDs = new UUID[itemsRequested.Count];
|
|
||||||
int i = 0;
|
|
||||||
foreach (OSDMap osdItemId in itemsRequested)
|
|
||||||
{
|
|
||||||
UUID id = osdItemId["item_id"].AsUUID();
|
|
||||||
if(!BadRequests.ContainsKey(id))
|
|
||||||
itemIDs[i++] = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
InventoryItemBase[] items = null;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// badrequests still not filled
|
|
||||||
items = m_inventoryService.GetMultipleItems(m_agentID, itemIDs);
|
|
||||||
}
|
|
||||||
catch{ }
|
|
||||||
|
|
||||||
StringBuilder lsl = LLSDxmlEncode.Start(4096);
|
|
||||||
LLSDxmlEncode.AddMap(lsl);
|
|
||||||
|
|
||||||
LLSDxmlEncode.AddElem("agent_id", m_agentID, lsl);
|
|
||||||
|
|
||||||
if (items == null || items.Length == 0)
|
|
||||||
{
|
|
||||||
LLSDxmlEncode.AddEmptyArray("items", lsl);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LLSDxmlEncode.AddArray("items", lsl);
|
|
||||||
foreach (InventoryItemBase item in items)
|
|
||||||
{
|
|
||||||
if (item != null)
|
|
||||||
item.ToLLSDxml(lsl, 0xff);
|
|
||||||
}
|
|
||||||
LLSDxmlEncode.AddEndArray(lsl);
|
|
||||||
}
|
|
||||||
|
|
||||||
LLSDxmlEncode.AddEndMap(lsl);
|
|
||||||
httpResponse.RawBuffer = Util.UTF8.GetBytes(LLSDxmlEncode.End(lsl));
|
|
||||||
httpResponse.StatusCode = (int)HttpStatusCode.OK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,170 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
* * Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* * Neither the name of the OpenSimulator Project nor the
|
|
||||||
* names of its contributors may be used to endorse or promote products
|
|
||||||
* derived from this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
|
||||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Net;
|
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using log4net;
|
|
||||||
using log4net.Config;
|
|
||||||
using NUnit.Framework;
|
|
||||||
using OpenMetaverse;
|
|
||||||
using OpenSim.Capabilities.Handlers;
|
|
||||||
using OpenSim.Framework;
|
|
||||||
using OpenSim.Framework.Servers.HttpServer;
|
|
||||||
using OpenSim.Region.Framework.Scenes;
|
|
||||||
using OpenSim.Services.Interfaces;
|
|
||||||
using OpenSim.Tests.Common;
|
|
||||||
|
|
||||||
namespace OpenSim.Capabilities.Handlers.FetchInventory.Tests
|
|
||||||
{
|
|
||||||
[TestFixture]
|
|
||||||
public class FetchInventory2HandlerTests : OpenSimTestCase
|
|
||||||
{
|
|
||||||
private UUID m_userID = UUID.Random();
|
|
||||||
private Scene m_scene;
|
|
||||||
private UUID m_rootFolderID;
|
|
||||||
private UUID m_notecardsFolder;
|
|
||||||
private UUID m_objectsFolder;
|
|
||||||
|
|
||||||
private void Init()
|
|
||||||
{
|
|
||||||
// Create an inventory that looks like this:
|
|
||||||
//
|
|
||||||
// /My Inventory
|
|
||||||
// <other system folders>
|
|
||||||
// /Objects
|
|
||||||
// Object 1
|
|
||||||
// Object 2
|
|
||||||
// Object 3
|
|
||||||
// /Notecards
|
|
||||||
// Notecard 1
|
|
||||||
// Notecard 2
|
|
||||||
// Notecard 3
|
|
||||||
// Notecard 4
|
|
||||||
// Notecard 5
|
|
||||||
|
|
||||||
m_scene = new SceneHelpers().SetupScene();
|
|
||||||
|
|
||||||
m_scene.InventoryService.CreateUserInventory(m_userID);
|
|
||||||
|
|
||||||
m_rootFolderID = m_scene.InventoryService.GetRootFolder(m_userID).ID;
|
|
||||||
|
|
||||||
InventoryFolderBase of = m_scene.InventoryService.GetFolderForType(m_userID, FolderType.Object);
|
|
||||||
m_objectsFolder = of.ID;
|
|
||||||
|
|
||||||
// Add 3 objects
|
|
||||||
InventoryItemBase item;
|
|
||||||
for (int i = 1; i <= 3; i++)
|
|
||||||
{
|
|
||||||
item = new InventoryItemBase(new UUID("b0000000-0000-0000-0000-0000000000b" + i), m_userID);
|
|
||||||
item.AssetID = UUID.Random();
|
|
||||||
item.AssetType = (int)AssetType.Object;
|
|
||||||
item.Folder = m_objectsFolder;
|
|
||||||
item.Name = "Object " + i;
|
|
||||||
m_scene.InventoryService.AddItem(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
InventoryFolderBase ncf = m_scene.InventoryService.GetFolderForType(m_userID, FolderType.Notecard);
|
|
||||||
m_notecardsFolder = ncf.ID;
|
|
||||||
|
|
||||||
// Add 5 notecards
|
|
||||||
for (int i = 1; i <= 5; i++)
|
|
||||||
{
|
|
||||||
item = new InventoryItemBase(new UUID("10000000-0000-0000-0000-00000000000" + i), m_userID);
|
|
||||||
item.AssetID = UUID.Random();
|
|
||||||
item.AssetType = (int)AssetType.Notecard;
|
|
||||||
item.Folder = m_notecardsFolder;
|
|
||||||
item.Name = "Notecard " + i;
|
|
||||||
m_scene.InventoryService.AddItem(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void Test_001_RequestOne()
|
|
||||||
{
|
|
||||||
TestHelpers.InMethod();
|
|
||||||
|
|
||||||
Init();
|
|
||||||
|
|
||||||
FetchInventory2Handler handler = new FetchInventory2Handler(m_scene.InventoryService, m_userID);
|
|
||||||
TestOSHttpRequest req = new TestOSHttpRequest();
|
|
||||||
TestOSHttpResponse resp = new TestOSHttpResponse();
|
|
||||||
|
|
||||||
string request = "<llsd><map><key>items</key><array><map><key>item_id</key><uuid>";
|
|
||||||
request += "10000000-0000-0000-0000-000000000001"; // Notecard 1
|
|
||||||
request += "</uuid></map></array></map></llsd>";
|
|
||||||
|
|
||||||
string llsdresponse = handler.FetchInventoryRequest(request, "/FETCH", string.Empty, req, resp);
|
|
||||||
|
|
||||||
Assert.That(llsdresponse != null, Is.True, "Incorrect null response");
|
|
||||||
Assert.That(llsdresponse != string.Empty, Is.True, "Incorrect empty response");
|
|
||||||
Assert.That(llsdresponse.Contains(m_userID.ToString()), Is.True, "Response should contain userID");
|
|
||||||
|
|
||||||
Assert.That(llsdresponse.Contains("10000000-0000-0000-0000-000000000001"), Is.True, "Response does not contain item uuid");
|
|
||||||
Assert.That(llsdresponse.Contains("Notecard 1"), Is.True, "Response does not contain item Name");
|
|
||||||
Console.WriteLine(llsdresponse);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void Test_002_RequestMany()
|
|
||||||
{
|
|
||||||
TestHelpers.InMethod();
|
|
||||||
|
|
||||||
Init();
|
|
||||||
|
|
||||||
FetchInventory2Handler handler = new FetchInventory2Handler(m_scene.InventoryService, m_userID);
|
|
||||||
TestOSHttpRequest req = new TestOSHttpRequest();
|
|
||||||
TestOSHttpResponse resp = new TestOSHttpResponse();
|
|
||||||
|
|
||||||
string request = "<llsd><map><key>items</key><array>";
|
|
||||||
request += "<map><key>item_id</key><uuid>10000000-0000-0000-0000-000000000001</uuid></map>"; // Notecard 1
|
|
||||||
request += "<map><key>item_id</key><uuid>10000000-0000-0000-0000-000000000002</uuid></map>"; // Notecard 2
|
|
||||||
request += "<map><key>item_id</key><uuid>10000000-0000-0000-0000-000000000003</uuid></map>"; // Notecard 3
|
|
||||||
request += "<map><key>item_id</key><uuid>10000000-0000-0000-0000-000000000004</uuid></map>"; // Notecard 4
|
|
||||||
request += "<map><key>item_id</key><uuid>10000000-0000-0000-0000-000000000005</uuid></map>"; // Notecard 5
|
|
||||||
request += "</array></map></llsd>";
|
|
||||||
|
|
||||||
string llsdresponse = handler.FetchInventoryRequest(request, "/FETCH", string.Empty, req, resp);
|
|
||||||
|
|
||||||
Assert.That(llsdresponse != null, Is.True, "Incorrect null response");
|
|
||||||
Assert.That(llsdresponse != string.Empty, Is.True, "Incorrect empty response");
|
|
||||||
Assert.That(llsdresponse.Contains(m_userID.ToString()), Is.True, "Response should contain userID");
|
|
||||||
|
|
||||||
Console.WriteLine(llsdresponse);
|
|
||||||
Assert.That(llsdresponse.Contains("10000000-0000-0000-0000-000000000001"), Is.True, "Response does not contain notecard 1");
|
|
||||||
Assert.That(llsdresponse.Contains("10000000-0000-0000-0000-000000000002"), Is.True, "Response does not contain notecard 2");
|
|
||||||
Assert.That(llsdresponse.Contains("10000000-0000-0000-0000-000000000003"), Is.True, "Response does not contain notecard 3");
|
|
||||||
Assert.That(llsdresponse.Contains("10000000-0000-0000-0000-000000000004"), Is.True, "Response does not contain notecard 4");
|
|
||||||
Assert.That(llsdresponse.Contains("10000000-0000-0000-0000-000000000005"), Is.True, "Response does not contain notecard 5");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,300 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
* * Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* * Neither the name of the OpenSimulator Project nor the
|
|
||||||
* names of its contributors may be used to endorse or promote products
|
|
||||||
* derived from this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
|
||||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.IO;
|
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using log4net;
|
|
||||||
using log4net.Config;
|
|
||||||
using NUnit.Framework;
|
|
||||||
using OpenMetaverse;
|
|
||||||
using OpenSim.Capabilities.Handlers;
|
|
||||||
using OpenSim.Framework;
|
|
||||||
using OpenSim.Framework.Servers.HttpServer;
|
|
||||||
using OpenSim.Region.Framework.Scenes;
|
|
||||||
using OpenSim.Services.Interfaces;
|
|
||||||
using OpenSim.Tests.Common;
|
|
||||||
|
|
||||||
namespace OpenSim.Capabilities.Handlers.FetchInventory.Tests
|
|
||||||
{
|
|
||||||
[TestFixture]
|
|
||||||
public class FetchInventoryDescendents2HandlerTests : OpenSimTestCase
|
|
||||||
{
|
|
||||||
private UUID m_userID = new UUID("00000000-0000-0000-0000-000000000001");
|
|
||||||
private Scene m_scene;
|
|
||||||
private UUID m_rootFolderID;
|
|
||||||
private int m_rootDescendents;
|
|
||||||
private UUID m_notecardsFolder;
|
|
||||||
private UUID m_objectsFolder;
|
|
||||||
|
|
||||||
private void Init()
|
|
||||||
{
|
|
||||||
// Create an inventory that looks like this:
|
|
||||||
//
|
|
||||||
// /My Inventory
|
|
||||||
// <other system folders>
|
|
||||||
// /Objects
|
|
||||||
// Some Object
|
|
||||||
// /Notecards
|
|
||||||
// Notecard 1
|
|
||||||
// Notecard 2
|
|
||||||
// /Test Folder
|
|
||||||
// Link to notecard -> /Notecards/Notecard 2
|
|
||||||
// Link to Objects folder -> /Objects
|
|
||||||
|
|
||||||
m_scene = new SceneHelpers().SetupScene();
|
|
||||||
|
|
||||||
m_scene.InventoryService.CreateUserInventory(m_userID);
|
|
||||||
|
|
||||||
m_rootFolderID = m_scene.InventoryService.GetRootFolder(m_userID).ID;
|
|
||||||
|
|
||||||
InventoryFolderBase of = m_scene.InventoryService.GetFolderForType(m_userID, FolderType.Object);
|
|
||||||
m_objectsFolder = of.ID;
|
|
||||||
|
|
||||||
// Add an object
|
|
||||||
InventoryItemBase item = new InventoryItemBase(new UUID("b0000000-0000-0000-0000-00000000000b"), m_userID);
|
|
||||||
item.AssetID = UUID.Random();
|
|
||||||
item.AssetType = (int)AssetType.Object;
|
|
||||||
item.Folder = m_objectsFolder;
|
|
||||||
item.Name = "Some Object";
|
|
||||||
m_scene.InventoryService.AddItem(item);
|
|
||||||
|
|
||||||
InventoryFolderBase ncf = m_scene.InventoryService.GetFolderForType(m_userID, FolderType.Notecard);
|
|
||||||
m_notecardsFolder = ncf.ID;
|
|
||||||
|
|
||||||
// Add a notecard
|
|
||||||
item = new InventoryItemBase(new UUID("10000000-0000-0000-0000-000000000001"), m_userID);
|
|
||||||
item.AssetID = UUID.Random();
|
|
||||||
item.AssetType = (int)AssetType.Notecard;
|
|
||||||
item.Folder = m_notecardsFolder;
|
|
||||||
item.Name = "Test Notecard 1";
|
|
||||||
m_scene.InventoryService.AddItem(item);
|
|
||||||
// Add another notecard
|
|
||||||
item.ID = new UUID("20000000-0000-0000-0000-000000000002");
|
|
||||||
item.AssetID = new UUID("a0000000-0000-0000-0000-00000000000a");
|
|
||||||
item.Name = "Test Notecard 2";
|
|
||||||
m_scene.InventoryService.AddItem(item);
|
|
||||||
|
|
||||||
// Add a folder
|
|
||||||
InventoryFolderBase folder = new InventoryFolderBase(new UUID("f0000000-0000-0000-0000-00000000000f"), "Test Folder", m_userID, m_rootFolderID);
|
|
||||||
folder.Type = (short)FolderType.None;
|
|
||||||
m_scene.InventoryService.AddFolder(folder);
|
|
||||||
|
|
||||||
// Add a link to notecard 2 in Test Folder
|
|
||||||
item.AssetID = item.ID; // use item ID of notecard 2
|
|
||||||
item.ID = new UUID("40000000-0000-0000-0000-000000000004");
|
|
||||||
item.AssetType = (int)AssetType.Link;
|
|
||||||
item.Folder = folder.ID;
|
|
||||||
item.Name = "Link to notecard";
|
|
||||||
m_scene.InventoryService.AddItem(item);
|
|
||||||
|
|
||||||
// Add a link to the Objects folder in Test Folder
|
|
||||||
item.AssetID = m_scene.InventoryService.GetFolderForType(m_userID, FolderType.Object).ID; // use item ID of Objects folder
|
|
||||||
item.ID = new UUID("50000000-0000-0000-0000-000000000005");
|
|
||||||
item.AssetType = (int)AssetType.LinkFolder;
|
|
||||||
item.Folder = folder.ID;
|
|
||||||
item.Name = "Link to Objects folder";
|
|
||||||
m_scene.InventoryService.AddItem(item);
|
|
||||||
|
|
||||||
InventoryCollection coll = m_scene.InventoryService.GetFolderContent(m_userID, m_rootFolderID);
|
|
||||||
m_rootDescendents = coll.Items.Count + coll.Folders.Count;
|
|
||||||
Console.WriteLine("Number of descendents: " + m_rootDescendents);
|
|
||||||
}
|
|
||||||
|
|
||||||
private string dorequest(FetchInvDescHandler handler, string request)
|
|
||||||
{
|
|
||||||
TestOSHttpRequest req = new TestOSHttpRequest();
|
|
||||||
TestOSHttpResponse resp = new TestOSHttpResponse();
|
|
||||||
using(ExpiringKey<UUID> bad = new ExpiringKey<UUID>(5000)) // bad but this is test
|
|
||||||
using (MemoryStream ms = new MemoryStream(Utils.StringToBytes(request), false))
|
|
||||||
{
|
|
||||||
req.InputStream = ms;
|
|
||||||
handler.FetchInventoryDescendentsRequest(req, resp, bad);
|
|
||||||
}
|
|
||||||
return Util.UTF8.GetString(resp.RawBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void Test_001_SimpleFolder()
|
|
||||||
{
|
|
||||||
TestHelpers.InMethod();
|
|
||||||
|
|
||||||
Init();
|
|
||||||
|
|
||||||
FetchInvDescHandler handler = new FetchInvDescHandler(m_scene.InventoryService, null, m_scene);
|
|
||||||
|
|
||||||
string request = "<llsd><map><key>folders</key><array><map><key>fetch_folders</key><integer>1</integer><key>fetch_items</key><boolean>1</boolean><key>folder_id</key><uuid>";
|
|
||||||
request += m_rootFolderID;
|
|
||||||
request += "</uuid><key>owner_id</key><uuid>";
|
|
||||||
request += m_userID.ToString();
|
|
||||||
request += "</uuid><key>sort_order</key><integer>1</integer></map></array></map></llsd>";
|
|
||||||
|
|
||||||
string llsdresponse = dorequest(handler, request);
|
|
||||||
|
|
||||||
Assert.That(llsdresponse != null, Is.True, "Incorrect null response");
|
|
||||||
Assert.That(llsdresponse != string.Empty, Is.True, "Incorrect empty response");
|
|
||||||
Assert.That(llsdresponse.Contains(m_userID.ToString()), Is.True, "Response should contain userID");
|
|
||||||
|
|
||||||
string descendents = "descendents</key><integer>" + m_rootDescendents + "</integer>";
|
|
||||||
Assert.That(llsdresponse.Contains(descendents), Is.True, "Incorrect number of descendents");
|
|
||||||
Console.WriteLine(llsdresponse);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void Test_002_MultipleFolders()
|
|
||||||
{
|
|
||||||
TestHelpers.InMethod();
|
|
||||||
|
|
||||||
FetchInvDescHandler handler = new FetchInvDescHandler(m_scene.InventoryService, null, m_scene);
|
|
||||||
|
|
||||||
string request = "<llsd><map><key>folders</key><array>";
|
|
||||||
request += "<map><key>fetch_folders</key><integer>1</integer><key>fetch_items</key><boolean>1</boolean><key>folder_id</key><uuid>";
|
|
||||||
request += m_rootFolderID;
|
|
||||||
request += "</uuid><key>owner_id</key><uuid>00000000-0000-0000-0000-000000000001</uuid><key>sort_order</key><integer>1</integer></map>";
|
|
||||||
request += "<map><key>fetch_folders</key><integer>1</integer><key>fetch_items</key><boolean>1</boolean><key>folder_id</key><uuid>";
|
|
||||||
request += m_notecardsFolder;
|
|
||||||
request += "</uuid><key>owner_id</key><uuid>00000000-0000-0000-0000-000000000001</uuid><key>sort_order</key><integer>1</integer></map>";
|
|
||||||
request += "</array></map></llsd>";
|
|
||||||
|
|
||||||
string llsdresponse = dorequest(handler, request);
|
|
||||||
Console.WriteLine(llsdresponse);
|
|
||||||
|
|
||||||
string descendents = "descendents</key><integer>" + m_rootDescendents + "</integer>";
|
|
||||||
Assert.That(llsdresponse.Contains(descendents), Is.True, "Incorrect number of descendents for root folder");
|
|
||||||
descendents = "descendents</key><integer>2</integer>";
|
|
||||||
Assert.That(llsdresponse.Contains(descendents), Is.True, "Incorrect number of descendents for Notecard folder");
|
|
||||||
|
|
||||||
Assert.That(llsdresponse.Contains("10000000-0000-0000-0000-000000000001"), Is.True, "Notecard 1 is missing from response");
|
|
||||||
Assert.That(llsdresponse.Contains("20000000-0000-0000-0000-000000000002"), Is.True, "Notecard 2 is missing from response");
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void Test_003_Links()
|
|
||||||
{
|
|
||||||
TestHelpers.InMethod();
|
|
||||||
|
|
||||||
FetchInvDescHandler handler = new FetchInvDescHandler(m_scene.InventoryService, null, m_scene);
|
|
||||||
|
|
||||||
string request = "<llsd><map><key>folders</key><array><map><key>fetch_folders</key><integer>1</integer><key>fetch_items</key><boolean>1</boolean><key>folder_id</key><uuid>";
|
|
||||||
request += "f0000000-0000-0000-0000-00000000000f";
|
|
||||||
request += "</uuid><key>owner_id</key><uuid>00000000-0000-0000-0000-000000000001</uuid><key>sort_order</key><integer>1</integer></map></array></map></llsd>";
|
|
||||||
|
|
||||||
string llsdresponse = dorequest(handler, request);
|
|
||||||
Console.WriteLine(llsdresponse);
|
|
||||||
|
|
||||||
string descendents = "descendents</key><integer>2</integer>";
|
|
||||||
Assert.That(llsdresponse.Contains(descendents), Is.True, "Incorrect number of descendents for Test Folder");
|
|
||||||
|
|
||||||
// Make sure that the note card link is included
|
|
||||||
Assert.That(llsdresponse.Contains("Link to notecard"), Is.True, "Link to notecard is missing");
|
|
||||||
|
|
||||||
//Make sure the notecard item itself is included
|
|
||||||
Assert.That(llsdresponse.Contains("Test Notecard 2"), Is.True, "Notecard 2 item (the source) is missing");
|
|
||||||
|
|
||||||
// Make sure that the source item is before the link item
|
|
||||||
int pos1 = llsdresponse.IndexOf("Test Notecard 2");
|
|
||||||
int pos2 = llsdresponse.IndexOf("Link to notecard");
|
|
||||||
Assert.Less(pos1, pos2, "Source of link is after link");
|
|
||||||
|
|
||||||
// Make sure the folder link is included
|
|
||||||
Assert.That(llsdresponse.Contains("Link to Objects folder"), Is.True, "Link to Objects folder is missing");
|
|
||||||
|
|
||||||
/* contents of link folder are not supposed to be listed
|
|
||||||
// Make sure the objects inside the Objects folder are included
|
|
||||||
// Note: I'm not entirely sure this is needed, but that's what I found in the implementation
|
|
||||||
Assert.That(llsdresponse.Contains("Some Object"), Is.True, "Some Object item (contents of the source) is missing");
|
|
||||||
*/
|
|
||||||
// Make sure that the source item is before the link item
|
|
||||||
pos1 = llsdresponse.IndexOf("Some Object");
|
|
||||||
pos2 = llsdresponse.IndexOf("Link to Objects folder");
|
|
||||||
Assert.Less(pos1, pos2, "Contents of source of folder link is after folder link");
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void Test_004_DuplicateFolders()
|
|
||||||
{
|
|
||||||
TestHelpers.InMethod();
|
|
||||||
|
|
||||||
FetchInvDescHandler handler = new FetchInvDescHandler(m_scene.InventoryService, null, m_scene);
|
|
||||||
|
|
||||||
string request = "<llsd><map><key>folders</key><array>";
|
|
||||||
request += "<map><key>fetch_folders</key><integer>1</integer><key>fetch_items</key><boolean>1</boolean><key>folder_id</key><uuid>";
|
|
||||||
request += m_rootFolderID;
|
|
||||||
request += "</uuid><key>owner_id</key><uuid>00000000-0000-0000-0000-000000000000</uuid><key>sort_order</key><integer>1</integer></map>";
|
|
||||||
request += "<map><key>fetch_folders</key><integer>1</integer><key>fetch_items</key><boolean>1</boolean><key>folder_id</key><uuid>";
|
|
||||||
request += m_notecardsFolder;
|
|
||||||
request += "</uuid><key>owner_id</key><uuid>00000000-0000-0000-0000-000000000000</uuid><key>sort_order</key><integer>1</integer></map>";
|
|
||||||
request += "<map><key>fetch_folders</key><integer>1</integer><key>fetch_items</key><boolean>1</boolean><key>folder_id</key><uuid>";
|
|
||||||
request += m_rootFolderID;
|
|
||||||
request += "</uuid><key>owner_id</key><uuid>00000000-0000-0000-0000-000000000000</uuid><key>sort_order</key><integer>1</integer></map>";
|
|
||||||
request += "<map><key>fetch_folders</key><integer>1</integer><key>fetch_items</key><boolean>1</boolean><key>folder_id</key><uuid>";
|
|
||||||
request += m_notecardsFolder;
|
|
||||||
request += "</uuid><key>owner_id</key><uuid>00000000-0000-0000-0000-000000000000</uuid><key>sort_order</key><integer>1</integer></map>";
|
|
||||||
request += "</array></map></llsd>";
|
|
||||||
|
|
||||||
string llsdresponse = dorequest(handler, request);
|
|
||||||
Console.WriteLine(llsdresponse);
|
|
||||||
|
|
||||||
string root_folder = "<key>folder_id</key><uuid>" + m_rootFolderID + "</uuid>";
|
|
||||||
string notecards_folder = "<key>folder_id</key><uuid>" + m_notecardsFolder + "</uuid>";
|
|
||||||
|
|
||||||
Assert.That(llsdresponse.Contains(root_folder), "Missing root folder");
|
|
||||||
Assert.That(llsdresponse.Contains(notecards_folder), "Missing notecards folder");
|
|
||||||
int count = Regex.Matches(llsdresponse, root_folder).Count;
|
|
||||||
Assert.AreEqual(1, count, "More than 1 root folder in response");
|
|
||||||
count = Regex.Matches(llsdresponse, notecards_folder).Count;
|
|
||||||
Assert.AreEqual(2, count, "More than 1 notecards folder in response"); // Notecards will also be under root, so 2
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void Test_005_FolderZero()
|
|
||||||
{
|
|
||||||
|
|
||||||
TestHelpers.InMethod();
|
|
||||||
|
|
||||||
Init();
|
|
||||||
|
|
||||||
FetchInvDescHandler handler = new FetchInvDescHandler(m_scene.InventoryService, null, m_scene);
|
|
||||||
|
|
||||||
string request = "<llsd><map><key>folders</key><array><map><key>fetch_folders</key><integer>1</integer><key>fetch_items</key><boolean>1</boolean><key>folder_id</key><uuid>";
|
|
||||||
request += UUID.Zero;
|
|
||||||
request += "</uuid><key>owner_id</key><uuid>00000000-0000-0000-0000-000000000000</uuid><key>sort_order</key><integer>1</integer></map></array></map></llsd>";
|
|
||||||
|
|
||||||
string llsdresponse = dorequest(handler, request);
|
|
||||||
|
|
||||||
Assert.That(llsdresponse != null, Is.True, "Incorrect null response");
|
|
||||||
Assert.That(llsdresponse != string.Empty, Is.True, "Incorrect empty response");
|
|
||||||
// we do return a answer now
|
|
||||||
//Assert.That(llsdresponse.Contains("bad_folders</key><array><uuid>00000000-0000-0000-0000-000000000000"), Is.True, "Folder Zero should be a bad folder");
|
|
||||||
|
|
||||||
Console.WriteLine(llsdresponse);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,124 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSimulator Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
|
using log4net;
|
||||||
|
using Nini.Config;
|
||||||
|
using OpenMetaverse;
|
||||||
|
using OpenMetaverse.StructuredData;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Framework.Capabilities;
|
||||||
|
using OpenSim.Region.Framework.Interfaces;
|
||||||
|
using OpenSim.Framework.Servers.HttpServer;
|
||||||
|
using OpenSim.Services.Interfaces;
|
||||||
|
using Caps = OpenSim.Framework.Capabilities.Caps;
|
||||||
|
using OSDArray = OpenMetaverse.StructuredData.OSDArray;
|
||||||
|
using OSDMap = OpenMetaverse.StructuredData.OSDMap;
|
||||||
|
|
||||||
|
namespace OpenSim.Capabilities.Handlers
|
||||||
|
{
|
||||||
|
public class FetchInventory2Handler
|
||||||
|
{
|
||||||
|
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
private IInventoryService m_inventoryService;
|
||||||
|
|
||||||
|
public FetchInventory2Handler(IInventoryService invService)
|
||||||
|
{
|
||||||
|
m_inventoryService = invService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string FetchInventoryRequest(string request, string path, string param, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
||||||
|
{
|
||||||
|
// m_log.DebugFormat("[FETCH INVENTORY HANDLER]: Received FetchInventory capabilty request");
|
||||||
|
|
||||||
|
OSDMap requestmap = (OSDMap)OSDParser.DeserializeLLSDXml(Utils.StringToBytes(request));
|
||||||
|
OSDArray itemsRequested = (OSDArray)requestmap["items"];
|
||||||
|
|
||||||
|
string reply;
|
||||||
|
LLSDFetchInventory llsdReply = new LLSDFetchInventory();
|
||||||
|
|
||||||
|
foreach (OSDMap osdItemId in itemsRequested)
|
||||||
|
{
|
||||||
|
UUID itemId = osdItemId["item_id"].AsUUID();
|
||||||
|
|
||||||
|
InventoryItemBase item = m_inventoryService.GetItem(new InventoryItemBase(itemId));
|
||||||
|
|
||||||
|
if (item != null)
|
||||||
|
{
|
||||||
|
// We don't know the agent that this request belongs to so we'll use the agent id of the item
|
||||||
|
// which will be the same for all items.
|
||||||
|
llsdReply.agent_id = item.Owner;
|
||||||
|
|
||||||
|
llsdReply.items.Array.Add(ConvertInventoryItem(item));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
reply = LLSDHelpers.SerialiseLLSDReply(llsdReply);
|
||||||
|
|
||||||
|
return reply;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Convert an internal inventory item object into an LLSD object.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="invItem"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private LLSDInventoryItem ConvertInventoryItem(InventoryItemBase invItem)
|
||||||
|
{
|
||||||
|
LLSDInventoryItem llsdItem = new LLSDInventoryItem();
|
||||||
|
llsdItem.asset_id = invItem.AssetID;
|
||||||
|
llsdItem.created_at = invItem.CreationDate;
|
||||||
|
llsdItem.desc = invItem.Description;
|
||||||
|
llsdItem.flags = (int)invItem.Flags;
|
||||||
|
llsdItem.item_id = invItem.ID;
|
||||||
|
llsdItem.name = invItem.Name;
|
||||||
|
llsdItem.parent_id = invItem.Folder;
|
||||||
|
llsdItem.type = invItem.AssetType;
|
||||||
|
llsdItem.inv_type = invItem.InvType;
|
||||||
|
|
||||||
|
llsdItem.permissions = new LLSDPermissions();
|
||||||
|
llsdItem.permissions.creator_id = invItem.CreatorIdAsUuid;
|
||||||
|
llsdItem.permissions.base_mask = (int)invItem.CurrentPermissions;
|
||||||
|
llsdItem.permissions.everyone_mask = (int)invItem.EveryOnePermissions;
|
||||||
|
llsdItem.permissions.group_id = invItem.GroupID;
|
||||||
|
llsdItem.permissions.group_mask = (int)invItem.GroupPermissions;
|
||||||
|
llsdItem.permissions.is_owner_group = invItem.GroupOwned;
|
||||||
|
llsdItem.permissions.next_owner_mask = (int)invItem.NextPermissions;
|
||||||
|
llsdItem.permissions.owner_id = invItem.Owner;
|
||||||
|
llsdItem.permissions.owner_mask = (int)invItem.CurrentPermissions;
|
||||||
|
llsdItem.sale_info = new LLSDSaleInfo();
|
||||||
|
llsdItem.sale_info.sale_price = invItem.SalePrice;
|
||||||
|
llsdItem.sale_info.sale_type = invItem.SaleType;
|
||||||
|
|
||||||
|
return llsdItem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -61,7 +61,7 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
if (m_InventoryService == null)
|
if (m_InventoryService == null)
|
||||||
throw new Exception(String.Format("Failed to load InventoryService from {0}; config is {1}", invService, m_ConfigName));
|
throw new Exception(String.Format("Failed to load InventoryService from {0}; config is {1}", invService, m_ConfigName));
|
||||||
|
|
||||||
FetchInventory2Handler fiHandler = new FetchInventory2Handler(m_InventoryService, UUID.Zero);
|
FetchInventory2Handler fiHandler = new FetchInventory2Handler(m_InventoryService);
|
||||||
IRequestHandler reqHandler
|
IRequestHandler reqHandler
|
||||||
= new RestStreamHandler(
|
= new RestStreamHandler(
|
||||||
"POST", "/CAPS/FetchInventory/", fiHandler.FetchInventoryRequest, "FetchInventory", null);
|
"POST", "/CAPS/FetchInventory/", fiHandler.FetchInventoryRequest, "FetchInventory", null);
|
|
@ -0,0 +1,446 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSimulator Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
|
using log4net;
|
||||||
|
using Nini.Config;
|
||||||
|
using OpenMetaverse;
|
||||||
|
using OpenMetaverse.StructuredData;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Framework.Capabilities;
|
||||||
|
using OpenSim.Region.Framework.Interfaces;
|
||||||
|
using OpenSim.Framework.Servers.HttpServer;
|
||||||
|
using OpenSim.Services.Interfaces;
|
||||||
|
using Caps = OpenSim.Framework.Capabilities.Caps;
|
||||||
|
|
||||||
|
namespace OpenSim.Capabilities.Handlers
|
||||||
|
{
|
||||||
|
public class FetchInvDescHandler
|
||||||
|
{
|
||||||
|
private static readonly ILog m_log =
|
||||||
|
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
private IInventoryService m_InventoryService;
|
||||||
|
private ILibraryService m_LibraryService;
|
||||||
|
// private object m_fetchLock = new Object();
|
||||||
|
|
||||||
|
public FetchInvDescHandler(IInventoryService invService, ILibraryService libService)
|
||||||
|
{
|
||||||
|
m_InventoryService = invService;
|
||||||
|
m_LibraryService = libService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string FetchInventoryDescendentsRequest(string request, string path, string param, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
||||||
|
{
|
||||||
|
// lock (m_fetchLock)
|
||||||
|
// {
|
||||||
|
// m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Received request {0}", request);
|
||||||
|
|
||||||
|
// nasty temporary hack here, the linden client falsely
|
||||||
|
// identifies the uuid 00000000-0000-0000-0000-000000000000
|
||||||
|
// as a string which breaks us
|
||||||
|
//
|
||||||
|
// correctly mark it as a uuid
|
||||||
|
//
|
||||||
|
request = request.Replace("<string>00000000-0000-0000-0000-000000000000</string>", "<uuid>00000000-0000-0000-0000-000000000000</uuid>");
|
||||||
|
|
||||||
|
// another hack <integer>1</integer> results in a
|
||||||
|
// System.ArgumentException: Object type System.Int32 cannot
|
||||||
|
// be converted to target type: System.Boolean
|
||||||
|
//
|
||||||
|
request = request.Replace("<key>fetch_folders</key><integer>0</integer>", "<key>fetch_folders</key><boolean>0</boolean>");
|
||||||
|
request = request.Replace("<key>fetch_folders</key><integer>1</integer>", "<key>fetch_folders</key><boolean>1</boolean>");
|
||||||
|
|
||||||
|
Hashtable hash = new Hashtable();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request));
|
||||||
|
}
|
||||||
|
catch (LLSD.LLSDParseException e)
|
||||||
|
{
|
||||||
|
m_log.ErrorFormat("[WEB FETCH INV DESC HANDLER]: Fetch error: {0}{1}" + e.Message, e.StackTrace);
|
||||||
|
m_log.Error("Request: " + request);
|
||||||
|
}
|
||||||
|
|
||||||
|
ArrayList foldersrequested = (ArrayList)hash["folders"];
|
||||||
|
|
||||||
|
string response = "";
|
||||||
|
|
||||||
|
for (int i = 0; i < foldersrequested.Count; i++)
|
||||||
|
{
|
||||||
|
string inventoryitemstr = "";
|
||||||
|
Hashtable inventoryhash = (Hashtable)foldersrequested[i];
|
||||||
|
|
||||||
|
LLSDFetchInventoryDescendents llsdRequest = new LLSDFetchInventoryDescendents();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
LLSDHelpers.DeserialiseOSDMap(inventoryhash, llsdRequest);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
m_log.Debug("[WEB FETCH INV DESC HANDLER]: caught exception doing OSD deserialize" + e);
|
||||||
|
}
|
||||||
|
LLSDInventoryDescendents reply = FetchInventoryReply(llsdRequest);
|
||||||
|
|
||||||
|
inventoryitemstr = LLSDHelpers.SerialiseLLSDReply(reply);
|
||||||
|
inventoryitemstr = inventoryitemstr.Replace("<llsd><map><key>folders</key><array>", "");
|
||||||
|
inventoryitemstr = inventoryitemstr.Replace("</array></map></llsd>", "");
|
||||||
|
|
||||||
|
response += inventoryitemstr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response.Length == 0)
|
||||||
|
{
|
||||||
|
// Ter-guess: If requests fail a lot, the client seems to stop requesting descendants.
|
||||||
|
// Therefore, I'm concluding that the client only has so many threads available to do requests
|
||||||
|
// and when a thread stalls.. is stays stalled.
|
||||||
|
// Therefore we need to return something valid
|
||||||
|
response = "<llsd><map><key>folders</key><array /></map></llsd>";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
response = "<llsd><map><key>folders</key><array>" + response + "</array></map></llsd>";
|
||||||
|
}
|
||||||
|
|
||||||
|
// m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Replying to CAPS fetch inventory request");
|
||||||
|
//m_log.Debug("[WEB FETCH INV DESC HANDLER] "+response);
|
||||||
|
|
||||||
|
return response;
|
||||||
|
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Construct an LLSD reply packet to a CAPS inventory request
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="invFetch"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private LLSDInventoryDescendents FetchInventoryReply(LLSDFetchInventoryDescendents invFetch)
|
||||||
|
{
|
||||||
|
LLSDInventoryDescendents reply = new LLSDInventoryDescendents();
|
||||||
|
LLSDInventoryFolderContents contents = new LLSDInventoryFolderContents();
|
||||||
|
contents.agent_id = invFetch.owner_id;
|
||||||
|
contents.owner_id = invFetch.owner_id;
|
||||||
|
contents.folder_id = invFetch.folder_id;
|
||||||
|
|
||||||
|
reply.folders.Array.Add(contents);
|
||||||
|
InventoryCollection inv = new InventoryCollection();
|
||||||
|
inv.Folders = new List<InventoryFolderBase>();
|
||||||
|
inv.Items = new List<InventoryItemBase>();
|
||||||
|
int version = 0;
|
||||||
|
int descendents = 0;
|
||||||
|
|
||||||
|
inv
|
||||||
|
= Fetch(
|
||||||
|
invFetch.owner_id, invFetch.folder_id, invFetch.owner_id,
|
||||||
|
invFetch.fetch_folders, invFetch.fetch_items, invFetch.sort_order, out version, out descendents);
|
||||||
|
|
||||||
|
if (inv != null && inv.Folders != null)
|
||||||
|
{
|
||||||
|
foreach (InventoryFolderBase invFolder in inv.Folders)
|
||||||
|
{
|
||||||
|
contents.categories.Array.Add(ConvertInventoryFolder(invFolder));
|
||||||
|
}
|
||||||
|
|
||||||
|
descendents += inv.Folders.Count;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inv != null && inv.Items != null)
|
||||||
|
{
|
||||||
|
foreach (InventoryItemBase invItem in inv.Items)
|
||||||
|
{
|
||||||
|
contents.items.Array.Add(ConvertInventoryItem(invItem));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
contents.descendents = descendents;
|
||||||
|
contents.version = version;
|
||||||
|
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[WEB FETCH INV DESC HANDLER]: Replying to request for folder {0} (fetch items {1}, fetch folders {2}) with {3} items and {4} folders for agent {5}",
|
||||||
|
// invFetch.folder_id,
|
||||||
|
// invFetch.fetch_items,
|
||||||
|
// invFetch.fetch_folders,
|
||||||
|
// contents.items.Array.Count,
|
||||||
|
// contents.categories.Array.Count,
|
||||||
|
// invFetch.owner_id);
|
||||||
|
|
||||||
|
return reply;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handle the caps inventory descendents fetch.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="agentID"></param>
|
||||||
|
/// <param name="folderID"></param>
|
||||||
|
/// <param name="ownerID"></param>
|
||||||
|
/// <param name="fetchFolders"></param>
|
||||||
|
/// <param name="fetchItems"></param>
|
||||||
|
/// <param name="sortOrder"></param>
|
||||||
|
/// <param name="version"></param>
|
||||||
|
/// <returns>An empty InventoryCollection if the inventory look up failed</returns>
|
||||||
|
private InventoryCollection Fetch(
|
||||||
|
UUID agentID, UUID folderID, UUID ownerID,
|
||||||
|
bool fetchFolders, bool fetchItems, int sortOrder, out int version, out int descendents)
|
||||||
|
{
|
||||||
|
//m_log.DebugFormat(
|
||||||
|
// "[WEB FETCH INV DESC HANDLER]: Fetching folders ({0}), items ({1}) from {2} for agent {3}",
|
||||||
|
// fetchFolders, fetchItems, folderID, agentID);
|
||||||
|
|
||||||
|
// FIXME MAYBE: We're not handling sortOrder!
|
||||||
|
|
||||||
|
version = 0;
|
||||||
|
descendents = 0;
|
||||||
|
|
||||||
|
InventoryFolderImpl fold;
|
||||||
|
if (m_LibraryService != null && m_LibraryService.LibraryRootFolder != null && agentID == m_LibraryService.LibraryRootFolder.Owner)
|
||||||
|
{
|
||||||
|
if ((fold = m_LibraryService.LibraryRootFolder.FindFolder(folderID)) != null)
|
||||||
|
{
|
||||||
|
InventoryCollection ret = new InventoryCollection();
|
||||||
|
ret.Folders = new List<InventoryFolderBase>();
|
||||||
|
ret.Items = fold.RequestListOfItems();
|
||||||
|
descendents = ret.Folders.Count + ret.Items.Count;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
InventoryCollection contents = new InventoryCollection();
|
||||||
|
|
||||||
|
if (folderID != UUID.Zero)
|
||||||
|
{
|
||||||
|
InventoryCollection fetchedContents = m_InventoryService.GetFolderContent(agentID, folderID);
|
||||||
|
|
||||||
|
if (fetchedContents == null)
|
||||||
|
{
|
||||||
|
m_log.WarnFormat("[WEB FETCH INV DESC HANDLER]: Could not get contents of folder {0} for user {1}", folderID, agentID);
|
||||||
|
return contents;
|
||||||
|
}
|
||||||
|
|
||||||
|
contents = fetchedContents;
|
||||||
|
InventoryFolderBase containingFolder = new InventoryFolderBase();
|
||||||
|
containingFolder.ID = folderID;
|
||||||
|
containingFolder.Owner = agentID;
|
||||||
|
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> itemsToReturn = contents.Items;
|
||||||
|
List<InventoryItemBase> originalItems = new List<InventoryItemBase>(itemsToReturn);
|
||||||
|
|
||||||
|
// descendents must only include the links, not the linked items we add
|
||||||
|
descendents = originalItems.Count;
|
||||||
|
|
||||||
|
// Add target items for links in this folder before the links themselves.
|
||||||
|
foreach (InventoryItemBase item in originalItems)
|
||||||
|
{
|
||||||
|
if (item.AssetType == (int)AssetType.Link)
|
||||||
|
{
|
||||||
|
InventoryItemBase linkedItem = m_InventoryService.GetItem(new InventoryItemBase(item.AssetID));
|
||||||
|
|
||||||
|
// Take care of genuinely broken links where the target doesn't exist
|
||||||
|
// HACK: Also, don't follow up links that just point to other links. In theory this is legitimate,
|
||||||
|
// but no viewer has been observed to set these up and this is the lazy way of avoiding cycles
|
||||||
|
// rather than having to keep track of every folder requested in the recursion.
|
||||||
|
if (linkedItem != null && linkedItem.AssetType != (int)AssetType.Link)
|
||||||
|
itemsToReturn.Insert(0, linkedItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now scan for folder links and insert the items they target and those links at the head of the return data
|
||||||
|
foreach (InventoryItemBase item in originalItems)
|
||||||
|
{
|
||||||
|
if (item.AssetType == (int)AssetType.LinkFolder)
|
||||||
|
{
|
||||||
|
InventoryCollection linkedFolderContents = m_InventoryService.GetFolderContent(ownerID, item.AssetID);
|
||||||
|
List<InventoryItemBase> links = linkedFolderContents.Items;
|
||||||
|
|
||||||
|
itemsToReturn.InsertRange(0, links);
|
||||||
|
|
||||||
|
foreach (InventoryItemBase link in linkedFolderContents.Items)
|
||||||
|
{
|
||||||
|
// Take care of genuinely broken links where the target doesn't exist
|
||||||
|
// HACK: Also, don't follow up links that just point to other links. In theory this is legitimate,
|
||||||
|
// but no viewer has been observed to set these up and this is the lazy way of avoiding cycles
|
||||||
|
// rather than having to keep track of every folder requested in the recursion.
|
||||||
|
if (link != null)
|
||||||
|
{
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[WEB FETCH INV DESC HANDLER]: Adding item {0} {1} from folder {2} linked from {3}",
|
||||||
|
// link.Name, (AssetType)link.AssetType, item.AssetID, containingFolder.Name);
|
||||||
|
|
||||||
|
InventoryItemBase linkedItem
|
||||||
|
= m_InventoryService.GetItem(new InventoryItemBase(link.AssetID));
|
||||||
|
|
||||||
|
if (linkedItem != null)
|
||||||
|
itemsToReturn.Insert(0, linkedItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// foreach (InventoryItemBase item in contents.Items)
|
||||||
|
// {
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[WEB FETCH INV DESC HANDLER]: Returning item {0}, type {1}, parent {2} in {3} {4}",
|
||||||
|
// item.Name, (AssetType)item.AssetType, item.Folder, containingFolder.Name, containingFolder.ID);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// =====
|
||||||
|
|
||||||
|
//
|
||||||
|
// foreach (InventoryItemBase linkedItem in linkedItemsToAdd)
|
||||||
|
// {
|
||||||
|
// 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
|
||||||
|
{
|
||||||
|
// Lost items don't really need a version
|
||||||
|
version = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return contents;
|
||||||
|
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Convert an internal inventory folder object into an LLSD object.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="invFolder"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private LLSDInventoryFolder ConvertInventoryFolder(InventoryFolderBase invFolder)
|
||||||
|
{
|
||||||
|
LLSDInventoryFolder llsdFolder = new LLSDInventoryFolder();
|
||||||
|
llsdFolder.folder_id = invFolder.ID;
|
||||||
|
llsdFolder.parent_id = invFolder.ParentID;
|
||||||
|
llsdFolder.name = invFolder.Name;
|
||||||
|
llsdFolder.type = invFolder.Type;
|
||||||
|
llsdFolder.preferred_type = -1;
|
||||||
|
|
||||||
|
return llsdFolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Convert an internal inventory item object into an LLSD object.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="invItem"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private LLSDInventoryItem ConvertInventoryItem(InventoryItemBase invItem)
|
||||||
|
{
|
||||||
|
LLSDInventoryItem llsdItem = new LLSDInventoryItem();
|
||||||
|
llsdItem.asset_id = invItem.AssetID;
|
||||||
|
llsdItem.created_at = invItem.CreationDate;
|
||||||
|
llsdItem.desc = invItem.Description;
|
||||||
|
llsdItem.flags = (int)invItem.Flags;
|
||||||
|
llsdItem.item_id = invItem.ID;
|
||||||
|
llsdItem.name = invItem.Name;
|
||||||
|
llsdItem.parent_id = invItem.Folder;
|
||||||
|
llsdItem.type = invItem.AssetType;
|
||||||
|
llsdItem.inv_type = invItem.InvType;
|
||||||
|
|
||||||
|
llsdItem.permissions = new LLSDPermissions();
|
||||||
|
llsdItem.permissions.creator_id = invItem.CreatorIdAsUuid;
|
||||||
|
llsdItem.permissions.base_mask = (int)invItem.CurrentPermissions;
|
||||||
|
llsdItem.permissions.everyone_mask = (int)invItem.EveryOnePermissions;
|
||||||
|
llsdItem.permissions.group_id = invItem.GroupID;
|
||||||
|
llsdItem.permissions.group_mask = (int)invItem.GroupPermissions;
|
||||||
|
llsdItem.permissions.is_owner_group = invItem.GroupOwned;
|
||||||
|
llsdItem.permissions.next_owner_mask = (int)invItem.NextPermissions;
|
||||||
|
llsdItem.permissions.owner_id = invItem.Owner;
|
||||||
|
llsdItem.permissions.owner_mask = (int)invItem.CurrentPermissions;
|
||||||
|
llsdItem.sale_info = new LLSDSaleInfo();
|
||||||
|
llsdItem.sale_info.sale_price = invItem.SalePrice;
|
||||||
|
llsdItem.sale_info.sale_type = invItem.SaleType;
|
||||||
|
|
||||||
|
return llsdItem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -29,12 +29,9 @@ using System;
|
||||||
using Nini.Config;
|
using Nini.Config;
|
||||||
using OpenSim.Server.Base;
|
using OpenSim.Server.Base;
|
||||||
using OpenSim.Services.Interfaces;
|
using OpenSim.Services.Interfaces;
|
||||||
using OpenSim.Framework;
|
|
||||||
using OpenSim.Framework.Servers.HttpServer;
|
using OpenSim.Framework.Servers.HttpServer;
|
||||||
using OpenSim.Server.Handlers.Base;
|
using OpenSim.Server.Handlers.Base;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
using OpenMetaverse.StructuredData;
|
|
||||||
|
|
||||||
|
|
||||||
namespace OpenSim.Capabilities.Handlers
|
namespace OpenSim.Capabilities.Handlers
|
||||||
{
|
{
|
||||||
|
@ -70,16 +67,16 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
m_LibraryService =
|
m_LibraryService =
|
||||||
ServerUtils.LoadPlugin<ILibraryService>(libService, args);
|
ServerUtils.LoadPlugin<ILibraryService>(libService, args);
|
||||||
|
|
||||||
ExpiringKey<UUID> m_badRequests = new ExpiringKey<UUID>(30000);
|
FetchInvDescHandler webFetchHandler = new FetchInvDescHandler(m_InventoryService, m_LibraryService);
|
||||||
|
IRequestHandler reqHandler
|
||||||
FetchInvDescHandler webFetchHandler = new FetchInvDescHandler(m_InventoryService, m_LibraryService, null);
|
= new RestStreamHandler(
|
||||||
ISimpleStreamHandler reqHandler
|
"POST",
|
||||||
= new SimpleStreamHandler("/CAPS/WebFetchInvDesc/", delegate(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
"/CAPS/WebFetchInvDesc/" /*+ UUID.Random()*/,
|
||||||
{
|
webFetchHandler.FetchInventoryDescendentsRequest,
|
||||||
webFetchHandler.FetchInventoryDescendentsRequest(httpRequest, httpResponse, m_badRequests);
|
"FetchInvDescendents",
|
||||||
});
|
null);
|
||||||
|
server.AddStreamHandler(reqHandler);
|
||||||
server.AddSimpleStreamHandler(reqHandler);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,190 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
* * Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* * Neither the name of the OpenSimulator Project nor the
|
|
||||||
* names of its contributors may be used to endorse or promote products
|
|
||||||
* derived from this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
|
||||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Net;
|
|
||||||
using System.Reflection;
|
|
||||||
using log4net;
|
|
||||||
using Nini.Config;
|
|
||||||
using OpenMetaverse;
|
|
||||||
using OpenMetaverse.StructuredData;
|
|
||||||
using OpenSim.Framework;
|
|
||||||
using OpenSim.Framework.Servers;
|
|
||||||
using OpenSim.Framework.Servers.HttpServer;
|
|
||||||
using OpenSim.Services.Interfaces;
|
|
||||||
using Caps = OpenSim.Framework.Capabilities.Caps;
|
|
||||||
|
|
||||||
namespace OpenSim.Capabilities.Handlers
|
|
||||||
{
|
|
||||||
public class GetAssetsHandler
|
|
||||||
{
|
|
||||||
private static readonly ILog m_log =
|
|
||||||
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
|
||||||
|
|
||||||
private static readonly Dictionary<string, AssetType> queryTypes = new Dictionary<string, AssetType>()
|
|
||||||
{
|
|
||||||
{"texture_id", AssetType.Texture},
|
|
||||||
{"sound_id", AssetType.Sound},
|
|
||||||
{"callcard_id", AssetType.CallingCard},
|
|
||||||
{"landmark_id", AssetType.Landmark},
|
|
||||||
{"script_id", AssetType.LSLText},
|
|
||||||
{"clothing_id", AssetType.Clothing},
|
|
||||||
{"object_id", AssetType.Object},
|
|
||||||
{"notecard_id", AssetType.Notecard},
|
|
||||||
{"lsltext_id", AssetType.LSLText},
|
|
||||||
{"lslbyte_id", AssetType.LSLBytecode},
|
|
||||||
{"txtr_tga_id", AssetType.TextureTGA},
|
|
||||||
{"bodypart_id", AssetType.Bodypart},
|
|
||||||
{"snd_wav_id", AssetType.SoundWAV},
|
|
||||||
{"img_tga_id", AssetType.ImageTGA},
|
|
||||||
{"jpeg_id", AssetType.ImageJPEG},
|
|
||||||
{"animatn_id", AssetType.Animation},
|
|
||||||
{"gesture_id", AssetType.Gesture},
|
|
||||||
{"mesh_id", AssetType.Mesh},
|
|
||||||
{"settings_id", AssetType.Settings}
|
|
||||||
};
|
|
||||||
|
|
||||||
private IAssetService m_assetService;
|
|
||||||
|
|
||||||
public GetAssetsHandler(IAssetService assService)
|
|
||||||
{
|
|
||||||
m_assetService = assService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Handle(OSHttpRequest req, OSHttpResponse response)
|
|
||||||
{
|
|
||||||
response.ContentType = "text/plain";
|
|
||||||
|
|
||||||
if (m_assetService == null)
|
|
||||||
{
|
|
||||||
response.StatusCode = (int)HttpStatusCode.ServiceUnavailable;
|
|
||||||
response.KeepAlive = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
response.StatusCode = (int)HttpStatusCode.BadRequest;
|
|
||||||
|
|
||||||
var queries = req.QueryAsDictionary;
|
|
||||||
if(queries.Count == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
AssetType type = AssetType.Unknown;
|
|
||||||
string assetStr = string.Empty;
|
|
||||||
foreach (KeyValuePair<string,string> kvp in queries)
|
|
||||||
{
|
|
||||||
if (queryTypes.ContainsKey(kvp.Key))
|
|
||||||
{
|
|
||||||
type = queryTypes[kvp.Key];
|
|
||||||
assetStr = kvp.Value;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(type == AssetType.Unknown)
|
|
||||||
{
|
|
||||||
//m_log.Warn("[GETASSET]: Unknown type: " + query);
|
|
||||||
m_log.Warn("[GETASSET]: Unknown type");
|
|
||||||
response.StatusCode = (int)HttpStatusCode.NotFound;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (String.IsNullOrEmpty(assetStr))
|
|
||||||
return;
|
|
||||||
|
|
||||||
UUID assetID = UUID.Zero;
|
|
||||||
if(!UUID.TryParse(assetStr, out assetID))
|
|
||||||
return;
|
|
||||||
|
|
||||||
AssetBase asset = m_assetService.Get(assetID.ToString());
|
|
||||||
if(asset == null)
|
|
||||||
{
|
|
||||||
// m_log.Warn("[GETASSET]: not found: " + query + " " + assetStr);
|
|
||||||
response.StatusCode = (int)HttpStatusCode.NotFound;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (asset.Type != (sbyte)type)
|
|
||||||
return;
|
|
||||||
|
|
||||||
int len = asset.Data.Length;
|
|
||||||
|
|
||||||
string range = null;
|
|
||||||
if (req.Headers["Range"] != null)
|
|
||||||
range = req.Headers["Range"];
|
|
||||||
else if (req.Headers["range"] != null)
|
|
||||||
range = req.Headers["range"];
|
|
||||||
|
|
||||||
// range request
|
|
||||||
int start, end;
|
|
||||||
if (Util.TryParseHttpRange(range, out start, out end))
|
|
||||||
{
|
|
||||||
// Before clamping start make sure we can satisfy it in order to avoid
|
|
||||||
// sending back the last byte instead of an error status
|
|
||||||
if (start >= asset.Data.Length)
|
|
||||||
{
|
|
||||||
response.StatusCode = (int)HttpStatusCode.RequestedRangeNotSatisfiable;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (end == -1)
|
|
||||||
end = asset.Data.Length - 1;
|
|
||||||
else
|
|
||||||
end = Utils.Clamp(end, 0, asset.Data.Length - 1);
|
|
||||||
|
|
||||||
start = Utils.Clamp(start, 0, end);
|
|
||||||
len = end - start + 1;
|
|
||||||
|
|
||||||
//m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID);
|
|
||||||
response.AddHeader("Content-Range", String.Format("bytes {0}-{1}/{2}", start, end, asset.Data.Length));
|
|
||||||
response.StatusCode = (int)HttpStatusCode.PartialContent;
|
|
||||||
response.RawBufferStart = start;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
response.StatusCode = (int)HttpStatusCode.OK;
|
|
||||||
|
|
||||||
response.ContentType = asset.Metadata.ContentType;
|
|
||||||
response.RawBuffer = asset.Data;
|
|
||||||
response.RawBufferLen = len;
|
|
||||||
if (type == AssetType.Mesh || type == AssetType.Texture)
|
|
||||||
{
|
|
||||||
if(len > 8196)
|
|
||||||
{
|
|
||||||
//if(type == AssetType.Texture && ((asset.Flags & AssetFlags.AvatarBake)!= 0))
|
|
||||||
// responsedata["prio"] = 1;
|
|
||||||
//else
|
|
||||||
response.Priority = 2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
response.Priority = 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
response.Priority = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,120 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSimulator Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
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;
|
||||||
|
using OSDMap = OpenMetaverse.StructuredData.OSDMap;
|
||||||
|
using OSDArray = OpenMetaverse.StructuredData.OSDArray;
|
||||||
|
|
||||||
|
namespace OpenSim.Capabilities.Handlers
|
||||||
|
{
|
||||||
|
public class GetDisplayNamesHandler : BaseStreamHandler
|
||||||
|
{
|
||||||
|
private static readonly ILog m_log =
|
||||||
|
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
private IUserManagement m_UserManagement;
|
||||||
|
|
||||||
|
public GetDisplayNamesHandler(string path, IUserManagement umService, string name, string description)
|
||||||
|
: base("GET", path, name, description)
|
||||||
|
{
|
||||||
|
m_UserManagement = umService;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
||||||
|
{
|
||||||
|
m_log.DebugFormat("[GET_DISPLAY_NAMES]: called {0}", httpRequest.Url.Query);
|
||||||
|
|
||||||
|
NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query);
|
||||||
|
string[] ids = query.GetValues("ids");
|
||||||
|
|
||||||
|
|
||||||
|
if (m_UserManagement == null)
|
||||||
|
{
|
||||||
|
m_log.Error("[GET_DISPLAY_NAMES]: Cannot fetch display names without a user management component");
|
||||||
|
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.InternalServerError;
|
||||||
|
return new byte[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
OSDMap osdReply = new OSDMap();
|
||||||
|
OSDArray agents = new OSDArray();
|
||||||
|
|
||||||
|
osdReply["agents"] = agents;
|
||||||
|
foreach (string id in ids)
|
||||||
|
{
|
||||||
|
UUID uuid = UUID.Zero;
|
||||||
|
if (UUID.TryParse(id, out uuid))
|
||||||
|
{
|
||||||
|
string name = m_UserManagement.GetUserName(uuid);
|
||||||
|
if (!string.IsNullOrEmpty(name))
|
||||||
|
{
|
||||||
|
string[] parts = name.Split(new char[] {' '});
|
||||||
|
OSDMap osdname = new OSDMap();
|
||||||
|
osdname["display_name_next_update"] = OSD.FromDate(DateTime.MinValue);
|
||||||
|
osdname["display_name_expires"] = OSD.FromDate(DateTime.Now.AddMonths(1));
|
||||||
|
osdname["display_name"] = OSD.FromString(name);
|
||||||
|
osdname["legacy_first_name"] = parts[0];
|
||||||
|
osdname["legacy_last_name"] = parts[1];
|
||||||
|
osdname["username"] = OSD.FromString(name);
|
||||||
|
osdname["id"] = OSD.FromUUID(uuid);
|
||||||
|
osdname["is_display_name_default"] = OSD.FromBoolean(true);
|
||||||
|
|
||||||
|
agents.Add(osdname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Full content request
|
||||||
|
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.OK;
|
||||||
|
//httpResponse.ContentLength = ??;
|
||||||
|
httpResponse.ContentType = "application/llsd+xml";
|
||||||
|
|
||||||
|
string reply = OSDParser.SerializeLLSDXmlString(osdReply);
|
||||||
|
return System.Text.Encoding.UTF8.GetBytes(reply);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -25,40 +25,47 @@
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using Nini.Config;
|
using Nini.Config;
|
||||||
using OpenSim.Server.Base;
|
using OpenSim.Server.Base;
|
||||||
using OpenSim.Services.Interfaces;
|
using OpenSim.Services.Interfaces;
|
||||||
using OpenSim.Framework.ServiceAuth;
|
|
||||||
using OpenSim.Framework.Servers.HttpServer;
|
using OpenSim.Framework.Servers.HttpServer;
|
||||||
using OpenSim.Server.Handlers.Base;
|
using OpenSim.Server.Handlers.Base;
|
||||||
|
using OpenMetaverse;
|
||||||
|
|
||||||
namespace OpenSim.Server.Handlers.AgentPreferences
|
namespace OpenSim.Capabilities.Handlers
|
||||||
{
|
{
|
||||||
public class AgentPreferencesServiceConnector : ServiceConnector
|
public class GetDisplayNamesServerConnector : ServiceConnector
|
||||||
{
|
{
|
||||||
private IAgentPreferencesService m_AgentPreferencesService;
|
private IUserManagement m_UserManagement;
|
||||||
private string m_ConfigName = "AgentPreferencesService";
|
private string m_ConfigName = "CapsService";
|
||||||
|
|
||||||
public AgentPreferencesServiceConnector(IConfigSource config, IHttpServer server, string configName) :
|
public GetDisplayNamesServerConnector(IConfigSource config, IHttpServer server, string configName) :
|
||||||
base(config, server, configName)
|
base(config, server, configName)
|
||||||
{
|
{
|
||||||
|
if (configName != String.Empty)
|
||||||
|
m_ConfigName = configName;
|
||||||
|
|
||||||
IConfig serverConfig = config.Configs[m_ConfigName];
|
IConfig serverConfig = config.Configs[m_ConfigName];
|
||||||
if (serverConfig == null)
|
if (serverConfig == null)
|
||||||
throw new Exception(String.Format("No section {0} in config file", m_ConfigName));
|
throw new Exception(String.Format("No section '{0}' in config file", m_ConfigName));
|
||||||
|
|
||||||
string service = serverConfig.GetString("LocalServiceModule", String.Empty);
|
string umService = serverConfig.GetString("AssetService", String.Empty);
|
||||||
|
|
||||||
if (String.IsNullOrWhiteSpace(service))
|
if (umService == String.Empty)
|
||||||
throw new Exception("No LocalServiceModule in config file");
|
throw new Exception("No AssetService in config file");
|
||||||
|
|
||||||
Object[] args = new Object[] { config };
|
Object[] args = new Object[] { config };
|
||||||
m_AgentPreferencesService = ServerUtils.LoadPlugin<IAgentPreferencesService>(service, args);
|
m_UserManagement =
|
||||||
|
ServerUtils.LoadPlugin<IUserManagement>(umService, args);
|
||||||
|
|
||||||
IServiceAuth auth = ServiceAuth.Create(config, m_ConfigName); ;
|
if (m_UserManagement == null)
|
||||||
|
throw new Exception(String.Format("Failed to load UserManagement from {0}; config is {1}", umService, m_ConfigName));
|
||||||
|
|
||||||
server.AddStreamHandler(new AgentPreferencesServerPostHandler(m_AgentPreferencesService, auth));
|
string rurl = serverConfig.GetString("GetTextureRedirectURL");
|
||||||
|
|
||||||
|
server.AddStreamHandler(
|
||||||
|
new GetDisplayNamesHandler("/CAPS/agents/", m_UserManagement, "GetDisplayNames", null));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -30,6 +30,7 @@ using System.Collections;
|
||||||
using System.Collections.Specialized;
|
using System.Collections.Specialized;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Text;
|
||||||
using System.Web;
|
using System.Web;
|
||||||
using log4net;
|
using log4net;
|
||||||
using Nini.Config;
|
using Nini.Config;
|
||||||
|
@ -43,113 +44,71 @@ using Caps = OpenSim.Framework.Capabilities.Caps;
|
||||||
|
|
||||||
namespace OpenSim.Capabilities.Handlers
|
namespace OpenSim.Capabilities.Handlers
|
||||||
{
|
{
|
||||||
public class GetMeshHandler
|
public class GetMeshHandler : BaseStreamHandler
|
||||||
{
|
{
|
||||||
private static readonly ILog m_log =
|
// private static readonly ILog m_log =
|
||||||
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
private IAssetService m_assetService;
|
private IAssetService m_assetService;
|
||||||
|
|
||||||
public const string DefaultFormat = "vnd.ll.mesh";
|
public GetMeshHandler(string path, IAssetService assService, string name, string description)
|
||||||
|
: base("GET", path, name, description)
|
||||||
public GetMeshHandler(IAssetService assService)
|
|
||||||
{
|
{
|
||||||
m_assetService = assService;
|
m_assetService = assService;
|
||||||
}
|
}
|
||||||
public Hashtable Handle(Hashtable request)
|
|
||||||
|
protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
||||||
{
|
{
|
||||||
return ProcessGetMesh(request, UUID.Zero, null); ;
|
// Try to parse the texture ID from the request URL
|
||||||
}
|
NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query);
|
||||||
|
string meshStr = query.GetOne("mesh_id");
|
||||||
|
|
||||||
public Hashtable ProcessGetMesh(Hashtable request, UUID AgentId, Caps cap)
|
// m_log.DebugFormat("Fetching mesh {0}", meshStr);
|
||||||
{
|
|
||||||
Hashtable responsedata = new Hashtable();
|
|
||||||
if (m_assetService == null)
|
|
||||||
{
|
|
||||||
responsedata["int_response_code"] = (int)System.Net.HttpStatusCode.ServiceUnavailable;
|
|
||||||
responsedata["str_response_string"] = "The asset service is unavailable";
|
|
||||||
responsedata["keepalive"] = false;
|
|
||||||
return responsedata;
|
|
||||||
}
|
|
||||||
|
|
||||||
responsedata["int_response_code"] = (int)System.Net.HttpStatusCode.BadRequest;
|
|
||||||
responsedata["content_type"] = "text/plain";
|
|
||||||
responsedata["int_bytes"] = 0;
|
|
||||||
|
|
||||||
string meshStr = string.Empty;
|
|
||||||
if (request.ContainsKey("mesh_id"))
|
|
||||||
meshStr = request["mesh_id"].ToString();
|
|
||||||
|
|
||||||
if (String.IsNullOrEmpty(meshStr))
|
|
||||||
return responsedata;
|
|
||||||
|
|
||||||
UUID meshID = UUID.Zero;
|
UUID meshID = UUID.Zero;
|
||||||
if(!UUID.TryParse(meshStr, out meshID))
|
if (!String.IsNullOrEmpty(meshStr) && UUID.TryParse(meshStr, out meshID))
|
||||||
return responsedata;
|
|
||||||
|
|
||||||
AssetBase mesh = m_assetService.Get(meshID.ToString());
|
|
||||||
if(mesh == null)
|
|
||||||
{
|
{
|
||||||
responsedata["int_response_code"] = (int)System.Net.HttpStatusCode.NotFound;
|
if (m_assetService == null)
|
||||||
responsedata["str_response_string"] = "Mesh not found.";
|
|
||||||
return responsedata;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mesh.Type != (SByte)AssetType.Mesh)
|
|
||||||
{
|
|
||||||
responsedata["str_response_string"] = "Asset isn't a mesh.";
|
|
||||||
return responsedata;
|
|
||||||
}
|
|
||||||
|
|
||||||
string range = String.Empty;
|
|
||||||
|
|
||||||
if (((Hashtable)request["headers"])["range"] != null)
|
|
||||||
range = (string)((Hashtable)request["headers"])["range"];
|
|
||||||
else if (((Hashtable)request["headers"])["Range"] != null)
|
|
||||||
range = (string)((Hashtable)request["headers"])["Range"];
|
|
||||||
|
|
||||||
responsedata["content_type"] = "application/vnd.ll.mesh";
|
|
||||||
if (String.IsNullOrEmpty(range))
|
|
||||||
{
|
|
||||||
// full mesh
|
|
||||||
responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data);
|
|
||||||
responsedata["int_response_code"] = (int)System.Net.HttpStatusCode.OK;
|
|
||||||
return responsedata;
|
|
||||||
}
|
|
||||||
|
|
||||||
// range request
|
|
||||||
int start, end;
|
|
||||||
if (Util.TryParseHttpRange(range, out start, out end))
|
|
||||||
{
|
|
||||||
// Before clamping start make sure we can satisfy it in order to avoid
|
|
||||||
// sending back the last byte instead of an error status
|
|
||||||
if (start >= mesh.Data.Length)
|
|
||||||
{
|
{
|
||||||
responsedata["str_response_string"] = "This range doesnt exist.";
|
httpResponse.StatusCode = 404;
|
||||||
return responsedata;
|
httpResponse.ContentType = "text/plain";
|
||||||
|
byte[] data = Encoding.UTF8.GetBytes("The asset service is unavailable. So is your mesh.");
|
||||||
|
httpResponse.Body.Write(data, 0, data.Length);
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
end = Utils.Clamp(end, 0, mesh.Data.Length - 1);
|
AssetBase mesh = m_assetService.Get(meshID.ToString());
|
||||||
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);
|
if (mesh != null)
|
||||||
Hashtable headers = new Hashtable();
|
{
|
||||||
headers["Content-Range"] = String.Format("bytes {0}-{1}/{2}", start, end, mesh.Data.Length);
|
if (mesh.Type == (SByte)AssetType.Mesh)
|
||||||
responsedata["headers"] = headers;
|
{
|
||||||
responsedata["int_response_code"] = (int)System.Net.HttpStatusCode.PartialContent;
|
byte[] data = mesh.Data;
|
||||||
|
httpResponse.Body.Write(data, 0, data.Length);
|
||||||
byte[] d = new byte[len];
|
httpResponse.ContentType = "application/vnd.ll.mesh";
|
||||||
Array.Copy(mesh.Data, start, d, 0, len);
|
httpResponse.StatusCode = 200;
|
||||||
responsedata["bin_response_data"] = d;
|
}
|
||||||
responsedata["int_bytes"] = len;
|
// Optionally add additional mesh types here
|
||||||
return responsedata;
|
else
|
||||||
|
{
|
||||||
|
httpResponse.StatusCode = 404;
|
||||||
|
httpResponse.ContentType = "text/plain";
|
||||||
|
byte[] data = Encoding.UTF8.GetBytes("Unfortunately, this asset isn't a mesh.");
|
||||||
|
httpResponse.Body.Write(data, 0, data.Length);
|
||||||
|
httpResponse.KeepAlive = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
httpResponse.StatusCode = 404;
|
||||||
|
httpResponse.ContentType = "text/plain";
|
||||||
|
byte[] data = Encoding.UTF8.GetBytes("Your Mesh wasn't found. Sorry!");
|
||||||
|
httpResponse.Body.Write(data, 0, data.Length);
|
||||||
|
httpResponse.KeepAlive = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_log.Warn("[GETMESH]: Failed to parse a range from GetMesh request, sending full asset: " + (string)request["uri"]);
|
return null;
|
||||||
responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data);
|
|
||||||
responsedata["int_response_code"] = (int)System.Net.HttpStatusCode.OK;
|
|
||||||
return responsedata;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -25,13 +25,16 @@
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using Nini.Config;
|
|
||||||
using OpenMetaverse;
|
|
||||||
using OpenSim.Framework.Servers.HttpServer;
|
|
||||||
using OpenSim.Server.Base;
|
|
||||||
using OpenSim.Server.Handlers.Base;
|
|
||||||
using OpenSim.Services.Interfaces;
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using Nini.Config;
|
||||||
|
using OpenSim.Server.Base;
|
||||||
|
using OpenSim.Services.Interfaces;
|
||||||
|
using OpenSim.Framework.Servers.HttpServer;
|
||||||
|
using OpenSim.Server.Handlers.Base;
|
||||||
|
using OpenSim.Framework.Servers;
|
||||||
|
|
||||||
|
using OpenMetaverse;
|
||||||
|
|
||||||
namespace OpenSim.Capabilities.Handlers
|
namespace OpenSim.Capabilities.Handlers
|
||||||
{
|
{
|
||||||
|
@ -62,17 +65,8 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
if (m_AssetService == null)
|
if (m_AssetService == null)
|
||||||
throw new Exception(String.Format("Failed to load AssetService from {0}; config is {1}", assetService, m_ConfigName));
|
throw new Exception(String.Format("Failed to load AssetService from {0}; config is {1}", assetService, m_ConfigName));
|
||||||
|
|
||||||
string rurl = serverConfig.GetString("GetMeshRedirectURL");
|
server.AddStreamHandler(
|
||||||
|
new GetMeshHandler("/CAPS/GetMesh/" /*+ UUID.Random() */, m_AssetService, "GetMesh", null));
|
||||||
GetMeshHandler gmeshHandler = new GetMeshHandler(m_AssetService);
|
|
||||||
IRequestHandler reqHandler
|
|
||||||
= new RestHTTPHandler(
|
|
||||||
"GET",
|
|
||||||
"/" + UUID.Random(),
|
|
||||||
httpMethod => gmeshHandler.ProcessGetMesh(httpMethod, UUID.Zero, null),
|
|
||||||
"GetMesh",
|
|
||||||
null);
|
|
||||||
server.AddStreamHandler(reqHandler); ;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -47,41 +47,46 @@ using Caps = OpenSim.Framework.Capabilities.Caps;
|
||||||
|
|
||||||
namespace OpenSim.Capabilities.Handlers
|
namespace OpenSim.Capabilities.Handlers
|
||||||
{
|
{
|
||||||
public class GetTextureHandler
|
public class GetTextureHandler : BaseStreamHandler
|
||||||
{
|
{
|
||||||
private static readonly ILog m_log =
|
private static readonly ILog m_log =
|
||||||
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
private IAssetService m_assetService;
|
private IAssetService m_assetService;
|
||||||
|
|
||||||
public const string DefaultFormat = "x-j2c";
|
public const string DefaultFormat = "x-j2c";
|
||||||
|
|
||||||
public GetTextureHandler(IAssetService assService)
|
// TODO: Change this to a config option
|
||||||
|
private string m_RedirectURL = null;
|
||||||
|
|
||||||
|
public GetTextureHandler(string path, IAssetService assService, string name, string description, string redirectURL)
|
||||||
|
: base("GET", path, name, description)
|
||||||
{
|
{
|
||||||
m_assetService = assService;
|
m_assetService = assService;
|
||||||
|
m_RedirectURL = redirectURL;
|
||||||
|
if (m_RedirectURL != null && !m_RedirectURL.EndsWith("/"))
|
||||||
|
m_RedirectURL += "/";
|
||||||
}
|
}
|
||||||
|
|
||||||
public Hashtable Handle(Hashtable request)
|
protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
||||||
{
|
{
|
||||||
Hashtable ret = new Hashtable();
|
// Try to parse the texture ID from the request URL
|
||||||
ret["int_response_code"] = (int)System.Net.HttpStatusCode.NotFound;
|
NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query);
|
||||||
ret["content_type"] = "text/plain";
|
string textureStr = query.GetOne("texture_id");
|
||||||
ret["int_bytes"] = 0;
|
string format = query.GetOne("format");
|
||||||
string textureStr = (string)request["texture_id"];
|
|
||||||
string format = (string)request["format"];
|
|
||||||
|
|
||||||
//m_log.DebugFormat("[GETTEXTURE]: called {0}", textureStr);
|
//m_log.DebugFormat("[GETTEXTURE]: called {0}", textureStr);
|
||||||
|
|
||||||
if (m_assetService == null)
|
if (m_assetService == null)
|
||||||
{
|
{
|
||||||
m_log.Error("[GETTEXTURE]: Cannot fetch texture " + textureStr + " without an asset service");
|
m_log.Error("[GETTEXTURE]: Cannot fetch texture " + textureStr + " without an asset service");
|
||||||
|
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
UUID textureID;
|
UUID textureID;
|
||||||
if (!String.IsNullOrEmpty(textureStr) && UUID.TryParse(textureStr, out textureID))
|
if (!String.IsNullOrEmpty(textureStr) && UUID.TryParse(textureStr, out textureID))
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat("[GETTEXTURE]: Received request for texture id {0}", textureID);
|
// m_log.DebugFormat("[GETTEXTURE]: Received request for texture id {0}", textureID);
|
||||||
|
|
||||||
string[] formats;
|
string[] formats;
|
||||||
if (!string.IsNullOrEmpty(format))
|
if (!string.IsNullOrEmpty(format))
|
||||||
{
|
{
|
||||||
|
@ -89,50 +94,41 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
formats = new string[1] { DefaultFormat }; // default
|
formats = WebUtil.GetPreferredImageTypes(httpRequest.Headers.Get("Accept"));
|
||||||
if (((Hashtable)request["headers"])["Accept"] != null)
|
|
||||||
formats = WebUtil.GetPreferredImageTypes((string)((Hashtable)request["headers"])["Accept"]);
|
|
||||||
if (formats.Length == 0)
|
if (formats.Length == 0)
|
||||||
formats = new string[1] { DefaultFormat }; // default
|
formats = new string[1] { DefaultFormat }; // default
|
||||||
|
|
||||||
}
|
}
|
||||||
// OK, we have an array with preferred formats, possibly with only one entry
|
// OK, we have an array with preferred formats, possibly with only one entry
|
||||||
bool foundtexture = false;
|
|
||||||
|
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
|
||||||
foreach (string f in formats)
|
foreach (string f in formats)
|
||||||
{
|
{
|
||||||
foundtexture = FetchTexture(request, ret, textureID, f);
|
if (FetchTexture(httpRequest, httpResponse, textureID, f))
|
||||||
if (foundtexture)
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!foundtexture)
|
|
||||||
{
|
|
||||||
ret["int_response_code"] = 404;
|
|
||||||
ret["error_status_text"] = "not found";
|
|
||||||
ret["str_response_string"] = "not found";
|
|
||||||
ret["content_type"] = "text/plain";
|
|
||||||
ret["int_bytes"] = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_log.Warn("[GETTEXTURE]: Failed to parse a texture_id from GetTexture request: " + (string)request["uri"]);
|
m_log.Warn("[GETTEXTURE]: Failed to parse a texture_id from GetTexture request: " + httpRequest.Url);
|
||||||
}
|
}
|
||||||
|
|
||||||
// m_log.DebugFormat(
|
// m_log.DebugFormat(
|
||||||
// "[GETTEXTURE]: For texture {0} sending back response {1}, data length {2}",
|
// "[GETTEXTURE]: For texture {0} sending back response {1}, data length {2}",
|
||||||
// textureID, httpResponse.StatusCode, httpResponse.ContentLength);
|
// textureID, httpResponse.StatusCode, httpResponse.ContentLength);
|
||||||
return ret;
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="httpRequest"></param>
|
/// <param name="httpRequest"></param>
|
||||||
/// <param name="httpResponse"></param>
|
/// <param name="httpResponse"></param>
|
||||||
/// <param name="textureID"></param>
|
/// <param name="textureID"></param>
|
||||||
/// <param name="format"></param>
|
/// <param name="format"></param>
|
||||||
/// <returns>False for "caller try another codec"; true otherwise</returns>
|
/// <returns>False for "caller try another codec"; true otherwise</returns>
|
||||||
private bool FetchTexture(Hashtable request, Hashtable response, UUID textureID, string format)
|
private bool FetchTexture(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, UUID textureID, string format)
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat("[GETTEXTURE]: {0} with requested format {1}", textureID, format);
|
// m_log.DebugFormat("[GETTEXTURE]: {0} with requested format {1}", textureID, format);
|
||||||
AssetBase texture;
|
AssetBase texture;
|
||||||
|
@ -141,76 +137,92 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
if (format != DefaultFormat)
|
if (format != DefaultFormat)
|
||||||
fullID = fullID + "-" + format;
|
fullID = fullID + "-" + format;
|
||||||
|
|
||||||
// try the cache
|
if (!String.IsNullOrEmpty(m_RedirectURL))
|
||||||
texture = m_assetService.GetCached(fullID);
|
|
||||||
|
|
||||||
if (texture == null)
|
|
||||||
{
|
{
|
||||||
//m_log.DebugFormat("[GETTEXTURE]: texture was not in the cache");
|
// Only try to fetch locally cached textures. Misses are redirected
|
||||||
|
texture = m_assetService.GetCached(fullID);
|
||||||
// Fetch locally or remotely. Misses return a 404
|
|
||||||
texture = m_assetService.Get(textureID.ToString());
|
|
||||||
|
|
||||||
if (texture != null)
|
if (texture != null)
|
||||||
{
|
{
|
||||||
if (texture.Type != (sbyte)AssetType.Texture)
|
if (texture.Type != (sbyte)AssetType.Texture)
|
||||||
return true;
|
|
||||||
|
|
||||||
if (format == DefaultFormat)
|
|
||||||
{
|
{
|
||||||
WriteTextureData(request, response, texture, format);
|
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
AssetBase newTexture = new AssetBase(texture.ID + "-" + format, texture.Name, (sbyte)AssetType.Texture, texture.Metadata.CreatorID);
|
|
||||||
newTexture.Data = ConvertTextureData(texture, format);
|
|
||||||
if (newTexture.Data.Length == 0)
|
|
||||||
return false; // !!! Caller try another codec, please!
|
|
||||||
|
|
||||||
newTexture.Flags = AssetFlags.Collectable;
|
|
||||||
newTexture.Temporary = true;
|
|
||||||
newTexture.Local = true;
|
|
||||||
m_assetService.Store(newTexture);
|
|
||||||
WriteTextureData(request, response, newTexture, format);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
WriteTextureData(httpRequest, httpResponse, texture, format);
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
else // it was on the cache
|
{
|
||||||
{
|
string textureUrl = m_RedirectURL + "?texture_id="+ textureID.ToString();
|
||||||
//m_log.DebugFormat("[GETTEXTURE]: texture was in the cache");
|
m_log.Debug("[GETTEXTURE]: Redirecting texture request to " + textureUrl);
|
||||||
WriteTextureData(request, response, texture, format);
|
httpResponse.StatusCode = (int)OSHttpStatusCode.RedirectMovedPermanently;
|
||||||
return true;
|
httpResponse.RedirectLocation = textureUrl;
|
||||||
}
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // no redirect
|
||||||
|
{
|
||||||
|
// try the cache
|
||||||
|
texture = m_assetService.GetCached(fullID);
|
||||||
|
|
||||||
//response = new Hashtable();
|
if (texture == null)
|
||||||
|
{
|
||||||
|
// m_log.DebugFormat("[GETTEXTURE]: texture was not in the cache");
|
||||||
|
|
||||||
|
// Fetch locally or remotely. Misses return a 404
|
||||||
|
texture = m_assetService.Get(textureID.ToString());
|
||||||
|
|
||||||
|
if (texture != null)
|
||||||
|
{
|
||||||
|
if (texture.Type != (sbyte)AssetType.Texture)
|
||||||
|
{
|
||||||
|
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (format == DefaultFormat)
|
||||||
|
{
|
||||||
|
WriteTextureData(httpRequest, httpResponse, texture, format);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AssetBase newTexture = new AssetBase(texture.ID + "-" + format, texture.Name, (sbyte)AssetType.Texture, texture.Metadata.CreatorID);
|
||||||
|
newTexture.Data = ConvertTextureData(texture, format);
|
||||||
|
if (newTexture.Data.Length == 0)
|
||||||
|
return false; // !!! Caller try another codec, please!
|
||||||
|
|
||||||
|
newTexture.Flags = AssetFlags.Collectable;
|
||||||
|
newTexture.Temporary = true;
|
||||||
|
newTexture.Local = true;
|
||||||
|
m_assetService.Store(newTexture);
|
||||||
|
WriteTextureData(httpRequest, httpResponse, newTexture, format);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // it was on the cache
|
||||||
|
{
|
||||||
|
// m_log.DebugFormat("[GETTEXTURE]: texture was in the cache");
|
||||||
|
WriteTextureData(httpRequest, httpResponse, texture, format);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//WriteTextureData(request,response,null,format);
|
|
||||||
// not found
|
// not found
|
||||||
//m_log.Warn("[GETTEXTURE]: Texture " + textureID + " not found");
|
// m_log.Warn("[GETTEXTURE]: Texture " + textureID + " not found");
|
||||||
return false;
|
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WriteTextureData(Hashtable request, Hashtable response, AssetBase texture, string format)
|
private void WriteTextureData(IOSHttpRequest request, IOSHttpResponse response, AssetBase texture, string format)
|
||||||
{
|
{
|
||||||
Hashtable headers = new Hashtable();
|
string range = request.Headers.GetOne("Range");
|
||||||
response["headers"] = headers;
|
|
||||||
|
|
||||||
string range = String.Empty;
|
|
||||||
|
|
||||||
if (((Hashtable)request["headers"])["range"] != null)
|
|
||||||
range = (string)((Hashtable)request["headers"])["range"];
|
|
||||||
|
|
||||||
else if (((Hashtable)request["headers"])["Range"] != null)
|
|
||||||
range = (string)((Hashtable)request["headers"])["Range"];
|
|
||||||
|
|
||||||
if (!String.IsNullOrEmpty(range)) // JP2's only
|
if (!String.IsNullOrEmpty(range)) // JP2's only
|
||||||
{
|
{
|
||||||
// Range request
|
// Range request
|
||||||
int start, end;
|
int start, end;
|
||||||
if (Util.TryParseHttpRange(range, out start, out end))
|
if (TryParseRange(range, out start, out end))
|
||||||
{
|
{
|
||||||
// Before clamping start make sure we can satisfy it in order to avoid
|
// Before clamping start make sure we can satisfy it in order to avoid
|
||||||
// sending back the last byte instead of an error status
|
// sending back the last byte instead of an error status
|
||||||
|
@ -232,8 +244,10 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
// However, if we return PartialContent (or OK) instead, the viewer will display that resolution.
|
// However, if we return PartialContent (or OK) instead, the viewer will display that resolution.
|
||||||
|
|
||||||
// response.StatusCode = (int)System.Net.HttpStatusCode.RequestedRangeNotSatisfiable;
|
// response.StatusCode = (int)System.Net.HttpStatusCode.RequestedRangeNotSatisfiable;
|
||||||
// viewers don't seem to handle RequestedRangeNotSatisfiable and keep retrying with same parameters
|
// response.AddHeader("Content-Range", String.Format("bytes */{0}", texture.Data.Length));
|
||||||
response["int_response_code"] = (int)System.Net.HttpStatusCode.NotFound;
|
// response.StatusCode = (int)System.Net.HttpStatusCode.OK;
|
||||||
|
response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent;
|
||||||
|
response.ContentType = texture.Metadata.ContentType;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -248,35 +262,41 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
|
|
||||||
// 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);
|
||||||
|
|
||||||
response["content-type"] = texture.Metadata.ContentType;
|
// Always return PartialContent, even if the range covered the entire data length
|
||||||
response["int_response_code"] = (int)System.Net.HttpStatusCode.PartialContent;
|
// We were accidentally sending back 404 before in this situation
|
||||||
headers["Content-Range"] = String.Format("bytes {0}-{1}/{2}", start, end, texture.Data.Length);
|
// https://issues.apache.org/bugzilla/show_bug.cgi?id=51878 supports sending 206 even if the
|
||||||
|
// entire range is requested, and viewer 3.2.2 (and very probably earlier) seems fine with this.
|
||||||
|
//
|
||||||
|
// We also do not want to send back OK even if the whole range was satisfiable since this causes
|
||||||
|
// HTTP textures on at least Imprudence 1.4.0-beta2 to never display the final texture quality.
|
||||||
|
// if (end > maxEnd)
|
||||||
|
// response.StatusCode = (int)System.Net.HttpStatusCode.OK;
|
||||||
|
// else
|
||||||
|
response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent;
|
||||||
|
|
||||||
byte[] d = new byte[len];
|
response.ContentLength = len;
|
||||||
Array.Copy(texture.Data, start, d, 0, len);
|
response.ContentType = texture.Metadata.ContentType;
|
||||||
response["bin_response_data"] = d;
|
response.AddHeader("Content-Range", String.Format("bytes {0}-{1}/{2}", start, end, texture.Data.Length));
|
||||||
response["int_bytes"] = len;
|
|
||||||
|
response.Body.Write(texture.Data, start, len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_log.Warn("[GETTEXTURE]: Malformed Range header: " + range);
|
m_log.Warn("[GETTEXTURE]: Malformed Range header: " + range);
|
||||||
response["int_response_code"] = (int)System.Net.HttpStatusCode.BadRequest;
|
response.StatusCode = (int)System.Net.HttpStatusCode.BadRequest;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else // JP2's or other formats
|
else // JP2's or other formats
|
||||||
{
|
{
|
||||||
// Full content request
|
// Full content request
|
||||||
response["int_response_code"] = (int)System.Net.HttpStatusCode.OK;
|
response.StatusCode = (int)System.Net.HttpStatusCode.OK;
|
||||||
|
response.ContentLength = texture.Data.Length;
|
||||||
if (format == DefaultFormat)
|
if (format == DefaultFormat)
|
||||||
response["content_type"] = texture.Metadata.ContentType;
|
response.ContentType = texture.Metadata.ContentType;
|
||||||
else
|
else
|
||||||
response["content_type"] = "image/" + format;
|
response.ContentType = "image/" + format;
|
||||||
|
response.Body.Write(texture.Data, 0, texture.Data.Length);
|
||||||
response["bin_response_data"] = texture.Data;
|
|
||||||
response["int_bytes"] = texture.Data.Length;
|
|
||||||
|
|
||||||
// response.Body.Write(texture.Data, 0, texture.Data.Length);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (response.StatusCode < 200 || response.StatusCode > 299)
|
// if (response.StatusCode < 200 || response.StatusCode > 299)
|
||||||
|
@ -289,41 +309,86 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
// texture.FullID, range, response.StatusCode, response.ContentLength, texture.Data.Length);
|
// texture.FullID, range, response.StatusCode, response.ContentLength, texture.Data.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Parse a range header.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// As per http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html,
|
||||||
|
/// this obeys range headers with two values (e.g. 533-4165) and no second value (e.g. 533-).
|
||||||
|
/// Where there is no value, -1 is returned.
|
||||||
|
/// FIXME: Need to cover the case where only a second value is specified (e.g. -4165), probably by returning -1
|
||||||
|
/// for start.</remarks>
|
||||||
|
/// <returns></returns>
|
||||||
|
/// <param name='header'></param>
|
||||||
|
/// <param name='start'>Start of the range. Undefined if this was not a number.</param>
|
||||||
|
/// <param name='end'>End of the range. Will be -1 if no end specified. Undefined if there was a raw string but this was not a number.</param>
|
||||||
|
private bool TryParseRange(string header, out int start, out int end)
|
||||||
|
{
|
||||||
|
start = end = 0;
|
||||||
|
|
||||||
|
if (header.StartsWith("bytes="))
|
||||||
|
{
|
||||||
|
string[] rangeValues = header.Substring(6).Split('-');
|
||||||
|
|
||||||
|
if (rangeValues.Length == 2)
|
||||||
|
{
|
||||||
|
if (!Int32.TryParse(rangeValues[0], out start))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
string rawEnd = rangeValues[1];
|
||||||
|
|
||||||
|
if (rawEnd == "")
|
||||||
|
{
|
||||||
|
end = -1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (Int32.TryParse(rawEnd, out end))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
start = end = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private byte[] ConvertTextureData(AssetBase texture, string format)
|
private byte[] ConvertTextureData(AssetBase texture, string format)
|
||||||
{
|
{
|
||||||
m_log.DebugFormat("[GETTEXTURE]: Converting texture {0} to {1}", texture.ID, format);
|
m_log.DebugFormat("[GETTEXTURE]: Converting texture {0} to {1}", texture.ID, format);
|
||||||
byte[] data = new byte[0];
|
byte[] data = new byte[0];
|
||||||
|
|
||||||
MemoryStream imgstream = new MemoryStream();
|
MemoryStream imgstream = new MemoryStream();
|
||||||
Bitmap mTexture = null;
|
Bitmap mTexture = new Bitmap(1, 1);
|
||||||
ManagedImage managedImage = null;
|
ManagedImage managedImage;
|
||||||
Image image = null;
|
Image image = (Image)mTexture;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Taking our jpeg2000 data, decoding it, then saving it to a byte array with regular data
|
// Taking our jpeg2000 data, decoding it, then saving it to a byte array with regular data
|
||||||
|
|
||||||
|
imgstream = new MemoryStream();
|
||||||
|
|
||||||
// Decode image to System.Drawing.Image
|
// Decode image to System.Drawing.Image
|
||||||
if (OpenJPEG.DecodeToImage(texture.Data, out managedImage, out image) && image != null)
|
if (OpenJPEG.DecodeToImage(texture.Data, out managedImage, out image))
|
||||||
{
|
{
|
||||||
// Save to bitmap
|
// Save to bitmap
|
||||||
mTexture = new Bitmap(image);
|
mTexture = new Bitmap(image);
|
||||||
|
|
||||||
using(EncoderParameters myEncoderParameters = new EncoderParameters())
|
EncoderParameters myEncoderParameters = new EncoderParameters();
|
||||||
{
|
myEncoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, 95L);
|
||||||
myEncoderParameters.Param[0] = new EncoderParameter(Encoder.Quality,95L);
|
|
||||||
|
|
||||||
// Save bitmap to stream
|
// Save bitmap to stream
|
||||||
ImageCodecInfo codec = GetEncoderInfo("image/" + format);
|
ImageCodecInfo codec = GetEncoderInfo("image/" + format);
|
||||||
if (codec != null)
|
if (codec != null)
|
||||||
{
|
{
|
||||||
mTexture.Save(imgstream, codec, myEncoderParameters);
|
mTexture.Save(imgstream, codec, myEncoderParameters);
|
||||||
// Write the stream to a byte array for output
|
// Write the stream to a byte array for output
|
||||||
data = imgstream.ToArray();
|
data = imgstream.ToArray();
|
||||||
}
|
|
||||||
else
|
|
||||||
m_log.WarnFormat("[GETTEXTURE]: No such codec {0}", format);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
m_log.WarnFormat("[GETTEXTURE]: No such codec {0}", format);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
@ -340,10 +405,11 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
if (image != null)
|
if (image != null)
|
||||||
image.Dispose();
|
image.Dispose();
|
||||||
|
|
||||||
if(managedImage != null)
|
|
||||||
managedImage.Clear();
|
|
||||||
if (imgstream != null)
|
if (imgstream != null)
|
||||||
|
{
|
||||||
|
imgstream.Close();
|
||||||
imgstream.Dispose();
|
imgstream.Dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
|
@ -362,4 +428,4 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,394 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
* * Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* * Neither the name of the OpenSimulator Project nor the
|
|
||||||
* names of its contributors may be used to endorse or promote products
|
|
||||||
* derived from this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
|
||||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Specialized;
|
|
||||||
using System.Drawing;
|
|
||||||
using System.Drawing.Imaging;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.IO;
|
|
||||||
using System.Net;
|
|
||||||
using System.Web;
|
|
||||||
using log4net;
|
|
||||||
using Nini.Config;
|
|
||||||
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.Services.Interfaces;
|
|
||||||
using Caps = OpenSim.Framework.Capabilities.Caps;
|
|
||||||
|
|
||||||
namespace OpenSim.Capabilities.Handlers
|
|
||||||
{
|
|
||||||
public class GetTextureRobustHandler : BaseStreamHandler
|
|
||||||
{
|
|
||||||
private static readonly ILog m_log =
|
|
||||||
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
|
||||||
private IAssetService m_assetService;
|
|
||||||
|
|
||||||
public const string DefaultFormat = "x-j2c";
|
|
||||||
|
|
||||||
// TODO: Change this to a config option
|
|
||||||
private string m_RedirectURL = null;
|
|
||||||
|
|
||||||
public GetTextureRobustHandler(string path, IAssetService assService, string name, string description, string redirectURL)
|
|
||||||
: base("GET", path, name, description)
|
|
||||||
{
|
|
||||||
m_assetService = assService;
|
|
||||||
m_RedirectURL = redirectURL;
|
|
||||||
if (m_RedirectURL != null && !m_RedirectURL.EndsWith("/"))
|
|
||||||
m_RedirectURL += "/";
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
|
||||||
{
|
|
||||||
// Try to parse the texture ID from the request URL
|
|
||||||
NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query);
|
|
||||||
string textureStr = query.GetOne("texture_id");
|
|
||||||
string format = query.GetOne("format");
|
|
||||||
|
|
||||||
//m_log.DebugFormat("[GETTEXTURE]: called {0}", textureStr);
|
|
||||||
|
|
||||||
if (m_assetService == null)
|
|
||||||
{
|
|
||||||
m_log.Error("[GETTEXTURE]: Cannot fetch texture " + textureStr + " without an asset service");
|
|
||||||
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
UUID textureID;
|
|
||||||
if (!String.IsNullOrEmpty(textureStr) && UUID.TryParse(textureStr, out textureID))
|
|
||||||
{
|
|
||||||
// m_log.DebugFormat("[GETTEXTURE]: Received request for texture id {0}", textureID);
|
|
||||||
|
|
||||||
string[] formats;
|
|
||||||
if (!string.IsNullOrEmpty(format))
|
|
||||||
{
|
|
||||||
formats = new string[1] { format.ToLower() };
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
formats = WebUtil.GetPreferredImageTypes(httpRequest.Headers.Get("Accept"));
|
|
||||||
if (formats.Length == 0)
|
|
||||||
formats = new string[1] { DefaultFormat }; // default
|
|
||||||
|
|
||||||
}
|
|
||||||
// OK, we have an array with preferred formats, possibly with only one entry
|
|
||||||
|
|
||||||
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
|
|
||||||
foreach (string f in formats)
|
|
||||||
{
|
|
||||||
if (FetchTexture(httpRequest, httpResponse, textureID, f))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="httpRequest"></param>
|
|
||||||
/// <param name="httpResponse"></param>
|
|
||||||
/// <param name="textureID"></param>
|
|
||||||
/// <param name="format"></param>
|
|
||||||
/// <returns>False for "caller try another codec"; true otherwise</returns>
|
|
||||||
private bool FetchTexture(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, UUID textureID, string format)
|
|
||||||
{
|
|
||||||
// m_log.DebugFormat("[GETTEXTURE]: {0} with requested format {1}", textureID, format);
|
|
||||||
if(!String.IsNullOrEmpty(m_RedirectURL))
|
|
||||||
{
|
|
||||||
string textureUrl = m_RedirectURL + "?texture_id=" + textureID.ToString();
|
|
||||||
m_log.Debug("[GETTEXTURE]: Redirecting texture request to " + textureUrl);
|
|
||||||
httpResponse.StatusCode = (int)HttpStatusCode.Moved;
|
|
||||||
httpResponse.AddHeader("Location:", textureUrl);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fetch, Misses or invalid return a 404
|
|
||||||
AssetBase texture = m_assetService.Get(textureID.ToString());
|
|
||||||
if (texture != null)
|
|
||||||
{
|
|
||||||
if (texture.Type != (sbyte)AssetType.Texture)
|
|
||||||
{
|
|
||||||
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (format == DefaultFormat)
|
|
||||||
{
|
|
||||||
WriteTextureData(httpRequest, httpResponse, texture, format);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// need to convert format
|
|
||||||
AssetBase newTexture = new AssetBase(texture.ID + "-" + format, texture.Name, (sbyte)AssetType.Texture, texture.Metadata.CreatorID);
|
|
||||||
newTexture.Data = ConvertTextureData(texture, format);
|
|
||||||
if (newTexture.Data.Length == 0)
|
|
||||||
return false; // !!! Caller try another codec, please!
|
|
||||||
|
|
||||||
newTexture.Flags = AssetFlags.Collectable;
|
|
||||||
newTexture.Temporary = true;
|
|
||||||
newTexture.Local = true;
|
|
||||||
WriteTextureData(httpRequest, httpResponse, newTexture, format);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// not found
|
|
||||||
// m_log.Warn("[GETTEXTURE]: Texture " + textureID + " not found");
|
|
||||||
httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void WriteTextureData(IOSHttpRequest request, IOSHttpResponse response, AssetBase texture, string format)
|
|
||||||
{
|
|
||||||
string range = request.Headers.GetOne("Range");
|
|
||||||
|
|
||||||
if (!String.IsNullOrEmpty(range)) // JP2's only
|
|
||||||
{
|
|
||||||
// Range request
|
|
||||||
int start, end;
|
|
||||||
if (TryParseRange(range, out start, out end))
|
|
||||||
{
|
|
||||||
// Before clamping start make sure we can satisfy it in order to avoid
|
|
||||||
// sending back the last byte instead of an error status
|
|
||||||
if (start >= texture.Data.Length)
|
|
||||||
{
|
|
||||||
// m_log.DebugFormat(
|
|
||||||
// "[GETTEXTURE]: Client requested range for texture {0} starting at {1} but texture has end of {2}",
|
|
||||||
// texture.ID, start, texture.Data.Length);
|
|
||||||
|
|
||||||
// Stricly speaking, as per http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html, we should be sending back
|
|
||||||
// Requested Range Not Satisfiable (416) here. However, it appears that at least recent implementations
|
|
||||||
// of the Linden Lab viewer (3.2.1 and 3.3.4 and probably earlier), a viewer that has previously
|
|
||||||
// received a very small texture may attempt to fetch bytes from the server past the
|
|
||||||
// range of data that it received originally. Whether this happens appears to depend on whether
|
|
||||||
// the viewer's estimation of how large a request it needs to make for certain discard levels
|
|
||||||
// (http://wiki.secondlife.com/wiki/Image_System#Discard_Level_and_Mip_Mapping), chiefly discard
|
|
||||||
// level 2. If this estimate is greater than the total texture size, returning a RequestedRangeNotSatisfiable
|
|
||||||
// here will cause the viewer to treat the texture as bad and never display the full resolution
|
|
||||||
// However, if we return PartialContent (or OK) instead, the viewer will display that resolution.
|
|
||||||
|
|
||||||
// response.StatusCode = (int)System.Net.HttpStatusCode.RequestedRangeNotSatisfiable;
|
|
||||||
// response.AddHeader("Content-Range", String.Format("bytes */{0}", texture.Data.Length));
|
|
||||||
// response.StatusCode = (int)System.Net.HttpStatusCode.OK;
|
|
||||||
response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent;
|
|
||||||
response.ContentType = texture.Metadata.ContentType;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Handle the case where no second range value was given. This is equivalent to requesting
|
|
||||||
// the rest of the entity.
|
|
||||||
if (end == -1)
|
|
||||||
end = int.MaxValue;
|
|
||||||
|
|
||||||
end = Utils.Clamp(end, 0, texture.Data.Length - 1);
|
|
||||||
start = Utils.Clamp(start, 0, end);
|
|
||||||
int len = end - start + 1;
|
|
||||||
|
|
||||||
// m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID);
|
|
||||||
|
|
||||||
// Always return PartialContent, even if the range covered the entire data length
|
|
||||||
// We were accidentally sending back 404 before in this situation
|
|
||||||
// https://issues.apache.org/bugzilla/show_bug.cgi?id=51878 supports sending 206 even if the
|
|
||||||
// entire range is requested, and viewer 3.2.2 (and very probably earlier) seems fine with this.
|
|
||||||
//
|
|
||||||
// We also do not want to send back OK even if the whole range was satisfiable since this causes
|
|
||||||
// HTTP textures on at least Imprudence 1.4.0-beta2 to never display the final texture quality.
|
|
||||||
// if (end > maxEnd)
|
|
||||||
// response.StatusCode = (int)System.Net.HttpStatusCode.OK;
|
|
||||||
// else
|
|
||||||
response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent;
|
|
||||||
|
|
||||||
response.ContentLength = len;
|
|
||||||
response.ContentType = texture.Metadata.ContentType;
|
|
||||||
response.AddHeader("Content-Range", String.Format("bytes {0}-{1}/{2}", start, end, texture.Data.Length));
|
|
||||||
response.RawBuffer = texture.Data;
|
|
||||||
response.RawBufferStart = start;
|
|
||||||
response.RawBufferLen = len;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_log.Warn("[GETTEXTURE]: Malformed Range header: " + range);
|
|
||||||
response.StatusCode = (int)System.Net.HttpStatusCode.BadRequest;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else // JP2's or other formats
|
|
||||||
{
|
|
||||||
// Full content request
|
|
||||||
response.StatusCode = (int)System.Net.HttpStatusCode.OK;
|
|
||||||
response.ContentLength = texture.Data.Length;
|
|
||||||
if (format == DefaultFormat)
|
|
||||||
response.ContentType = texture.Metadata.ContentType;
|
|
||||||
else
|
|
||||||
response.ContentType = "image/" + format;
|
|
||||||
response.RawBuffer = texture.Data;
|
|
||||||
response.RawBufferStart = 0;
|
|
||||||
response.RawBufferLen = texture.Data.Length;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if (response.StatusCode < 200 || response.StatusCode > 299)
|
|
||||||
// m_log.WarnFormat(
|
|
||||||
// "[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);
|
|
||||||
// else
|
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Parse a range header.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// As per http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html,
|
|
||||||
/// this obeys range headers with two values (e.g. 533-4165) and no second value (e.g. 533-).
|
|
||||||
/// Where there is no value, -1 is returned.
|
|
||||||
/// FIXME: Need to cover the case where only a second value is specified (e.g. -4165), probably by returning -1
|
|
||||||
/// for start.</remarks>
|
|
||||||
/// <returns></returns>
|
|
||||||
/// <param name='header'></param>
|
|
||||||
/// <param name='start'>Start of the range. Undefined if this was not a number.</param>
|
|
||||||
/// <param name='end'>End of the range. Will be -1 if no end specified. Undefined if there was a raw string but this was not a number.</param>
|
|
||||||
private bool TryParseRange(string header, out int start, out int end)
|
|
||||||
{
|
|
||||||
start = end = 0;
|
|
||||||
|
|
||||||
if (header.StartsWith("bytes="))
|
|
||||||
{
|
|
||||||
string[] rangeValues = header.Substring(6).Split('-');
|
|
||||||
|
|
||||||
if (rangeValues.Length == 2)
|
|
||||||
{
|
|
||||||
if (!Int32.TryParse(rangeValues[0], out start))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
string rawEnd = rangeValues[1];
|
|
||||||
|
|
||||||
if (rawEnd == "")
|
|
||||||
{
|
|
||||||
end = -1;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (Int32.TryParse(rawEnd, out end))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
start = end = 0;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private byte[] ConvertTextureData(AssetBase texture, string format)
|
|
||||||
{
|
|
||||||
m_log.DebugFormat("[GETTEXTURE]: Converting texture {0} to {1}", texture.ID, format);
|
|
||||||
byte[] data = new byte[0];
|
|
||||||
|
|
||||||
MemoryStream imgstream = new MemoryStream();
|
|
||||||
Bitmap mTexture = null;
|
|
||||||
ManagedImage managedImage = null;
|
|
||||||
Image image = null;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// Taking our jpeg2000 data, decoding it, then saving it to a byte array with regular data
|
|
||||||
// Decode image to System.Drawing.Image
|
|
||||||
if (OpenJPEG.DecodeToImage(texture.Data, out managedImage, out image) && image != null)
|
|
||||||
{
|
|
||||||
// Save to bitmap
|
|
||||||
mTexture = new Bitmap(image);
|
|
||||||
|
|
||||||
using(EncoderParameters myEncoderParameters = new EncoderParameters())
|
|
||||||
{
|
|
||||||
myEncoderParameters.Param[0] = new EncoderParameter(Encoder.Quality,95L);
|
|
||||||
|
|
||||||
// Save bitmap to stream
|
|
||||||
ImageCodecInfo codec = GetEncoderInfo("image/" + format);
|
|
||||||
if (codec != null)
|
|
||||||
{
|
|
||||||
mTexture.Save(imgstream, codec, myEncoderParameters);
|
|
||||||
// Write the stream to a byte array for output
|
|
||||||
data = imgstream.ToArray();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
m_log.WarnFormat("[GETTEXTURE]: No such codec {0}", format);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
m_log.WarnFormat("[GETTEXTURE]: Unable to convert texture {0} to {1}: {2}", texture.ID, format, e.Message);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
// Reclaim memory, these are unmanaged resources
|
|
||||||
// If we encountered an exception, one or more of these will be null
|
|
||||||
if (mTexture != null)
|
|
||||||
mTexture.Dispose();
|
|
||||||
|
|
||||||
if (image != null)
|
|
||||||
image.Dispose();
|
|
||||||
|
|
||||||
if(managedImage != null)
|
|
||||||
managedImage.Clear();
|
|
||||||
|
|
||||||
if (imgstream != null)
|
|
||||||
imgstream.Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
// From msdn
|
|
||||||
private static ImageCodecInfo GetEncoderInfo(String mimeType)
|
|
||||||
{
|
|
||||||
ImageCodecInfo[] encoders;
|
|
||||||
encoders = ImageCodecInfo.GetImageEncoders();
|
|
||||||
for (int j = 0; j < encoders.Length; ++j)
|
|
||||||
{
|
|
||||||
if (encoders[j].MimeType == mimeType)
|
|
||||||
return encoders[j];
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -33,7 +33,6 @@ using OpenSim.Framework.Servers.HttpServer;
|
||||||
using OpenSim.Server.Handlers.Base;
|
using OpenSim.Server.Handlers.Base;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
|
|
||||||
|
|
||||||
namespace OpenSim.Capabilities.Handlers
|
namespace OpenSim.Capabilities.Handlers
|
||||||
{
|
{
|
||||||
public class GetTextureServerConnector : ServiceConnector
|
public class GetTextureServerConnector : ServiceConnector
|
||||||
|
@ -66,8 +65,7 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
string rurl = serverConfig.GetString("GetTextureRedirectURL");
|
string rurl = serverConfig.GetString("GetTextureRedirectURL");
|
||||||
;
|
;
|
||||||
server.AddStreamHandler(
|
server.AddStreamHandler(
|
||||||
new GetTextureRobustHandler("/CAPS/GetTexture", m_AssetService, "GetTexture", null, rurl));
|
new GetTextureHandler("/CAPS/GetTexture/" /*+ UUID.Random() */, m_AssetService, "GetTexture", null, rurl));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,6 @@ using OpenSim.Framework.Servers.HttpServer;
|
||||||
using OpenSim.Region.Framework.Scenes;
|
using OpenSim.Region.Framework.Scenes;
|
||||||
using OpenSim.Tests.Common;
|
using OpenSim.Tests.Common;
|
||||||
|
|
||||||
/*
|
|
||||||
namespace OpenSim.Capabilities.Handlers.GetTexture.Tests
|
namespace OpenSim.Capabilities.Handlers.GetTexture.Tests
|
||||||
{
|
{
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
|
@ -60,5 +59,4 @@ namespace OpenSim.Capabilities.Handlers.GetTexture.Tests
|
||||||
Assert.That(resp.StatusCode, Is.EqualTo((int)System.Net.HttpStatusCode.NotFound));
|
Assert.That(resp.StatusCode, Is.EqualTo((int)System.Net.HttpStatusCode.NotFound));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
|
@ -2,7 +2,7 @@
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
// General Information about an assembly is controlled through the following
|
// General Information about an assembly is controlled through the following
|
||||||
// set of attributes. Change these attribute values to modify the information
|
// set of attributes. Change these attribute values to modify the information
|
||||||
// associated with an assembly.
|
// associated with an assembly.
|
||||||
[assembly: AssemblyTitle("OpenSim.Capabilities.Handlers")]
|
[assembly: AssemblyTitle("OpenSim.Capabilities.Handlers")]
|
||||||
|
@ -14,8 +14,8 @@ using System.Runtime.InteropServices;
|
||||||
[assembly: AssemblyTrademark("")]
|
[assembly: AssemblyTrademark("")]
|
||||||
[assembly: AssemblyCulture("")]
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
// Setting ComVisible to false makes the types in this assembly not visible
|
// Setting ComVisible to false makes the types in this assembly not visible
|
||||||
// to COM components. If you need to access a type in this assembly from
|
// to COM components. If you need to access a type in this assembly from
|
||||||
// COM, set the ComVisible attribute to true on that type.
|
// COM, set the ComVisible attribute to true on that type.
|
||||||
[assembly: ComVisible(false)]
|
[assembly: ComVisible(false)]
|
||||||
|
|
||||||
|
@ -25,9 +25,9 @@ using System.Runtime.InteropServices;
|
||||||
// Version information for an assembly consists of the following four values:
|
// Version information for an assembly consists of the following four values:
|
||||||
//
|
//
|
||||||
// Major Version
|
// Major Version
|
||||||
// Minor Version
|
// Minor Version
|
||||||
// Build Number
|
// Build Number
|
||||||
// Revision
|
// Revision
|
||||||
//
|
//
|
||||||
[assembly: AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)]
|
[assembly: AssemblyVersion("0.8.1.*")]
|
||||||
|
|
||||||
|
|
|
@ -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, IOSHttpRequest httpRequest, IOSHttpResponse 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, "UploadBakedTexture", null));
|
||||||
|
|
||||||
|
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.ErrorFormat("[UPLOAD BAKED TEXTURE HANDLER]: {0}{1}", e.Message, e.StackTrace);
|
||||||
|
}
|
||||||
|
|
||||||
|
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.DebugFormat("[UPLOAD BAKED TEXTURE HANDLER]: 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -29,35 +29,48 @@ using System;
|
||||||
using Nini.Config;
|
using Nini.Config;
|
||||||
using OpenSim.Server.Base;
|
using OpenSim.Server.Base;
|
||||||
using OpenSim.Services.Interfaces;
|
using OpenSim.Services.Interfaces;
|
||||||
using OpenSim.Framework.ServiceAuth;
|
|
||||||
using OpenSim.Framework.Servers.HttpServer;
|
using OpenSim.Framework.Servers.HttpServer;
|
||||||
using OpenSim.Server.Handlers.Base;
|
using OpenSim.Server.Handlers.Base;
|
||||||
|
using OpenMetaverse;
|
||||||
|
|
||||||
namespace OpenSim.Server.Handlers.GridUser
|
namespace OpenSim.Capabilities.Handlers
|
||||||
{
|
{
|
||||||
public class MuteListServiceConnector : ServiceConnector
|
public class UploadBakedTextureServerConnector : ServiceConnector
|
||||||
{
|
{
|
||||||
private IMuteListService m_MuteListService;
|
private IAssetService m_AssetService;
|
||||||
private string m_ConfigName = "MuteListService";
|
private string m_ConfigName = "CapsService";
|
||||||
|
|
||||||
public MuteListServiceConnector(IConfigSource config, IHttpServer server, string configName) :
|
public UploadBakedTextureServerConnector(IConfigSource config, IHttpServer server, string configName) :
|
||||||
base(config, server, configName)
|
base(config, server, configName)
|
||||||
{
|
{
|
||||||
|
if (configName != String.Empty)
|
||||||
|
m_ConfigName = configName;
|
||||||
|
|
||||||
IConfig serverConfig = config.Configs[m_ConfigName];
|
IConfig serverConfig = config.Configs[m_ConfigName];
|
||||||
if (serverConfig == null)
|
if (serverConfig == null)
|
||||||
throw new Exception(String.Format("No section {0} in config file", m_ConfigName));
|
throw new Exception(String.Format("No section '{0}' in config file", m_ConfigName));
|
||||||
|
|
||||||
string service = serverConfig.GetString("LocalServiceModule", String.Empty);
|
string assetService = serverConfig.GetString("AssetService", String.Empty);
|
||||||
|
|
||||||
if (service == String.Empty)
|
if (assetService == String.Empty)
|
||||||
throw new Exception("LocalServiceModule not present in MuteListService config file MuteListService section");
|
throw new Exception("No AssetService in config file");
|
||||||
|
|
||||||
Object[] args = new Object[] { config };
|
Object[] args = new Object[] { config };
|
||||||
m_MuteListService = ServerUtils.LoadPlugin<IMuteListService>(service, args);
|
m_AssetService =
|
||||||
|
ServerUtils.LoadPlugin<IAssetService>(assetService, args);
|
||||||
|
|
||||||
IServiceAuth auth = ServiceAuth.Create(config, m_ConfigName);
|
if (m_AssetService == null)
|
||||||
|
throw new Exception(String.Format("Failed to load AssetService from {0}; config is {1}", assetService, m_ConfigName));
|
||||||
|
|
||||||
server.AddStreamHandler(new MuteListServerPostHandler(m_MuteListService, auth));
|
// NEED TO FIX THIS
|
||||||
}
|
OpenSim.Framework.Capabilities.Caps caps = new OpenSim.Framework.Capabilities.Caps(server, "", server.Port, "", UUID.Zero, "");
|
||||||
|
server.AddStreamHandler(new RestStreamHandler(
|
||||||
|
"POST",
|
||||||
|
"/CAPS/UploadBakedTexture/",
|
||||||
|
new UploadBakedTextureHandler(caps, m_AssetService, true).UploadBakedTexture,
|
||||||
|
"UploadBakedTexture",
|
||||||
|
"Upload Baked Texture Capability"));
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -107,17 +107,17 @@ namespace OpenSim.Framework.Capabilities
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static byte[] LLSDSerialize(object obj)
|
public static byte[] LLSDSerialize(object obj)
|
||||||
{
|
{
|
||||||
using(StringWriter sw = new StringWriter())
|
StringWriter sw = new StringWriter();
|
||||||
using(XmlTextWriter writer = new XmlTextWriter(sw))
|
XmlTextWriter writer = new XmlTextWriter(sw);
|
||||||
{
|
writer.Formatting = Formatting.None;
|
||||||
writer.Formatting = Formatting.None;
|
|
||||||
|
|
||||||
writer.WriteStartElement(String.Empty, "llsd", String.Empty);
|
writer.WriteStartElement(String.Empty, "llsd", String.Empty);
|
||||||
LLSDWriteOne(writer, obj);
|
LLSDWriteOne(writer, obj);
|
||||||
writer.WriteEndElement();
|
writer.WriteEndElement();
|
||||||
writer.Flush();
|
|
||||||
return Util.UTF8.GetBytes(sw.ToString());
|
writer.Close();
|
||||||
}
|
|
||||||
|
return Util.UTF8.GetBytes(sw.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -566,7 +566,7 @@ namespace OpenSim.Framework.Capabilities
|
||||||
endPos = FindEnd(llsd, 1);
|
endPos = FindEnd(llsd, 1);
|
||||||
|
|
||||||
if (Double.TryParse(llsd.Substring(1, endPos - 1), NumberStyles.Float,
|
if (Double.TryParse(llsd.Substring(1, endPos - 1), NumberStyles.Float,
|
||||||
Culture.NumberFormatInfo, out value))
|
Utils.EnUsCulture.NumberFormat, out value))
|
||||||
return value;
|
return value;
|
||||||
else
|
else
|
||||||
throw new LLSDParseException("Failed to parse double value type");
|
throw new LLSDParseException("Failed to parse double value type");
|
||||||
|
|
|
@ -30,20 +30,13 @@ using OpenMetaverse;
|
||||||
|
|
||||||
namespace OpenSim.Framework.Capabilities
|
namespace OpenSim.Framework.Capabilities
|
||||||
{
|
{
|
||||||
|
|
||||||
[LLSDType("MAP")]
|
[LLSDType("MAP")]
|
||||||
public class LLSDAssetUploadComplete
|
public class LLSDAssetUploadComplete
|
||||||
{
|
{
|
||||||
public string new_asset = String.Empty;
|
public string new_asset = String.Empty;
|
||||||
public UUID new_inventory_item = UUID.Zero;
|
public UUID new_inventory_item = UUID.Zero;
|
||||||
// public UUID new_texture_folder_id = UUID.Zero;
|
|
||||||
public string state = String.Empty;
|
public string state = String.Empty;
|
||||||
public LLSDAssetUploadError error = null;
|
|
||||||
//public bool success = false;
|
//public bool success = false;
|
||||||
public int new_next_owner_mask = 0;
|
|
||||||
public int new_group_mask = 0;
|
|
||||||
public int new_everyone_mask = 0;
|
|
||||||
public int inventory_item_flags = 0;
|
|
||||||
|
|
||||||
public LLSDAssetUploadComplete()
|
public LLSDAssetUploadComplete()
|
||||||
{
|
{
|
||||||
|
|
|
@ -30,28 +30,15 @@ using OpenMetaverse;
|
||||||
|
|
||||||
namespace OpenSim.Framework.Capabilities
|
namespace OpenSim.Framework.Capabilities
|
||||||
{
|
{
|
||||||
[OSDMap]
|
|
||||||
public class LLSDAssetResource
|
|
||||||
{
|
|
||||||
public OSDArray instance_list = new OSDArray();
|
|
||||||
public OSDArray texture_list = new OSDArray();
|
|
||||||
public OSDArray mesh_list = new OSDArray();
|
|
||||||
public string metric = String.Empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
[OSDMap]
|
[OSDMap]
|
||||||
public class LLSDAssetUploadRequest
|
public class LLSDAssetUploadRequest
|
||||||
{
|
{
|
||||||
public string asset_type = String.Empty;
|
public string asset_type = String.Empty;
|
||||||
public string description = String.Empty;
|
public string description = String.Empty;
|
||||||
public UUID folder_id = UUID.Zero;
|
public UUID folder_id = UUID.Zero;
|
||||||
public UUID texture_folder_id = UUID.Zero;
|
|
||||||
public int next_owner_mask = 0;
|
|
||||||
public int group_mask = 0;
|
|
||||||
public int everyone_mask = 0;
|
|
||||||
public string inventory_type = String.Empty;
|
public string inventory_type = String.Empty;
|
||||||
public string name = String.Empty;
|
public string name = String.Empty;
|
||||||
public LLSDAssetResource asset_resources = new LLSDAssetResource();
|
|
||||||
public LLSDAssetUploadRequest()
|
public LLSDAssetUploadRequest()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,51 +26,20 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using OpenMetaverse;
|
|
||||||
|
|
||||||
namespace OpenSim.Framework.Capabilities
|
namespace OpenSim.Framework.Capabilities
|
||||||
{
|
{
|
||||||
[OSDMap]
|
|
||||||
public class LLSDAssetUploadError
|
|
||||||
{
|
|
||||||
public string message = String.Empty;
|
|
||||||
public UUID identifier = UUID.Zero;
|
|
||||||
}
|
|
||||||
|
|
||||||
[OSDMap]
|
|
||||||
public class LLSDAssetUploadResponsePricebrkDown
|
|
||||||
{
|
|
||||||
public int mesh_streaming;
|
|
||||||
public int mesh_physics;
|
|
||||||
public int mesh_instance;
|
|
||||||
public int texture;
|
|
||||||
public int model;
|
|
||||||
}
|
|
||||||
|
|
||||||
[OSDMap]
|
|
||||||
public class LLSDAssetUploadResponseData
|
|
||||||
{
|
|
||||||
public double resource_cost;
|
|
||||||
public double model_streaming_cost;
|
|
||||||
public double simulation_cost;
|
|
||||||
public double physics_cost;
|
|
||||||
public LLSDAssetUploadResponsePricebrkDown upload_price_breakdown = new LLSDAssetUploadResponsePricebrkDown();
|
|
||||||
}
|
|
||||||
|
|
||||||
[OSDMap]
|
[OSDMap]
|
||||||
public class LLSDAssetUploadResponse
|
public class LLSDAssetUploadResponse
|
||||||
{
|
{
|
||||||
public string uploader = String.Empty;
|
public string uploader = String.Empty;
|
||||||
public string state = String.Empty;
|
public string state = String.Empty;
|
||||||
public int upload_price = 0;
|
|
||||||
public LLSDAssetUploadResponseData data = null;
|
|
||||||
public LLSDAssetUploadError error = null;
|
|
||||||
public LLSDAssetUploadResponse()
|
public LLSDAssetUploadResponse()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[OSDMap]
|
[OSDMap]
|
||||||
public class LLSDNewFileAngentInventoryVariablePriceReplyResponse
|
public class LLSDNewFileAngentInventoryVariablePriceReplyResponse
|
||||||
{
|
{
|
||||||
|
@ -78,7 +47,7 @@ namespace OpenSim.Framework.Capabilities
|
||||||
public string state;
|
public string state;
|
||||||
public int upload_price;
|
public int upload_price;
|
||||||
public string rsvp;
|
public string rsvp;
|
||||||
|
|
||||||
public LLSDNewFileAngentInventoryVariablePriceReplyResponse()
|
public LLSDNewFileAngentInventoryVariablePriceReplyResponse()
|
||||||
{
|
{
|
||||||
state = "confirm_upload";
|
state = "confirm_upload";
|
||||||
|
|
|
@ -42,7 +42,7 @@ namespace OpenSim.Framework.Capabilities
|
||||||
{
|
{
|
||||||
public string username;
|
public string username;
|
||||||
public string display_name;
|
public string display_name;
|
||||||
//'display_name_next_update':d"1970-01-01T00:00:00Z"
|
//'display_name_next_update':d"1970-01-01T00:00:00Z"
|
||||||
public string legacy_first_name;
|
public string legacy_first_name;
|
||||||
public string legacy_last_name;
|
public string legacy_last_name;
|
||||||
public UUID id;
|
public UUID id;
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSimulator Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using OpenMetaverse;
|
||||||
|
|
||||||
|
namespace OpenSim.Framework.Capabilities
|
||||||
|
{
|
||||||
|
[OSDMap]
|
||||||
|
public class LLSDEnvironmentRequest
|
||||||
|
{
|
||||||
|
public UUID messageID;
|
||||||
|
public UUID regionID;
|
||||||
|
}
|
||||||
|
|
||||||
|
[OSDMap]
|
||||||
|
public class LLSDEnvironmentSetResponse
|
||||||
|
{
|
||||||
|
public UUID regionID;
|
||||||
|
public UUID messageID;
|
||||||
|
public Boolean success;
|
||||||
|
public String fail_reason;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class EnvironmentSettings
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// generates a empty llsd settings response for viewer
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="messageID">the message UUID</param>
|
||||||
|
/// <param name="regionID">the region UUID</param>
|
||||||
|
public static string EmptySettings(UUID messageID, UUID regionID)
|
||||||
|
{
|
||||||
|
OSDArray arr = new OSDArray();
|
||||||
|
LLSDEnvironmentRequest msg = new LLSDEnvironmentRequest();
|
||||||
|
msg.messageID = messageID;
|
||||||
|
msg.regionID = regionID;
|
||||||
|
arr.Array.Add(msg);
|
||||||
|
return LLSDHelpers.SerialiseLLSDReply(arr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -30,7 +30,6 @@ using System.Collections;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
using OpenMetaverse;
|
|
||||||
|
|
||||||
namespace OpenSim.Framework.Capabilities
|
namespace OpenSim.Framework.Capabilities
|
||||||
{
|
{
|
||||||
|
@ -41,32 +40,17 @@ namespace OpenSim.Framework.Capabilities
|
||||||
|
|
||||||
public static string SerialiseLLSDReply(object obj)
|
public static string SerialiseLLSDReply(object obj)
|
||||||
{
|
{
|
||||||
using(StringWriter sw = new StringWriter())
|
StringWriter sw = new StringWriter();
|
||||||
using(XmlTextWriter writer = new XmlTextWriter(sw))
|
XmlTextWriter writer = new XmlTextWriter(sw);
|
||||||
{
|
writer.Formatting = Formatting.None;
|
||||||
writer.Formatting = Formatting.None;
|
writer.WriteStartElement(String.Empty, "llsd", String.Empty);
|
||||||
writer.WriteStartElement(String.Empty, "llsd", String.Empty);
|
SerializeOSDType(writer, obj);
|
||||||
SerializeOSDType(writer, obj);
|
writer.WriteEndElement();
|
||||||
writer.WriteEndElement();
|
writer.Close();
|
||||||
writer.Flush();
|
|
||||||
//m_log.DebugFormat("[LLSD Helpers]: Generated serialized LLSD reply {0}", sw.ToString());
|
//m_log.DebugFormat("[LLSD Helpers]: Generated serialized LLSD reply {0}", sw.ToString());
|
||||||
|
|
||||||
return sw.ToString();
|
return sw.ToString();
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string SerialiseLLSDReplyNoHeader(object obj)
|
|
||||||
{
|
|
||||||
using(StringWriter sw = new StringWriter())
|
|
||||||
using(XmlTextWriter writer = new XmlTextWriter(sw))
|
|
||||||
{
|
|
||||||
writer.Formatting = Formatting.None;
|
|
||||||
SerializeOSDType(writer, obj);
|
|
||||||
writer.Flush();
|
|
||||||
//m_log.DebugFormat("[LLSD Helpers]: Generated serialized LLSD reply {0}", sw.ToString());
|
|
||||||
|
|
||||||
return sw.ToString();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void SerializeOSDType(XmlTextWriter writer, object obj)
|
private static void SerializeOSDType(XmlTextWriter writer, object obj)
|
||||||
|
@ -173,22 +157,6 @@ namespace OpenSim.Framework.Capabilities
|
||||||
// the LLSD map/array types in the array need to be deserialised
|
// the LLSD map/array types in the array need to be deserialised
|
||||||
// but first we need to know the right class to deserialise them into.
|
// but first we need to know the right class to deserialise them into.
|
||||||
}
|
}
|
||||||
else if(enumerator.Value is Boolean && field.FieldType == typeof(int) )
|
|
||||||
{
|
|
||||||
int i = (bool)enumerator.Value ? 1 : 0;
|
|
||||||
field.SetValue(obj, i);
|
|
||||||
}
|
|
||||||
else if(field.FieldType == typeof(bool) && enumerator.Value is int)
|
|
||||||
{
|
|
||||||
bool b = (int)enumerator.Value != 0;
|
|
||||||
field.SetValue(obj, b);
|
|
||||||
}
|
|
||||||
else if(field.FieldType == typeof(UUID) && enumerator.Value is string)
|
|
||||||
{
|
|
||||||
UUID u;
|
|
||||||
UUID.TryParse((string)enumerator.Value, out u);
|
|
||||||
field.SetValue(obj, u);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
field.SetValue(obj, enumerator.Value);
|
field.SetValue(obj, enumerator.Value);
|
||||||
|
|
|
@ -37,6 +37,5 @@ namespace OpenSim.Framework.Capabilities
|
||||||
public string name;
|
public string name;
|
||||||
public int type;
|
public int type;
|
||||||
public int preferred_type;
|
public int preferred_type;
|
||||||
public int version;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,12 +87,12 @@ namespace OpenSim.Framework.Capabilities
|
||||||
[OSDMap]
|
[OSDMap]
|
||||||
public class LLSDInventoryFolderContents
|
public class LLSDInventoryFolderContents
|
||||||
{
|
{
|
||||||
public UUID agent_id;
|
public UUID agent_id;
|
||||||
public int descendents;
|
public int descendents;
|
||||||
public UUID folder_id;
|
public UUID folder_id;
|
||||||
public OSDArray categories = new OSDArray();
|
public OSDArray categories = new OSDArray();
|
||||||
public OSDArray items = new OSDArray();
|
public OSDArray items = new OSDArray();
|
||||||
public UUID owner_id;
|
public UUID owner_id;
|
||||||
public int version;
|
public int version;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,11 +25,17 @@
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using OpenSim.Region.Framework.Scenes;
|
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
|
|
||||||
public interface IUserAccountCacheModule
|
namespace OpenSim.Framework.Capabilities
|
||||||
{
|
{
|
||||||
void Remove(string name);
|
[OSDMap]
|
||||||
void Remove(UUID id);
|
public class LLSDItemUpdate
|
||||||
|
{
|
||||||
|
public UUID item_id;
|
||||||
|
|
||||||
|
public LLSDItemUpdate()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSimulator Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System.Collections;
|
||||||
|
|
||||||
|
namespace OpenSim.Framework.Capabilities
|
||||||
|
{
|
||||||
|
[OSDMap]
|
||||||
|
public class LLSDParcelVoiceInfoResponse
|
||||||
|
{
|
||||||
|
public int parcel_local_id;
|
||||||
|
public string region_name;
|
||||||
|
public Hashtable voice_credentials;
|
||||||
|
|
||||||
|
public LLSDParcelVoiceInfoResponse()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public LLSDParcelVoiceInfoResponse(string region, int localID, Hashtable creds)
|
||||||
|
{
|
||||||
|
region_name = region;
|
||||||
|
parcel_local_id = localID;
|
||||||
|
voice_credentials = creds;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSimulator Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
using OpenMetaverse;
|
||||||
|
|
||||||
|
namespace OpenSim.Framework.Capabilities
|
||||||
|
{
|
||||||
|
[LLSDType("MAP")]
|
||||||
|
public class LLSDRemoteParcelResponse
|
||||||
|
{
|
||||||
|
public UUID parcel_id;
|
||||||
|
|
||||||
|
public LLSDRemoteParcelResponse()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -61,9 +61,6 @@ namespace OpenSim.Framework.Capabilities
|
||||||
// OpenMetaverse.StructuredData.LLSDParser.DeserializeXml(new XmlTextReader(request));
|
// OpenMetaverse.StructuredData.LLSDParser.DeserializeXml(new XmlTextReader(request));
|
||||||
|
|
||||||
Hashtable hash = (Hashtable) LLSD.LLSDDeserialize(request);
|
Hashtable hash = (Hashtable) LLSD.LLSDDeserialize(request);
|
||||||
if(hash == null)
|
|
||||||
return new byte[0];
|
|
||||||
|
|
||||||
TRequest llsdRequest = new TRequest();
|
TRequest llsdRequest = new TRequest();
|
||||||
LLSDHelpers.DeserialiseOSDMap(hash, llsdRequest);
|
LLSDHelpers.DeserialiseOSDMap(hash, llsdRequest);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSimulator Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using OpenMetaverse;
|
||||||
|
|
||||||
|
namespace OpenSim.Framework.Capabilities
|
||||||
|
{
|
||||||
|
[OSDMap]
|
||||||
|
public class LLSDTaskScriptUpdate
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The item containing the script to update
|
||||||
|
/// </summary>
|
||||||
|
public UUID item_id;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The task containing the script
|
||||||
|
/// </summary>
|
||||||
|
public UUID task_id;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Signals whether the script is currently active
|
||||||
|
/// </summary>
|
||||||
|
public int is_script_running;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSimulator Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace OpenSim.Framework.Capabilities
|
||||||
|
{
|
||||||
|
[OSDMap]
|
||||||
|
public class LLSDVoiceAccountResponse
|
||||||
|
{
|
||||||
|
public string username;
|
||||||
|
public string password;
|
||||||
|
public string voice_sip_uri_hostname;
|
||||||
|
public string voice_account_server_name;
|
||||||
|
|
||||||
|
public LLSDVoiceAccountResponse()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public LLSDVoiceAccountResponse(string user, string pass)
|
||||||
|
{
|
||||||
|
username = user;
|
||||||
|
password = pass;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LLSDVoiceAccountResponse(string user, string pass, string sipUriHost, string accountServer)
|
||||||
|
{
|
||||||
|
username = user;
|
||||||
|
password = pass;
|
||||||
|
voice_sip_uri_hostname = sipUriHost;
|
||||||
|
voice_account_server_name = accountServer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,7 +2,7 @@
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
// General Information about an assembly is controlled through the following
|
// General Information about an assembly is controlled through the following
|
||||||
// set of attributes. Change these attribute values to modify the information
|
// set of attributes. Change these attribute values to modify the information
|
||||||
// associated with an assembly.
|
// associated with an assembly.
|
||||||
[assembly: AssemblyTitle("OpenSim.Capabilities")]
|
[assembly: AssemblyTitle("OpenSim.Capabilities")]
|
||||||
|
@ -14,8 +14,8 @@ using System.Runtime.InteropServices;
|
||||||
[assembly: AssemblyTrademark("")]
|
[assembly: AssemblyTrademark("")]
|
||||||
[assembly: AssemblyCulture("")]
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
// Setting ComVisible to false makes the types in this assembly not visible
|
// Setting ComVisible to false makes the types in this assembly not visible
|
||||||
// to COM components. If you need to access a type in this assembly from
|
// to COM components. If you need to access a type in this assembly from
|
||||||
// COM, set the ComVisible attribute to true on that type.
|
// COM, set the ComVisible attribute to true on that type.
|
||||||
[assembly: ComVisible(false)]
|
[assembly: ComVisible(false)]
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ using System.Runtime.InteropServices;
|
||||||
// Version information for an assembly consists of the following four values:
|
// Version information for an assembly consists of the following four values:
|
||||||
//
|
//
|
||||||
// Major Version
|
// Major Version
|
||||||
// Minor Version
|
// Minor Version
|
||||||
// Build Number
|
// Build Number
|
||||||
// Revision
|
// Revision
|
||||||
//
|
//
|
||||||
|
|
|
@ -80,7 +80,7 @@ namespace OpenSim.ConsoleClient
|
||||||
while (m_Server.Running)
|
while (m_Server.Running)
|
||||||
{
|
{
|
||||||
System.Threading.Thread.Sleep(500);
|
System.Threading.Thread.Sleep(500);
|
||||||
MainConsole.Instance.Prompt();
|
// MainConsole.Instance.Prompt();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pidFile != String.Empty)
|
if (pidFile != String.Empty)
|
||||||
|
@ -178,7 +178,7 @@ namespace OpenSim.ConsoleClient
|
||||||
Requester.MakeRequest(requestUrl, requestData, ReadResponses);
|
Requester.MakeRequest(requestUrl, requestData, ReadResponses);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<string> lines = new List<string>();
|
List<string> lines = new List<string>();
|
||||||
|
|
||||||
foreach (XmlNode part in rootNodeL[0].ChildNodes)
|
foreach (XmlNode part in rootNodeL[0].ChildNodes)
|
||||||
|
@ -202,7 +202,7 @@ namespace OpenSim.ConsoleClient
|
||||||
string[] parts = l.Split(new char[] {':'}, 3);
|
string[] parts = l.Split(new char[] {':'}, 3);
|
||||||
if (parts.Length != 3)
|
if (parts.Length != 3)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (parts[2].StartsWith("+++") || parts[2].StartsWith("-++"))
|
if (parts[2].StartsWith("+++") || parts[2].StartsWith("-++"))
|
||||||
prompt = parts[2];
|
prompt = parts[2];
|
||||||
else
|
else
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
// General Information about an assembly is controlled through the following
|
// General Information about an assembly is controlled through the following
|
||||||
// set of attributes. Change these attribute values to modify the information
|
// set of attributes. Change these attribute values to modify the information
|
||||||
// associated with an assembly.
|
// associated with an assembly.
|
||||||
[assembly: AssemblyTitle("OpenSim.ConsoleClient")]
|
[assembly: AssemblyTitle("OpenSim.ConsoleClient")]
|
||||||
|
@ -14,8 +14,8 @@ using System.Runtime.InteropServices;
|
||||||
[assembly: AssemblyTrademark("")]
|
[assembly: AssemblyTrademark("")]
|
||||||
[assembly: AssemblyCulture("")]
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
// Setting ComVisible to false makes the types in this assembly not visible
|
// Setting ComVisible to false makes the types in this assembly not visible
|
||||||
// to COM components. If you need to access a type in this assembly from
|
// to COM components. If you need to access a type in this assembly from
|
||||||
// COM, set the ComVisible attribute to true on that type.
|
// COM, set the ComVisible attribute to true on that type.
|
||||||
[assembly: ComVisible(false)]
|
[assembly: ComVisible(false)]
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ using System.Runtime.InteropServices;
|
||||||
// Version information for an assembly consists of the following four values:
|
// Version information for an assembly consists of the following four values:
|
||||||
//
|
//
|
||||||
// Major Version
|
// Major Version
|
||||||
// Minor Version
|
// Minor Version
|
||||||
// Build Number
|
// Build Number
|
||||||
// Revision
|
// Revision
|
||||||
//
|
//
|
||||||
|
|
|
@ -37,7 +37,7 @@ namespace OpenSim.Data
|
||||||
public abstract class AssetDataBase : IAssetDataPlugin
|
public abstract class AssetDataBase : IAssetDataPlugin
|
||||||
{
|
{
|
||||||
public abstract AssetBase GetAsset(UUID uuid);
|
public abstract AssetBase GetAsset(UUID uuid);
|
||||||
public abstract bool StoreAsset(AssetBase asset);
|
public abstract void StoreAsset(AssetBase asset);
|
||||||
public abstract bool[] AssetsExist(UUID[] uuids);
|
public abstract bool[] AssetsExist(UUID[] uuids);
|
||||||
|
|
||||||
public abstract List<AssetMetadata> FetchAssetMetadataSet(int start, int count);
|
public abstract List<AssetMetadata> FetchAssetMetadataSet(int start, int count);
|
||||||
|
|
|
@ -38,7 +38,7 @@ namespace OpenSim.Data
|
||||||
/// <summary>This function converts a value returned from the database in one of the
|
/// <summary>This function converts a value returned from the database in one of the
|
||||||
/// supported formats into a UUID. This function is not actually DBMS-specific right
|
/// supported formats into a UUID. This function is not actually DBMS-specific right
|
||||||
/// now
|
/// now
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="id"></param>
|
/// <param name="id"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
|
@ -47,25 +47,24 @@ namespace OpenSim.Data
|
||||||
if ((id == null) || (id == DBNull.Value))
|
if ((id == null) || (id == DBNull.Value))
|
||||||
return UUID.Zero;
|
return UUID.Zero;
|
||||||
|
|
||||||
Type idtype = id.GetType();
|
if (id.GetType() == typeof(Guid))
|
||||||
|
|
||||||
if (idtype == typeof(Guid))
|
|
||||||
return new UUID((Guid)id);
|
return new UUID((Guid)id);
|
||||||
|
|
||||||
if (id.GetType() == typeof(string))
|
if (id.GetType() == typeof(byte[]))
|
||||||
{
|
{
|
||||||
Guid gg;
|
if (((byte[])id).Length == 0)
|
||||||
if (Guid.TryParse((string)id, out gg))
|
return UUID.Zero;
|
||||||
return new UUID(gg);
|
else if (((byte[])id).Length == 16)
|
||||||
return UUID.Zero;
|
return new UUID((byte[])id, 0);
|
||||||
|
}
|
||||||
|
else if (id.GetType() == typeof(string))
|
||||||
|
{
|
||||||
|
if (((string)id).Length == 0)
|
||||||
|
return UUID.Zero;
|
||||||
|
else if (((string)id).Length == 36)
|
||||||
|
return new UUID((string)id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (idtype == typeof(byte[]))
|
|
||||||
{
|
|
||||||
if (((byte[])id).Length < 16)
|
|
||||||
return UUID.Zero;
|
|
||||||
return new UUID((byte[])id, 0);
|
|
||||||
}
|
|
||||||
throw new Exception("Failed to convert db value to UUID: " + id.ToString());
|
throw new Exception("Failed to convert db value to UUID: " + id.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@ namespace OpenSim.Data
|
||||||
public interface IAssetDataPlugin : IPlugin
|
public interface IAssetDataPlugin : IPlugin
|
||||||
{
|
{
|
||||||
AssetBase GetAsset(UUID uuid);
|
AssetBase GetAsset(UUID uuid);
|
||||||
bool StoreAsset(AssetBase asset);
|
void StoreAsset(AssetBase asset);
|
||||||
bool[] AssetsExist(UUID[] uuids);
|
bool[] AssetsExist(UUID[] uuids);
|
||||||
List<AssetMetadata> FetchAssetMetadataSet(int start, int count);
|
List<AssetMetadata> FetchAssetMetadataSet(int start, int count);
|
||||||
void Initialise(string connect);
|
void Initialise(string connect);
|
||||||
|
|
|
@ -39,7 +39,7 @@ namespace OpenSim.Data
|
||||||
public Dictionary<string, string> Data;
|
public Dictionary<string, string> Data;
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface IAvatarData
|
public interface IAvatarData
|
||||||
{
|
{
|
||||||
AvatarBaseData[] Get(string field, string val);
|
AvatarBaseData[] Get(string field, string val);
|
||||||
bool Store(AvatarBaseData data);
|
bool Store(AvatarBaseData data);
|
||||||
|
|
|
@ -46,14 +46,14 @@ namespace OpenSim.Data
|
||||||
/// <param name="create">If true, then an estate is created if one is not found.</param>
|
/// <param name="create">If true, then an estate is created if one is not found.</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
EstateSettings LoadEstateSettings(UUID regionID, bool create);
|
EstateSettings LoadEstateSettings(UUID regionID, bool create);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Load estate settings for an estate ID.
|
/// Load estate settings for an estate ID.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="estateID"></param>
|
/// <param name="estateID"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
EstateSettings LoadEstateSettings(int estateID);
|
EstateSettings LoadEstateSettings(int estateID);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create a new estate.
|
/// Create a new estate.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -67,7 +67,7 @@ namespace OpenSim.Data
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>An empty list if no estates were found.</returns>
|
/// <returns>An empty list if no estates were found.</returns>
|
||||||
List<EstateSettings> LoadEstateSettingsAll();
|
List<EstateSettings> LoadEstateSettingsAll();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Store estate settings.
|
/// Store estate settings.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -75,7 +75,7 @@ namespace OpenSim.Data
|
||||||
/// This is also called by EstateSettings.Save()</remarks>
|
/// This is also called by EstateSettings.Save()</remarks>
|
||||||
/// <param name="es"></param>
|
/// <param name="es"></param>
|
||||||
void StoreEstateSettings(EstateSettings es);
|
void StoreEstateSettings(EstateSettings es);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get estate IDs.
|
/// Get estate IDs.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -88,13 +88,13 @@ namespace OpenSim.Data
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>An empty list if no estates were found.</returns>
|
/// <returns>An empty list if no estates were found.</returns>
|
||||||
List<int> GetEstatesByOwner(UUID ownerID);
|
List<int> GetEstatesByOwner(UUID ownerID);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get the IDs of all estates.
|
/// Get the IDs of all estates.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>An empty list if no estates were found.</returns>
|
/// <returns>An empty list if no estates were found.</returns>
|
||||||
List<int> GetEstatesAll();
|
List<int> GetEstatesAll();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Link a region to an estate.
|
/// Link a region to an estate.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -102,14 +102,14 @@ namespace OpenSim.Data
|
||||||
/// <param name="estateID"></param>
|
/// <param name="estateID"></param>
|
||||||
/// <returns>true if the link succeeded, false otherwise</returns>
|
/// <returns>true if the link succeeded, false otherwise</returns>
|
||||||
bool LinkRegion(UUID regionID, int estateID);
|
bool LinkRegion(UUID regionID, int estateID);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get the UUIDs of all the regions in an estate.
|
/// Get the UUIDs of all the regions in an estate.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="estateID"></param>
|
/// <param name="estateID"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
List<UUID> GetRegions(int estateID);
|
List<UUID> GetRegions(int estateID);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Delete an estate
|
/// Delete an estate
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -1,47 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
* * Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* * Neither the name of the OpenSimulator Project nor the
|
|
||||||
* names of its contributors may be used to endorse or promote products
|
|
||||||
* derived from this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
|
||||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using OpenMetaverse;
|
|
||||||
using OpenSim.Framework;
|
|
||||||
|
|
||||||
namespace OpenSim.Data
|
|
||||||
{
|
|
||||||
public delegate string FSStoreDelegate(AssetBase asset, bool force);
|
|
||||||
|
|
||||||
public interface IFSAssetDataPlugin : IPlugin
|
|
||||||
{
|
|
||||||
bool[] AssetsExist(UUID[] uuids);
|
|
||||||
void Initialise(string connect, string realm, int SkipAccessTimeDays);
|
|
||||||
bool Delete(string id);
|
|
||||||
|
|
||||||
AssetMetadata Get(string id, out string hash);
|
|
||||||
bool Store(AssetMetadata metadata, string hash);
|
|
||||||
void Import(string conn, string table, int start, int count, bool force, FSStoreDelegate store);
|
|
||||||
int Count();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -47,7 +47,7 @@ namespace OpenSim.Data
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// An interface for connecting to the user grid datastore
|
/// An interface for connecting to the user grid datastore
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IGridUserData
|
public interface IGridUserData
|
||||||
{
|
{
|
||||||
GridUserData Get(string userID);
|
GridUserData Get(string userID);
|
||||||
GridUserData[] GetAll(string query);
|
GridUserData[] GetAll(string query);
|
||||||
|
|
|
@ -81,7 +81,7 @@ namespace OpenSim.Data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public interface IGroupsData
|
public interface IGroupsData
|
||||||
{
|
{
|
||||||
// groups table
|
// groups table
|
||||||
bool StoreGroup(GroupData data);
|
bool StoreGroup(GroupData data);
|
||||||
|
|
|
@ -48,7 +48,7 @@ namespace OpenSim.Data
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// An interface for connecting to the user grid datastore
|
/// An interface for connecting to the user grid datastore
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IHGTravelingData
|
public interface IHGTravelingData
|
||||||
{
|
{
|
||||||
HGTravelingData Get(UUID sessionID);
|
HGTravelingData Get(UUID sessionID);
|
||||||
HGTravelingData[] GetSessions(UUID userID);
|
HGTravelingData[] GetSessions(UUID userID);
|
||||||
|
|
|
@ -39,7 +39,7 @@ namespace OpenSim.Data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public interface IOfflineIMData
|
public interface IOfflineIMData
|
||||||
{
|
{
|
||||||
OfflineIMData[] Get(string field, string val);
|
OfflineIMData[] Get(string field, string val);
|
||||||
long GetCount(string field, string key);
|
long GetCount(string field, string key);
|
||||||
|
|
|
@ -44,7 +44,7 @@ namespace OpenSim.Data
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// An interface for connecting to the presence datastore
|
/// An interface for connecting to the presence datastore
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IPresenceData
|
public interface IPresenceData
|
||||||
{
|
{
|
||||||
bool Store(PresenceData data);
|
bool Store(PresenceData data);
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,7 @@ namespace OpenSim.Data
|
||||||
bool UpdateAvatarProperties(ref UserProfileProperties props, ref string result);
|
bool UpdateAvatarProperties(ref UserProfileProperties props, ref string result);
|
||||||
bool UpdateAvatarInterests(UserProfileProperties up, ref string result);
|
bool UpdateAvatarInterests(UserProfileProperties up, ref string result);
|
||||||
bool GetClassifiedInfo(ref UserClassifiedAdd ad, ref string result);
|
bool GetClassifiedInfo(ref UserClassifiedAdd ad, ref string result);
|
||||||
bool UpdateUserPreferences(ref UserPreferences pref, ref string result);
|
bool UpdateUserPreferences(ref UserPreferences pref, ref string result);
|
||||||
bool GetUserPreferences(ref UserPreferences pref, ref string result);
|
bool GetUserPreferences(ref UserPreferences pref, ref string result);
|
||||||
bool GetUserAppData(ref UserAppData props, ref string result);
|
bool GetUserAppData(ref UserAppData props, ref string result);
|
||||||
bool SetUserAppData(UserAppData props, ref string result);
|
bool SetUserAppData(UserAppData props, ref string result);
|
||||||
|
|
|
@ -67,12 +67,10 @@ namespace OpenSim.Data
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// An interface for connecting to the authentication datastore
|
/// An interface for connecting to the authentication datastore
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IRegionData
|
public interface IRegionData
|
||||||
{
|
{
|
||||||
RegionData Get(UUID regionID, UUID ScopeID);
|
RegionData Get(UUID regionID, UUID ScopeID);
|
||||||
List<RegionData> Get(string regionName, UUID ScopeID);
|
List<RegionData> Get(string regionName, UUID ScopeID);
|
||||||
RegionData GetSpecific(string regionName, UUID ScopeID);
|
|
||||||
|
|
||||||
RegionData Get(int x, int y, UUID ScopeID);
|
RegionData Get(int x, int y, UUID ScopeID);
|
||||||
List<RegionData> Get(int xStart, int yStart, int xEnd, int yEnd, UUID ScopeID);
|
List<RegionData> Get(int xStart, int yStart, int xEnd, int yEnd, UUID ScopeID);
|
||||||
|
|
||||||
|
|
|
@ -50,6 +50,5 @@ namespace OpenSim.Data
|
||||||
bool Store(UserAccountData data);
|
bool Store(UserAccountData data);
|
||||||
bool Delete(string field, string val);
|
bool Delete(string field, string val);
|
||||||
UserAccountData[] GetUsers(UUID scopeID, string query);
|
UserAccountData[] GetUsers(UUID scopeID, string query);
|
||||||
UserAccountData[] GetUsersWhere(UUID scopeID, string where);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,12 +38,12 @@ namespace OpenSim.Data
|
||||||
public UUID ownerRoleID;
|
public UUID ownerRoleID;
|
||||||
public string name;
|
public string name;
|
||||||
public string charter;
|
public string charter;
|
||||||
public bool showInList;
|
public bool showInList;
|
||||||
public UUID insigniaID;
|
public UUID insigniaID;
|
||||||
public int membershipFee;
|
public int membershipFee;
|
||||||
public bool openEnrollment;
|
public bool openEnrollment;
|
||||||
public bool allowPublish;
|
public bool allowPublish;
|
||||||
public bool maturePublish;
|
public bool maturePublish;
|
||||||
public UUID founderID;
|
public UUID founderID;
|
||||||
public ulong everyonePowers;
|
public ulong everyonePowers;
|
||||||
public ulong ownersPowers;
|
public ulong ownersPowers;
|
||||||
|
|
|
@ -80,10 +80,10 @@ namespace OpenSim.Data
|
||||||
|
|
||||||
/// <summary>Have the parameterless constructor just so we can specify it as a generic parameter with the new() constraint.
|
/// <summary>Have the parameterless constructor just so we can specify it as a generic parameter with the new() constraint.
|
||||||
/// Currently this is only used in the tests. A Migration instance created this way must be then
|
/// Currently this is only used in the tests. A Migration instance created this way must be then
|
||||||
/// initialized with Initialize(). Regular creation should be through the parameterized constructors.
|
/// initialized with Initialize(). Regular creation should be through the parameterized constructors.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Migration()
|
public Migration()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public Migration(DbConnection conn, Assembly assem, string subtype, string type)
|
public Migration(DbConnection conn, Assembly assem, string subtype, string type)
|
||||||
|
@ -91,7 +91,7 @@ namespace OpenSim.Data
|
||||||
Initialize(conn, assem, type, subtype);
|
Initialize(conn, assem, type, subtype);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Migration(DbConnection conn, Assembly assem, string type)
|
public Migration(DbConnection conn, Assembly assem, string type)
|
||||||
{
|
{
|
||||||
Initialize(conn, assem, type, "");
|
Initialize(conn, assem, type, "");
|
||||||
}
|
}
|
||||||
|
@ -191,7 +191,7 @@ namespace OpenSim.Data
|
||||||
int newversion = kvp.Key;
|
int newversion = kvp.Key;
|
||||||
// we need to up the command timeout to infinite as we might be doing long migrations.
|
// we need to up the command timeout to infinite as we might be doing long migrations.
|
||||||
|
|
||||||
/* [AlexRa 01-May-10]: We can't always just run any SQL in a single batch (= ExecuteNonQuery()). Things like
|
/* [AlexRa 01-May-10]: We can't always just run any SQL in a single batch (= ExecuteNonQuery()). Things like
|
||||||
* stored proc definitions might have to be sent to the server each in a separate batch.
|
* stored proc definitions might have to be sent to the server each in a separate batch.
|
||||||
* This is certainly so for MS SQL; not sure how the MySQL connector sorts out the mess
|
* This is certainly so for MS SQL; not sure how the MySQL connector sorts out the mess
|
||||||
* with 'delimiter @@'/'delimiter ;' around procs. So each "script" this code executes now is not
|
* with 'delimiter @@'/'delimiter ;' around procs. So each "script" this code executes now is not
|
||||||
|
@ -276,7 +276,7 @@ namespace OpenSim.Data
|
||||||
private delegate void FlushProc();
|
private delegate void FlushProc();
|
||||||
|
|
||||||
/// <summary>Scans for migration resources in either old-style "scattered" (one file per version)
|
/// <summary>Scans for migration resources in either old-style "scattered" (one file per version)
|
||||||
/// or new-style "integrated" format (single file with ":VERSION nnn" sections).
|
/// or new-style "integrated" format (single file with ":VERSION nnn" sections).
|
||||||
/// In the new-style migrations it also recognizes ':GO' separators for parts of the SQL script
|
/// In the new-style migrations it also recognizes ':GO' separators for parts of the SQL script
|
||||||
/// that must be sent to the server separately. The old-style migrations are loaded each in one piece
|
/// that must be sent to the server separately. The old-style migrations are loaded each in one piece
|
||||||
/// and don't support the ':GO' feature.
|
/// and don't support the ':GO' feature.
|
||||||
|
@ -301,12 +301,12 @@ namespace OpenSim.Data
|
||||||
{
|
{
|
||||||
/* The filename should be '<StoreName>.migrations[.NNN]' where NNN
|
/* The filename should be '<StoreName>.migrations[.NNN]' where NNN
|
||||||
* is the last version number defined in the file. If the '.NNN' part is recognized, the code can skip
|
* is the last version number defined in the file. If the '.NNN' part is recognized, the code can skip
|
||||||
* the file without looking inside if we have a higher version already. Without the suffix we read
|
* the file without looking inside if we have a higher version already. Without the suffix we read
|
||||||
* the file anyway and use the version numbers inside. Any unrecognized suffix (such as '.sql')
|
* the file anyway and use the version numbers inside. Any unrecognized suffix (such as '.sql')
|
||||||
* is valid but ignored.
|
* is valid but ignored.
|
||||||
*
|
*
|
||||||
* NOTE that we expect only one 'merged' migration file. If there are several, we take the last one.
|
* NOTE that we expect only one 'merged' migration file. If there are several, we take the last one.
|
||||||
* If you are numbering them, leave only the latest one in the project or at least make sure they numbered
|
* If you are numbering them, leave only the latest one in the project or at least make sure they numbered
|
||||||
* to come up in the correct order (e.g. 'SomeStore.migrations.001' rather than 'SomeStore.migrations.1')
|
* to come up in the correct order (e.g. 'SomeStore.migrations.001' rather than 'SomeStore.migrations.1')
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -351,7 +351,7 @@ namespace OpenSim.Data
|
||||||
if (sLine.Trim().Equals(":GO", StringComparison.InvariantCultureIgnoreCase))
|
if (sLine.Trim().Equals(":GO", StringComparison.InvariantCultureIgnoreCase))
|
||||||
{
|
{
|
||||||
if (sb.Length == 0) continue;
|
if (sb.Length == 0) continue;
|
||||||
if (nVersion > after)
|
if (nVersion > after)
|
||||||
script.Add(sb.ToString());
|
script.Add(sb.ToString());
|
||||||
sb.Length = 0;
|
sb.Length = 0;
|
||||||
continue;
|
continue;
|
||||||
|
@ -405,10 +405,10 @@ scan_old_style:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (migrations.Count < 1)
|
if (migrations.Count < 1)
|
||||||
m_log.DebugFormat("[MIGRATIONS]: {0} data tables already up to date at revision {1}", _type, after);
|
m_log.DebugFormat("[MIGRATIONS]: {0} data tables already up to date at revision {1}", _type, after);
|
||||||
|
|
||||||
return migrations;
|
return migrations;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,7 +75,6 @@ namespace OpenSim.Data.MySQL
|
||||||
dbcon.Open();
|
dbcon.Open();
|
||||||
Migration m = new Migration(dbcon, Assembly, "AssetStore");
|
Migration m = new Migration(dbcon, Assembly, "AssetStore");
|
||||||
m.Update();
|
m.Update();
|
||||||
dbcon.Close();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,7 +144,6 @@ namespace OpenSim.Data.MySQL
|
||||||
string.Format("[ASSETS DB]: MySql failure fetching asset {0}. Exception ", assetID), e);
|
string.Format("[ASSETS DB]: MySql failure fetching asset {0}. Exception ", assetID), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dbcon.Close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return asset;
|
return asset;
|
||||||
|
@ -156,62 +154,65 @@ namespace OpenSim.Data.MySQL
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="asset">Asset UUID to create</param>
|
/// <param name="asset">Asset UUID to create</param>
|
||||||
/// <remarks>On failure : Throw an exception and attempt to reconnect to database</remarks>
|
/// <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)
|
||||||
{
|
{
|
||||||
string assetName = asset.Name;
|
|
||||||
if (asset.Name.Length > AssetBase.MAX_ASSET_NAME)
|
|
||||||
{
|
|
||||||
assetName = asset.Name.Substring(0, AssetBase.MAX_ASSET_NAME);
|
|
||||||
m_log.WarnFormat(
|
|
||||||
"[ASSET DB]: Name '{0}' for asset {1} truncated from {2} to {3} characters on add",
|
|
||||||
asset.Name, asset.ID, asset.Name.Length, assetName.Length);
|
|
||||||
}
|
|
||||||
|
|
||||||
string assetDescription = asset.Description;
|
|
||||||
if (asset.Description.Length > AssetBase.MAX_ASSET_DESC)
|
|
||||||
{
|
|
||||||
assetDescription = asset.Description.Substring(0, AssetBase.MAX_ASSET_DESC);
|
|
||||||
m_log.WarnFormat(
|
|
||||||
"[ASSET DB]: Description '{0}' for asset {1} truncated from {2} to {3} characters on add",
|
|
||||||
asset.Description, asset.ID, asset.Description.Length, assetDescription.Length);
|
|
||||||
}
|
|
||||||
|
|
||||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||||
{
|
{
|
||||||
dbcon.Open();
|
dbcon.Open();
|
||||||
|
|
||||||
using (MySqlCommand cmd =
|
using (MySqlCommand cmd =
|
||||||
new MySqlCommand(
|
new MySqlCommand(
|
||||||
"replace INTO assets(id, name, description, assetType, local, temporary, create_time, access_time, asset_flags, CreatorID, data)" +
|
"replace INTO assets(id, name, description, assetType, local, temporary, create_time, access_time, asset_flags, CreatorID, data)" +
|
||||||
"VALUES(?id, ?name, ?description, ?assetType, ?local, ?temporary, ?create_time, ?access_time, ?asset_flags, ?CreatorID, ?data)",
|
"VALUES(?id, ?name, ?description, ?assetType, ?local, ?temporary, ?create_time, ?access_time, ?asset_flags, ?CreatorID, ?data)",
|
||||||
dbcon))
|
dbcon))
|
||||||
{
|
{
|
||||||
|
string assetName = asset.Name;
|
||||||
|
if (asset.Name.Length > AssetBase.MAX_ASSET_NAME)
|
||||||
|
{
|
||||||
|
assetName = asset.Name.Substring(0, AssetBase.MAX_ASSET_NAME);
|
||||||
|
m_log.WarnFormat(
|
||||||
|
"[ASSET DB]: Name '{0}' for asset {1} truncated from {2} to {3} characters on add",
|
||||||
|
asset.Name, asset.ID, asset.Name.Length, assetName.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
string assetDescription = asset.Description;
|
||||||
|
if (asset.Description.Length > AssetBase.MAX_ASSET_DESC)
|
||||||
|
{
|
||||||
|
assetDescription = asset.Description.Substring(0, AssetBase.MAX_ASSET_DESC);
|
||||||
|
m_log.WarnFormat(
|
||||||
|
"[ASSET DB]: Description '{0}' for asset {1} truncated from {2} to {3} characters on add",
|
||||||
|
asset.Description, asset.ID, asset.Description.Length, assetDescription.Length);
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// create unix epoch time
|
using (cmd)
|
||||||
int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow);
|
{
|
||||||
cmd.Parameters.AddWithValue("?id", asset.ID);
|
// create unix epoch time
|
||||||
cmd.Parameters.AddWithValue("?name", assetName);
|
int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow);
|
||||||
cmd.Parameters.AddWithValue("?description", assetDescription);
|
cmd.Parameters.AddWithValue("?id", asset.ID);
|
||||||
cmd.Parameters.AddWithValue("?assetType", asset.Type);
|
cmd.Parameters.AddWithValue("?name", assetName);
|
||||||
cmd.Parameters.AddWithValue("?local", asset.Local);
|
cmd.Parameters.AddWithValue("?description", assetDescription);
|
||||||
cmd.Parameters.AddWithValue("?temporary", asset.Temporary);
|
cmd.Parameters.AddWithValue("?assetType", asset.Type);
|
||||||
cmd.Parameters.AddWithValue("?create_time", now);
|
cmd.Parameters.AddWithValue("?local", asset.Local);
|
||||||
cmd.Parameters.AddWithValue("?access_time", now);
|
cmd.Parameters.AddWithValue("?temporary", asset.Temporary);
|
||||||
cmd.Parameters.AddWithValue("?CreatorID", asset.Metadata.CreatorID);
|
cmd.Parameters.AddWithValue("?create_time", now);
|
||||||
cmd.Parameters.AddWithValue("?asset_flags", (int)asset.Flags);
|
cmd.Parameters.AddWithValue("?access_time", now);
|
||||||
cmd.Parameters.AddWithValue("?data", asset.Data);
|
cmd.Parameters.AddWithValue("?CreatorID", asset.Metadata.CreatorID);
|
||||||
cmd.ExecuteNonQuery();
|
cmd.Parameters.AddWithValue("?asset_flags", (int)asset.Flags);
|
||||||
dbcon.Close();
|
cmd.Parameters.AddWithValue("?data", asset.Data);
|
||||||
return true;
|
cmd.ExecuteNonQuery();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
m_log.ErrorFormat("[ASSET DB]: MySQL failure creating asset {0} with name \"{1}\". Error: {2}",
|
m_log.Error(
|
||||||
asset.FullID, asset.Name, e.Message);
|
string.Format(
|
||||||
dbcon.Close();
|
"[ASSET DB]: MySQL failure creating asset {0} with name {1}. Exception ",
|
||||||
return false;
|
asset.FullID, asset.Name)
|
||||||
|
, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -226,22 +227,24 @@ namespace OpenSim.Data.MySQL
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// create unix epoch time
|
using (cmd)
|
||||||
int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow);
|
{
|
||||||
cmd.Parameters.AddWithValue("?id", asset.ID);
|
// create unix epoch time
|
||||||
cmd.Parameters.AddWithValue("?access_time", now);
|
int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow);
|
||||||
cmd.ExecuteNonQuery();
|
cmd.Parameters.AddWithValue("?id", asset.ID);
|
||||||
|
cmd.Parameters.AddWithValue("?access_time", now);
|
||||||
|
cmd.ExecuteNonQuery();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
m_log.Error(
|
m_log.Error(
|
||||||
string.Format(
|
string.Format(
|
||||||
"[ASSETS DB]: Failure updating access_time for asset {0} with name {1}. Exception ",
|
"[ASSETS DB]: Failure updating access_time for asset {0} with name {1}. Exception ",
|
||||||
asset.FullID, asset.Name),
|
asset.FullID, asset.Name),
|
||||||
e);
|
e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dbcon.Close();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -274,7 +277,6 @@ namespace OpenSim.Data.MySQL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dbcon.Close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool[] results = new bool[uuids.Length];
|
bool[] results = new bool[uuids.Length];
|
||||||
|
@ -334,12 +336,11 @@ namespace OpenSim.Data.MySQL
|
||||||
{
|
{
|
||||||
m_log.Error(
|
m_log.Error(
|
||||||
string.Format(
|
string.Format(
|
||||||
"[ASSETS DB]: MySql failure fetching asset set from {0}, count {1}. Exception ",
|
"[ASSETS DB]: MySql failure fetching asset set from {0}, count {1}. Exception ",
|
||||||
start, count),
|
start, count),
|
||||||
e);
|
e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dbcon.Close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return retList;
|
return retList;
|
||||||
|
@ -356,7 +357,6 @@ namespace OpenSim.Data.MySQL
|
||||||
cmd.Parameters.AddWithValue("?id", id);
|
cmd.Parameters.AddWithValue("?id", id);
|
||||||
cmd.ExecuteNonQuery();
|
cmd.ExecuteNonQuery();
|
||||||
}
|
}
|
||||||
dbcon.Close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -364,4 +364,4 @@ namespace OpenSim.Data.MySQL
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -59,7 +59,6 @@ namespace OpenSim.Data.MySQL
|
||||||
dbcon.Open();
|
dbcon.Open();
|
||||||
Migration m = new Migration(dbcon, Assembly, "AuthStore");
|
Migration m = new Migration(dbcon, Assembly, "AuthStore");
|
||||||
m.Update();
|
m.Update();
|
||||||
dbcon.Close();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,30 +76,27 @@ namespace OpenSim.Data.MySQL
|
||||||
{
|
{
|
||||||
cmd.Parameters.AddWithValue("?principalID", principalID.ToString());
|
cmd.Parameters.AddWithValue("?principalID", principalID.ToString());
|
||||||
|
|
||||||
using(IDataReader result = cmd.ExecuteReader())
|
IDataReader result = cmd.ExecuteReader();
|
||||||
|
|
||||||
|
if (result.Read())
|
||||||
{
|
{
|
||||||
if(result.Read())
|
ret.PrincipalID = principalID;
|
||||||
|
|
||||||
|
CheckColumnNames(result);
|
||||||
|
|
||||||
|
foreach (string s in m_ColumnNames)
|
||||||
{
|
{
|
||||||
ret.PrincipalID = principalID;
|
if (s == "UUID")
|
||||||
|
continue;
|
||||||
CheckColumnNames(result);
|
|
||||||
|
ret.Data[s] = result[s].ToString();
|
||||||
foreach(string s in m_ColumnNames)
|
|
||||||
{
|
|
||||||
if(s == "UUID")
|
|
||||||
continue;
|
|
||||||
|
|
||||||
ret.Data[s] = result[s].ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
dbcon.Close();
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dbcon.Close();
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -136,25 +132,25 @@ namespace OpenSim.Data.MySQL
|
||||||
if (!first)
|
if (!first)
|
||||||
update += ", ";
|
update += ", ";
|
||||||
update += "`" + field + "` = ?"+field;
|
update += "`" + field + "` = ?"+field;
|
||||||
|
|
||||||
first = false;
|
first = false;
|
||||||
|
|
||||||
cmd.Parameters.AddWithValue("?"+field, data.Data[field]);
|
cmd.Parameters.AddWithValue("?"+field, data.Data[field]);
|
||||||
}
|
}
|
||||||
|
|
||||||
update += " where UUID = ?principalID";
|
update += " where UUID = ?principalID";
|
||||||
|
|
||||||
cmd.CommandText = update;
|
cmd.CommandText = update;
|
||||||
cmd.Parameters.AddWithValue("?principalID", data.PrincipalID.ToString());
|
cmd.Parameters.AddWithValue("?principalID", data.PrincipalID.ToString());
|
||||||
|
|
||||||
if (ExecuteNonQuery(cmd) < 1)
|
if (ExecuteNonQuery(cmd) < 1)
|
||||||
{
|
{
|
||||||
string insert = "insert into `" + m_Realm + "` (`UUID`, `" +
|
string insert = "insert into `" + m_Realm + "` (`UUID`, `" +
|
||||||
String.Join("`, `", fields) +
|
String.Join("`, `", fields) +
|
||||||
"`) values (?principalID, ?" + String.Join(", ?", fields) + ")";
|
"`) values (?principalID, ?" + String.Join(", ?", fields) + ")";
|
||||||
|
|
||||||
cmd.CommandText = insert;
|
cmd.CommandText = insert;
|
||||||
|
|
||||||
if (ExecuteNonQuery(cmd) < 1)
|
if (ExecuteNonQuery(cmd) < 1)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -170,7 +166,7 @@ namespace OpenSim.Data.MySQL
|
||||||
{
|
{
|
||||||
cmd.Parameters.AddWithValue("?"+item, value);
|
cmd.Parameters.AddWithValue("?"+item, value);
|
||||||
cmd.Parameters.AddWithValue("?UUID", principalID.ToString());
|
cmd.Parameters.AddWithValue("?UUID", principalID.ToString());
|
||||||
|
|
||||||
if (ExecuteNonQuery(cmd) > 0)
|
if (ExecuteNonQuery(cmd) > 0)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -190,7 +186,7 @@ namespace OpenSim.Data.MySQL
|
||||||
cmd.Parameters.AddWithValue("?principalID", principalID.ToString());
|
cmd.Parameters.AddWithValue("?principalID", principalID.ToString());
|
||||||
cmd.Parameters.AddWithValue("?token", token);
|
cmd.Parameters.AddWithValue("?token", token);
|
||||||
cmd.Parameters.AddWithValue("?lifetime", lifetime.ToString());
|
cmd.Parameters.AddWithValue("?lifetime", lifetime.ToString());
|
||||||
|
|
||||||
if (ExecuteNonQuery(cmd) > 0)
|
if (ExecuteNonQuery(cmd) > 0)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,7 @@ namespace OpenSim.Data.MySQL
|
||||||
cmd.CommandText = String.Format("delete from {0} where `PrincipalID` = ?PrincipalID and `Name` = ?Name", m_Realm);
|
cmd.CommandText = String.Format("delete from {0} where `PrincipalID` = ?PrincipalID and `Name` = ?Name", m_Realm);
|
||||||
cmd.Parameters.AddWithValue("?PrincipalID", principalID.ToString());
|
cmd.Parameters.AddWithValue("?PrincipalID", principalID.ToString());
|
||||||
cmd.Parameters.AddWithValue("?Name", name);
|
cmd.Parameters.AddWithValue("?Name", name);
|
||||||
|
|
||||||
if (ExecuteNonQuery(cmd) > 0)
|
if (ExecuteNonQuery(cmd) > 0)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,12 @@ namespace OpenSim.Data.MySQL
|
||||||
private static readonly ILog m_log =
|
private static readonly ILog m_log =
|
||||||
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
private const string m_waitTimeoutSelect = "select @@wait_timeout";
|
||||||
|
|
||||||
private string m_connectionString;
|
private string m_connectionString;
|
||||||
|
private long m_waitTimeout;
|
||||||
|
private long m_waitTimeoutLeeway = 60 * TimeSpan.TicksPerSecond;
|
||||||
|
// private long m_lastConnectionUse;
|
||||||
|
|
||||||
private FieldInfo[] m_Fields;
|
private FieldInfo[] m_Fields;
|
||||||
private Dictionary<string, FieldInfo> m_FieldMap =
|
private Dictionary<string, FieldInfo> m_FieldMap =
|
||||||
|
@ -76,13 +81,14 @@ namespace OpenSim.Data.MySQL
|
||||||
m_log.Debug("Exception: password not found in connection string\n" + e.ToString());
|
m_log.Debug("Exception: password not found in connection string\n" + e.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GetWaitTimeout();
|
||||||
|
|
||||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||||
{
|
{
|
||||||
dbcon.Open();
|
dbcon.Open();
|
||||||
|
|
||||||
Migration m = new Migration(dbcon, Assembly, "EstateStore");
|
Migration m = new Migration(dbcon, Assembly, "EstateStore");
|
||||||
m.Update();
|
m.Update();
|
||||||
dbcon.Close();
|
|
||||||
|
|
||||||
Type t = typeof(EstateSettings);
|
Type t = typeof(EstateSettings);
|
||||||
m_Fields = t.GetFields(BindingFlags.NonPublic |
|
m_Fields = t.GetFields(BindingFlags.NonPublic |
|
||||||
|
@ -102,6 +108,33 @@ namespace OpenSim.Data.MySQL
|
||||||
get { return new List<string>(m_FieldMap.Keys).ToArray(); }
|
get { return new List<string>(m_FieldMap.Keys).ToArray(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void GetWaitTimeout()
|
||||||
|
{
|
||||||
|
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||||
|
{
|
||||||
|
dbcon.Open();
|
||||||
|
|
||||||
|
using (MySqlCommand cmd = new MySqlCommand(m_waitTimeoutSelect, dbcon))
|
||||||
|
{
|
||||||
|
using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow))
|
||||||
|
{
|
||||||
|
if (dbReader.Read())
|
||||||
|
{
|
||||||
|
m_waitTimeout
|
||||||
|
= Convert.ToInt32(dbReader["@@wait_timeout"]) *
|
||||||
|
TimeSpan.TicksPerSecond + m_waitTimeoutLeeway;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// m_lastConnectionUse = DateTime.Now.Ticks;
|
||||||
|
|
||||||
|
m_log.DebugFormat(
|
||||||
|
"[REGION DB]: Connection wait timeout {0} seconds",
|
||||||
|
m_waitTimeout / TimeSpan.TicksPerSecond);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public EstateSettings LoadEstateSettings(UUID regionID, bool create)
|
public EstateSettings LoadEstateSettings(UUID regionID, bool create)
|
||||||
{
|
{
|
||||||
string sql = "select estate_settings." + String.Join(",estate_settings.", FieldList) +
|
string sql = "select estate_settings." + String.Join(",estate_settings.", FieldList) +
|
||||||
|
@ -144,6 +177,7 @@ namespace OpenSim.Data.MySQL
|
||||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||||
{
|
{
|
||||||
dbcon.Open();
|
dbcon.Open();
|
||||||
|
|
||||||
cmd.Connection = dbcon;
|
cmd.Connection = dbcon;
|
||||||
|
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
@ -171,8 +205,6 @@ namespace OpenSim.Data.MySQL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dbcon.Close();
|
|
||||||
cmd.Connection = null;
|
|
||||||
|
|
||||||
if (!found && create)
|
if (!found && create)
|
||||||
{
|
{
|
||||||
|
@ -233,7 +265,6 @@ namespace OpenSim.Data.MySQL
|
||||||
|
|
||||||
es.Save();
|
es.Save();
|
||||||
}
|
}
|
||||||
dbcon.Close();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -266,7 +297,6 @@ namespace OpenSim.Data.MySQL
|
||||||
|
|
||||||
cmd.ExecuteNonQuery();
|
cmd.ExecuteNonQuery();
|
||||||
}
|
}
|
||||||
dbcon.Close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SaveBanList(es);
|
SaveBanList(es);
|
||||||
|
@ -285,7 +315,7 @@ namespace OpenSim.Data.MySQL
|
||||||
|
|
||||||
using (MySqlCommand cmd = dbcon.CreateCommand())
|
using (MySqlCommand cmd = dbcon.CreateCommand())
|
||||||
{
|
{
|
||||||
cmd.CommandText = "select * from estateban where EstateID = ?EstateID";
|
cmd.CommandText = "select bannedUUID from estateban where EstateID = ?EstateID";
|
||||||
cmd.Parameters.AddWithValue("?EstateID", es.EstateID);
|
cmd.Parameters.AddWithValue("?EstateID", es.EstateID);
|
||||||
|
|
||||||
using (IDataReader r = cmd.ExecuteReader())
|
using (IDataReader r = cmd.ExecuteReader())
|
||||||
|
@ -293,16 +323,17 @@ namespace OpenSim.Data.MySQL
|
||||||
while (r.Read())
|
while (r.Read())
|
||||||
{
|
{
|
||||||
EstateBan eb = new EstateBan();
|
EstateBan eb = new EstateBan();
|
||||||
eb.BannedUserID = DBGuid.FromDB(r["bannedUUID"]); ;
|
|
||||||
|
UUID uuid = new UUID();
|
||||||
|
UUID.TryParse(r["bannedUUID"].ToString(), out uuid);
|
||||||
|
|
||||||
|
eb.BannedUserID = uuid;
|
||||||
eb.BannedHostAddress = "0.0.0.0";
|
eb.BannedHostAddress = "0.0.0.0";
|
||||||
eb.BannedHostIPMask = "0.0.0.0";
|
eb.BannedHostIPMask = "0.0.0.0";
|
||||||
eb.BanningUserID = DBGuid.FromDB(r["banningUUID"]);
|
|
||||||
eb.BanTime = Convert.ToInt32(r["banTime"]);
|
|
||||||
es.AddBan(eb);
|
es.AddBan(eb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dbcon.Close();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -321,20 +352,17 @@ namespace OpenSim.Data.MySQL
|
||||||
|
|
||||||
cmd.Parameters.Clear();
|
cmd.Parameters.Clear();
|
||||||
|
|
||||||
cmd.CommandText = "insert into estateban (EstateID, bannedUUID, bannedIp, bannedIpHostMask, bannedNameMask, banningUUID, banTime) values ( ?EstateID, ?bannedUUID, '', '', '', ?banningUUID, ?banTime)";
|
cmd.CommandText = "insert into estateban (EstateID, bannedUUID, bannedIp, bannedIpHostMask, bannedNameMask) values ( ?EstateID, ?bannedUUID, '', '', '' )";
|
||||||
|
|
||||||
foreach (EstateBan b in es.EstateBans)
|
foreach (EstateBan b in es.EstateBans)
|
||||||
{
|
{
|
||||||
cmd.Parameters.AddWithValue("?EstateID", es.EstateID.ToString());
|
cmd.Parameters.AddWithValue("?EstateID", es.EstateID.ToString());
|
||||||
cmd.Parameters.AddWithValue("?bannedUUID", b.BannedUserID.ToString());
|
cmd.Parameters.AddWithValue("?bannedUUID", b.BannedUserID.ToString());
|
||||||
cmd.Parameters.AddWithValue("?banningUUID", b.BanningUserID.ToString());
|
|
||||||
cmd.Parameters.AddWithValue("?banTime", b.BanTime);
|
|
||||||
|
|
||||||
cmd.ExecuteNonQuery();
|
cmd.ExecuteNonQuery();
|
||||||
cmd.Parameters.Clear();
|
cmd.Parameters.Clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dbcon.Close();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -364,7 +392,6 @@ namespace OpenSim.Data.MySQL
|
||||||
cmd.Parameters.Clear();
|
cmd.Parameters.Clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dbcon.Close();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -390,7 +417,6 @@ namespace OpenSim.Data.MySQL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dbcon.Close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return uuids.ToArray();
|
return uuids.ToArray();
|
||||||
|
@ -411,19 +437,19 @@ namespace OpenSim.Data.MySQL
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<EstateSettings> LoadEstateSettingsAll()
|
public List<EstateSettings> LoadEstateSettingsAll()
|
||||||
{
|
{
|
||||||
List<EstateSettings> allEstateSettings = new List<EstateSettings>();
|
List<EstateSettings> allEstateSettings = new List<EstateSettings>();
|
||||||
|
|
||||||
List<int> allEstateIds = GetEstatesAll();
|
List<int> allEstateIds = GetEstatesAll();
|
||||||
|
|
||||||
foreach (int estateId in allEstateIds)
|
foreach (int estateId in allEstateIds)
|
||||||
allEstateSettings.Add(LoadEstateSettings(estateId));
|
allEstateSettings.Add(LoadEstateSettings(estateId));
|
||||||
|
|
||||||
return allEstateSettings;
|
return allEstateSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<int> GetEstatesAll()
|
public List<int> GetEstatesAll()
|
||||||
{
|
{
|
||||||
List<int> result = new List<int>();
|
List<int> result = new List<int>();
|
||||||
|
@ -445,10 +471,11 @@ namespace OpenSim.Data.MySQL
|
||||||
reader.Close();
|
reader.Close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dbcon.Close();
|
dbcon.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<int> GetEstates(string search)
|
public List<int> GetEstates(string search)
|
||||||
|
@ -473,6 +500,7 @@ namespace OpenSim.Data.MySQL
|
||||||
reader.Close();
|
reader.Close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dbcon.Close();
|
dbcon.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,433 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
* * Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* * Neither the name of the OpenSimulator Project nor the
|
|
||||||
* names of its contributors may be used to endorse or promote products
|
|
||||||
* derived from this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
|
||||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Data;
|
|
||||||
using OpenSim.Framework;
|
|
||||||
using OpenSim.Framework.Console;
|
|
||||||
using log4net;
|
|
||||||
using MySql.Data.MySqlClient;
|
|
||||||
using OpenMetaverse;
|
|
||||||
|
|
||||||
namespace OpenSim.Data.MySQL
|
|
||||||
{
|
|
||||||
public class MySQLFSAssetData : IFSAssetDataPlugin
|
|
||||||
{
|
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
|
||||||
|
|
||||||
protected string m_ConnectionString;
|
|
||||||
protected string m_Table;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Number of days that must pass before we update the access time on an asset when it has been fetched
|
|
||||||
/// Config option to change this is "DaysBetweenAccessTimeUpdates"
|
|
||||||
/// </summary>
|
|
||||||
private int DaysBetweenAccessTimeUpdates = 0;
|
|
||||||
|
|
||||||
protected virtual Assembly Assembly
|
|
||||||
{
|
|
||||||
get { return GetType().Assembly; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public MySQLFSAssetData()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
#region IPlugin Members
|
|
||||||
|
|
||||||
public string Version { get { return "1.0.0.0"; } }
|
|
||||||
|
|
||||||
// Loads and initialises the MySQL storage plugin and checks for migrations
|
|
||||||
public void Initialise(string connect, string realm, int UpdateAccessTime)
|
|
||||||
{
|
|
||||||
m_ConnectionString = connect;
|
|
||||||
m_Table = realm;
|
|
||||||
|
|
||||||
DaysBetweenAccessTimeUpdates = UpdateAccessTime;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
using (MySqlConnection conn = new MySqlConnection(m_ConnectionString))
|
|
||||||
{
|
|
||||||
conn.Open();
|
|
||||||
Migration m = new Migration(conn, Assembly, "FSAssetStore");
|
|
||||||
m.Update();
|
|
||||||
conn.Close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (MySqlException e)
|
|
||||||
{
|
|
||||||
m_log.ErrorFormat("[FSASSETS]: Can't connect to database: {0}", e.Message.ToString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Initialise()
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose() { }
|
|
||||||
|
|
||||||
public string Name
|
|
||||||
{
|
|
||||||
get { return "MySQL FSAsset storage engine"; }
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
private bool ExecuteNonQuery(MySqlCommand cmd)
|
|
||||||
{
|
|
||||||
using (MySqlConnection conn = new MySqlConnection(m_ConnectionString))
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
conn.Open();
|
|
||||||
}
|
|
||||||
catch (MySqlException e)
|
|
||||||
{
|
|
||||||
m_log.ErrorFormat("[FSASSETS]: Database open failed with {0}", e.ToString());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd.Connection = conn;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
cmd.ExecuteNonQuery();
|
|
||||||
}
|
|
||||||
catch (MySqlException e)
|
|
||||||
{
|
|
||||||
cmd.Connection = null;
|
|
||||||
conn.Close();
|
|
||||||
m_log.ErrorFormat("[FSASSETS]: Query {0} failed with {1}", cmd.CommandText, e.ToString());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
conn.Close();
|
|
||||||
cmd.Connection = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
#region IFSAssetDataPlugin Members
|
|
||||||
|
|
||||||
public AssetMetadata Get(string id, out string hash)
|
|
||||||
{
|
|
||||||
hash = String.Empty;
|
|
||||||
|
|
||||||
AssetMetadata meta = new AssetMetadata();
|
|
||||||
|
|
||||||
using (MySqlConnection conn = new MySqlConnection(m_ConnectionString))
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
conn.Open();
|
|
||||||
}
|
|
||||||
catch (MySqlException e)
|
|
||||||
{
|
|
||||||
m_log.ErrorFormat("[FSASSETS]: Database open failed with {0}", e.ToString());
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
using (MySqlCommand cmd = conn.CreateCommand())
|
|
||||||
{
|
|
||||||
cmd.CommandText = String.Format("select id, name, description, type, hash, create_time, asset_flags, access_time from {0} where id = ?id", m_Table);
|
|
||||||
cmd.Parameters.AddWithValue("?id", id);
|
|
||||||
|
|
||||||
using (IDataReader reader = cmd.ExecuteReader())
|
|
||||||
{
|
|
||||||
if (!reader.Read())
|
|
||||||
return null;
|
|
||||||
|
|
||||||
hash = reader["hash"].ToString();
|
|
||||||
|
|
||||||
meta.ID = id;
|
|
||||||
meta.FullID = new UUID(id);
|
|
||||||
|
|
||||||
meta.Name = reader["name"].ToString();
|
|
||||||
meta.Description = reader["description"].ToString();
|
|
||||||
meta.Type = (sbyte)Convert.ToInt32(reader["type"]);
|
|
||||||
meta.ContentType = SLUtil.SLAssetTypeToContentType(meta.Type);
|
|
||||||
meta.CreationDate = Util.ToDateTime(Convert.ToInt32(reader["create_time"]));
|
|
||||||
meta.Flags = (AssetFlags)Convert.ToInt32(reader["asset_flags"]);
|
|
||||||
|
|
||||||
int AccessTime = Convert.ToInt32(reader["access_time"]);
|
|
||||||
UpdateAccessTime(id, AccessTime);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
conn.Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
return meta;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateAccessTime(string AssetID, int AccessTime)
|
|
||||||
{
|
|
||||||
// Reduce DB work by only updating access time if asset hasn't recently been accessed
|
|
||||||
// 0 By Default, Config option is "DaysBetweenAccessTimeUpdates"
|
|
||||||
if (DaysBetweenAccessTimeUpdates > 0 && (DateTime.UtcNow - Utils.UnixTimeToDateTime(AccessTime)).TotalDays < DaysBetweenAccessTimeUpdates)
|
|
||||||
return;
|
|
||||||
|
|
||||||
using (MySqlConnection conn = new MySqlConnection(m_ConnectionString))
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
conn.Open();
|
|
||||||
}
|
|
||||||
catch (MySqlException e)
|
|
||||||
{
|
|
||||||
m_log.ErrorFormat("[FSASSETS]: Database open failed with {0}", e.ToString());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
using (MySqlCommand cmd = conn.CreateCommand())
|
|
||||||
{
|
|
||||||
cmd.CommandText = String.Format("UPDATE {0} SET `access_time` = UNIX_TIMESTAMP() WHERE `id` = ?id", m_Table);
|
|
||||||
cmd.Parameters.AddWithValue("?id", AssetID);
|
|
||||||
cmd.ExecuteNonQuery();
|
|
||||||
}
|
|
||||||
conn.Close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Store(AssetMetadata meta, string hash)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
string oldhash;
|
|
||||||
AssetMetadata existingAsset = Get(meta.ID, out oldhash);
|
|
||||||
|
|
||||||
using (MySqlCommand cmd = new MySqlCommand())
|
|
||||||
{
|
|
||||||
cmd.Parameters.AddWithValue("?id", meta.ID);
|
|
||||||
cmd.Parameters.AddWithValue("?name", meta.Name);
|
|
||||||
cmd.Parameters.AddWithValue("?description", meta.Description);
|
|
||||||
// cmd.Parameters.AddWithValue("?type", meta.Type.ToString());
|
|
||||||
cmd.Parameters.AddWithValue("?type", meta.Type);
|
|
||||||
cmd.Parameters.AddWithValue("?hash", hash);
|
|
||||||
cmd.Parameters.AddWithValue("?asset_flags", meta.Flags);
|
|
||||||
|
|
||||||
if (existingAsset == null)
|
|
||||||
{
|
|
||||||
cmd.CommandText = String.Format("insert into {0} (id, name, description, type, hash, asset_flags, create_time, access_time) values ( ?id, ?name, ?description, ?type, ?hash, ?asset_flags, UNIX_TIMESTAMP(), UNIX_TIMESTAMP())", m_Table);
|
|
||||||
|
|
||||||
ExecuteNonQuery(cmd);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//cmd.CommandText = String.Format("update {0} set hash = ?hash, access_time = UNIX_TIMESTAMP() where id = ?id", m_Table);
|
|
||||||
|
|
||||||
//ExecuteNonQuery(cmd);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// return false;
|
|
||||||
// if the asset already exits
|
|
||||||
// assume it was already correctly stored
|
|
||||||
// or regions will keep retry.
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
catch(Exception e)
|
|
||||||
{
|
|
||||||
m_log.Error("[FSAssets] Failed to store asset with ID " + meta.ID);
|
|
||||||
m_log.Error(e.ToString());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Check if the assets exist in the database.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="uuids">The asset UUID's</param>
|
|
||||||
/// <returns>For each asset: true if it exists, false otherwise</returns>
|
|
||||||
public bool[] AssetsExist(UUID[] uuids)
|
|
||||||
{
|
|
||||||
if (uuids.Length == 0)
|
|
||||||
return new bool[0];
|
|
||||||
|
|
||||||
bool[] results = new bool[uuids.Length];
|
|
||||||
for (int i = 0; i < uuids.Length; i++)
|
|
||||||
results[i] = false;
|
|
||||||
|
|
||||||
HashSet<UUID> exists = new HashSet<UUID>();
|
|
||||||
|
|
||||||
string ids = "'" + string.Join("','", uuids) + "'";
|
|
||||||
string sql = string.Format("select id from {1} where id in ({0})", ids, m_Table);
|
|
||||||
|
|
||||||
using (MySqlConnection conn = new MySqlConnection(m_ConnectionString))
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
conn.Open();
|
|
||||||
}
|
|
||||||
catch (MySqlException e)
|
|
||||||
{
|
|
||||||
m_log.ErrorFormat("[FSASSETS]: Failed to open database: {0}", e.ToString());
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
|
|
||||||
using (MySqlCommand cmd = conn.CreateCommand())
|
|
||||||
{
|
|
||||||
cmd.CommandText = sql;
|
|
||||||
|
|
||||||
using (MySqlDataReader dbReader = cmd.ExecuteReader())
|
|
||||||
{
|
|
||||||
while (dbReader.Read())
|
|
||||||
{
|
|
||||||
UUID id = DBGuid.FromDB(dbReader["ID"]);
|
|
||||||
exists.Add(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
conn.Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < uuids.Length; i++)
|
|
||||||
results[i] = exists.Contains(uuids[i]);
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int Count()
|
|
||||||
{
|
|
||||||
int count = 0;
|
|
||||||
|
|
||||||
using (MySqlConnection conn = new MySqlConnection(m_ConnectionString))
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
conn.Open();
|
|
||||||
}
|
|
||||||
catch (MySqlException e)
|
|
||||||
{
|
|
||||||
m_log.ErrorFormat("[FSASSETS]: Failed to open database: {0}", e.ToString());
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
using(MySqlCommand cmd = conn.CreateCommand())
|
|
||||||
{
|
|
||||||
cmd.CommandText = String.Format("select count(*) as count from {0}",m_Table);
|
|
||||||
|
|
||||||
using (IDataReader reader = cmd.ExecuteReader())
|
|
||||||
{
|
|
||||||
reader.Read();
|
|
||||||
|
|
||||||
count = Convert.ToInt32(reader["count"]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
conn.Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Delete(string id)
|
|
||||||
{
|
|
||||||
using(MySqlCommand cmd = new MySqlCommand())
|
|
||||||
{
|
|
||||||
|
|
||||||
cmd.CommandText = String.Format("delete from {0} where id = ?id",m_Table);
|
|
||||||
|
|
||||||
cmd.Parameters.AddWithValue("?id", id);
|
|
||||||
|
|
||||||
ExecuteNonQuery(cmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Import(string conn, string table, int start, int count, bool force, FSStoreDelegate store)
|
|
||||||
{
|
|
||||||
int imported = 0;
|
|
||||||
|
|
||||||
using (MySqlConnection importConn = new MySqlConnection(conn))
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
importConn.Open();
|
|
||||||
}
|
|
||||||
catch (MySqlException e)
|
|
||||||
{
|
|
||||||
m_log.ErrorFormat("[FSASSETS]: Can't connect to database: {0}",
|
|
||||||
e.Message.ToString());
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
using (MySqlCommand cmd = importConn.CreateCommand())
|
|
||||||
{
|
|
||||||
string limit = String.Empty;
|
|
||||||
if (count != -1)
|
|
||||||
{
|
|
||||||
limit = String.Format(" limit {0},{1}", start, count);
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd.CommandText = String.Format("select * from {0}{1}", table, limit);
|
|
||||||
|
|
||||||
MainConsole.Instance.Output("Querying database");
|
|
||||||
using (IDataReader reader = cmd.ExecuteReader())
|
|
||||||
{
|
|
||||||
MainConsole.Instance.Output("Reading data");
|
|
||||||
|
|
||||||
while (reader.Read())
|
|
||||||
{
|
|
||||||
if ((imported % 100) == 0)
|
|
||||||
{
|
|
||||||
MainConsole.Instance.Output(String.Format("{0} assets imported so far", imported));
|
|
||||||
}
|
|
||||||
|
|
||||||
AssetBase asset = new AssetBase();
|
|
||||||
AssetMetadata meta = new AssetMetadata();
|
|
||||||
|
|
||||||
meta.ID = reader["id"].ToString();
|
|
||||||
meta.FullID = new UUID(meta.ID);
|
|
||||||
|
|
||||||
meta.Name = reader["name"].ToString();
|
|
||||||
meta.Description = reader["description"].ToString();
|
|
||||||
meta.Type = (sbyte)Convert.ToInt32(reader["assetType"]);
|
|
||||||
meta.ContentType = SLUtil.SLAssetTypeToContentType(meta.Type);
|
|
||||||
meta.CreationDate = Util.ToDateTime(Convert.ToInt32(reader["create_time"]));
|
|
||||||
|
|
||||||
asset.Metadata = meta;
|
|
||||||
asset.Data = (byte[])reader["data"];
|
|
||||||
|
|
||||||
store(asset, force);
|
|
||||||
|
|
||||||
imported++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
importConn.Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
MainConsole.Instance.Output(String.Format("Import done, {0} assets imported", imported));
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -36,7 +36,7 @@ using MySql.Data.MySqlClient;
|
||||||
namespace OpenSim.Data.MySQL
|
namespace OpenSim.Data.MySQL
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Common code for a number of database modules
|
/// A database interface class to a user profile storage system
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class MySqlFramework
|
public class MySqlFramework
|
||||||
{
|
{
|
||||||
|
@ -44,78 +44,30 @@ namespace OpenSim.Data.MySQL
|
||||||
log4net.LogManager.GetLogger(
|
log4net.LogManager.GetLogger(
|
||||||
System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
protected string m_connectionString = String.Empty;
|
protected string m_connectionString;
|
||||||
protected MySqlTransaction m_trans = null;
|
|
||||||
|
|
||||||
// Constructor using a connection string. Instances constructed
|
|
||||||
// this way will open a new connection for each call.
|
|
||||||
protected MySqlFramework(string connectionString)
|
protected MySqlFramework(string connectionString)
|
||||||
{
|
{
|
||||||
m_connectionString = connectionString;
|
m_connectionString = connectionString;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Constructor using a connection object. Instances constructed
|
|
||||||
// this way will use the connection object and never create
|
|
||||||
// new connections.
|
|
||||||
protected MySqlFramework(MySqlTransaction trans)
|
|
||||||
{
|
|
||||||
m_trans = trans;
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// All non queries are funneled through one connection
|
|
||||||
// to increase performance a little
|
|
||||||
//
|
|
||||||
protected int ExecuteNonQuery(MySqlCommand cmd)
|
protected int ExecuteNonQuery(MySqlCommand cmd)
|
||||||
{
|
{
|
||||||
if (m_trans == null)
|
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||||
{
|
|
||||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
|
||||||
{
|
|
||||||
dbcon.Open();
|
|
||||||
int ret = ExecuteNonQueryWithConnection(cmd, dbcon);
|
|
||||||
dbcon.Close();
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return ExecuteNonQueryWithTransaction(cmd, m_trans);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private int ExecuteNonQueryWithTransaction(MySqlCommand cmd, MySqlTransaction trans)
|
|
||||||
{
|
|
||||||
cmd.Transaction = trans;
|
|
||||||
return ExecuteNonQueryWithConnection(cmd, trans.Connection);
|
|
||||||
}
|
|
||||||
|
|
||||||
private int ExecuteNonQueryWithConnection(MySqlCommand cmd, MySqlConnection dbcon)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
|
dbcon.Open();
|
||||||
cmd.Connection = dbcon;
|
cmd.Connection = dbcon;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
int ret = cmd.ExecuteNonQuery();
|
return cmd.ExecuteNonQuery();
|
||||||
cmd.Connection = null;
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
m_log.Error(e.Message, e);
|
m_log.Error(e.Message, e);
|
||||||
m_log.Error(Environment.StackTrace.ToString());
|
|
||||||
cmd.Connection = null;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
m_log.Error(e.Message, e);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -29,16 +29,18 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text;
|
using log4net;
|
||||||
using MySql.Data.MySqlClient;
|
using MySql.Data.MySqlClient;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Region.Framework.Interfaces;
|
||||||
|
|
||||||
namespace OpenSim.Data.MySQL
|
namespace OpenSim.Data.MySQL
|
||||||
{
|
{
|
||||||
public class MySQLGenericTableHandler<T> : MySqlFramework where T: class, new()
|
public class MySQLGenericTableHandler<T> : MySqlFramework 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 Dictionary<string, FieldInfo> m_Fields =
|
protected Dictionary<string, FieldInfo> m_Fields =
|
||||||
new Dictionary<string, FieldInfo>();
|
new Dictionary<string, FieldInfo>();
|
||||||
|
|
||||||
|
@ -51,27 +53,14 @@ namespace OpenSim.Data.MySQL
|
||||||
get { return GetType().Assembly; }
|
get { return GetType().Assembly; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public MySQLGenericTableHandler(MySqlTransaction trans,
|
|
||||||
string realm, string storeName) : base(trans)
|
|
||||||
{
|
|
||||||
m_Realm = realm;
|
|
||||||
|
|
||||||
CommonConstruct(storeName);
|
|
||||||
}
|
|
||||||
|
|
||||||
public MySQLGenericTableHandler(string connectionString,
|
public MySQLGenericTableHandler(string connectionString,
|
||||||
string realm, string storeName) : base(connectionString)
|
string realm, string storeName) : base(connectionString)
|
||||||
{
|
{
|
||||||
m_Realm = realm;
|
m_Realm = realm;
|
||||||
|
m_connectionString = connectionString;
|
||||||
CommonConstruct(storeName);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void CommonConstruct(string storeName)
|
|
||||||
{
|
|
||||||
if (storeName != String.Empty)
|
if (storeName != String.Empty)
|
||||||
{
|
{
|
||||||
// We always use a new connection for any Migrations
|
|
||||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||||
{
|
{
|
||||||
dbcon.Open();
|
dbcon.Open();
|
||||||
|
@ -116,167 +105,102 @@ namespace OpenSim.Data.MySQL
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual T[] Get(string field, string key)
|
public virtual T[] Get(string field, string key)
|
||||||
{
|
|
||||||
using (MySqlCommand cmd = new MySqlCommand())
|
|
||||||
{
|
|
||||||
cmd.Parameters.AddWithValue(field, key);
|
|
||||||
cmd.CommandText = string.Format("select * from {0} where `{1}` = ?{1}", m_Realm, field);
|
|
||||||
return DoQuery(cmd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual T[] Get(string field, string[] keys)
|
|
||||||
{
|
{
|
||||||
int flen = keys.Length;
|
return Get(new string[] { field }, new string[] { key });
|
||||||
if(flen == 0)
|
|
||||||
return new T[0];
|
|
||||||
|
|
||||||
int flast = flen - 1;
|
|
||||||
StringBuilder sb = new StringBuilder(1024);
|
|
||||||
sb.AppendFormat("select * from {0} where {1} IN (?", m_Realm, field);
|
|
||||||
using (MySqlCommand cmd = new MySqlCommand())
|
|
||||||
{
|
|
||||||
for (int i = 0 ; i < flen ; i++)
|
|
||||||
{
|
|
||||||
string fname = field + i.ToString();
|
|
||||||
cmd.Parameters.AddWithValue(fname, keys[i]);
|
|
||||||
|
|
||||||
sb.Append(fname);
|
|
||||||
if(i < flast)
|
|
||||||
sb.Append(",?");
|
|
||||||
else
|
|
||||||
sb.Append(")");
|
|
||||||
}
|
|
||||||
cmd.CommandText = sb.ToString();
|
|
||||||
return DoQuery(cmd);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual T[] Get(string[] fields, string[] keys)
|
public virtual T[] Get(string[] fields, string[] keys)
|
||||||
{
|
{
|
||||||
return Get(fields, keys, String.Empty);
|
if (fields.Length != keys.Length)
|
||||||
}
|
|
||||||
|
|
||||||
public virtual T[] Get(string[] fields, string[] keys, string options)
|
|
||||||
{
|
|
||||||
int flen = fields.Length;
|
|
||||||
if (flen == 0 || flen != keys.Length)
|
|
||||||
return new T[0];
|
return new T[0];
|
||||||
|
|
||||||
int flast = flen - 1;
|
List<string> terms = new List<string>();
|
||||||
StringBuilder sb = new StringBuilder(1024);
|
|
||||||
sb.AppendFormat("select * from {0} where ", m_Realm);
|
|
||||||
|
|
||||||
using (MySqlCommand cmd = new MySqlCommand())
|
using (MySqlCommand cmd = new MySqlCommand())
|
||||||
{
|
{
|
||||||
for (int i = 0 ; i < flen ; i++)
|
for (int i = 0 ; i < fields.Length ; i++)
|
||||||
{
|
{
|
||||||
cmd.Parameters.AddWithValue(fields[i], keys[i]);
|
cmd.Parameters.AddWithValue(fields[i], keys[i]);
|
||||||
if(i < flast)
|
terms.Add("`" + fields[i] + "` = ?" + fields[i]);
|
||||||
sb.AppendFormat("`{0}` = ?{0} and ", fields[i]);
|
|
||||||
else
|
|
||||||
sb.AppendFormat("`{0}` = ?{0} ", fields[i]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sb.Append(options);
|
string where = String.Join(" and ", terms.ToArray());
|
||||||
cmd.CommandText = sb.ToString();
|
|
||||||
|
|
||||||
|
string query = String.Format("select * from {0} where {1}",
|
||||||
|
m_Realm, where);
|
||||||
|
|
||||||
|
cmd.CommandText = query;
|
||||||
|
|
||||||
return DoQuery(cmd);
|
return DoQuery(cmd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected T[] DoQuery(MySqlCommand cmd)
|
protected T[] DoQuery(MySqlCommand cmd)
|
||||||
{
|
|
||||||
if (m_trans == null)
|
|
||||||
{
|
|
||||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
|
||||||
{
|
|
||||||
dbcon.Open();
|
|
||||||
T[] ret = DoQueryWithConnection(cmd, dbcon);
|
|
||||||
dbcon.Close();
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return DoQueryWithTransaction(cmd, m_trans);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected T[] DoQueryWithTransaction(MySqlCommand cmd, MySqlTransaction trans)
|
|
||||||
{
|
|
||||||
cmd.Transaction = trans;
|
|
||||||
|
|
||||||
return DoQueryWithConnection(cmd, trans.Connection);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected T[] DoQueryWithConnection(MySqlCommand cmd, MySqlConnection dbcon)
|
|
||||||
{
|
{
|
||||||
List<T> result = new List<T>();
|
List<T> result = new List<T>();
|
||||||
|
|
||||||
cmd.Connection = dbcon;
|
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||||
|
|
||||||
using (IDataReader reader = cmd.ExecuteReader())
|
|
||||||
{
|
{
|
||||||
if (reader == null)
|
dbcon.Open();
|
||||||
return new T[0];
|
cmd.Connection = dbcon;
|
||||||
|
|
||||||
CheckColumnNames(reader);
|
using (IDataReader reader = cmd.ExecuteReader())
|
||||||
|
|
||||||
while (reader.Read())
|
|
||||||
{
|
{
|
||||||
T row = new T();
|
if (reader == null)
|
||||||
|
return new T[0];
|
||||||
|
|
||||||
foreach (string name in m_Fields.Keys)
|
CheckColumnNames(reader);
|
||||||
|
|
||||||
|
while (reader.Read())
|
||||||
{
|
{
|
||||||
if (reader[name] is DBNull)
|
T row = new T();
|
||||||
|
|
||||||
|
foreach (string name in m_Fields.Keys)
|
||||||
{
|
{
|
||||||
continue;
|
if (reader[name] is DBNull)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (m_Fields[name].FieldType == typeof(bool))
|
||||||
|
{
|
||||||
|
int v = Convert.ToInt32(reader[name]);
|
||||||
|
m_Fields[name].SetValue(row, v != 0 ? true : false);
|
||||||
|
}
|
||||||
|
else if (m_Fields[name].FieldType == typeof(UUID))
|
||||||
|
{
|
||||||
|
m_Fields[name].SetValue(row, DBGuid.FromDB(reader[name]));
|
||||||
|
}
|
||||||
|
else if (m_Fields[name].FieldType == typeof(int))
|
||||||
|
{
|
||||||
|
int v = Convert.ToInt32(reader[name]);
|
||||||
|
m_Fields[name].SetValue(row, v);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_Fields[name].SetValue(row, reader[name]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (m_Fields[name].FieldType == typeof(bool))
|
|
||||||
|
if (m_DataField != null)
|
||||||
{
|
{
|
||||||
int v = Convert.ToInt32(reader[name]);
|
Dictionary<string, string> data =
|
||||||
m_Fields[name].SetValue(row, v != 0);
|
new Dictionary<string, string>();
|
||||||
}
|
|
||||||
else if (m_Fields[name].FieldType == typeof(UUID))
|
foreach (string col in m_ColumnNames)
|
||||||
{
|
{
|
||||||
m_Fields[name].SetValue(row, DBGuid.FromDB(reader[name]));
|
data[col] = reader[col].ToString();
|
||||||
}
|
if (data[col] == null)
|
||||||
else if (m_Fields[name].FieldType == typeof(int))
|
data[col] = String.Empty;
|
||||||
{
|
}
|
||||||
int v = Convert.ToInt32(reader[name]);
|
|
||||||
m_Fields[name].SetValue(row, v);
|
m_DataField.SetValue(row, data);
|
||||||
}
|
|
||||||
else if (m_Fields[name].FieldType == typeof(uint))
|
|
||||||
{
|
|
||||||
uint v = Convert.ToUInt32(reader[name]);
|
|
||||||
m_Fields[name].SetValue(row, v);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_Fields[name].SetValue(row, reader[name]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result.Add(row);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_DataField != null)
|
|
||||||
{
|
|
||||||
Dictionary<string, string> data =
|
|
||||||
new Dictionary<string, string>();
|
|
||||||
|
|
||||||
foreach (string col in m_ColumnNames)
|
|
||||||
{
|
|
||||||
data[col] = reader[col].ToString();
|
|
||||||
if (data[col] == null)
|
|
||||||
data[col] = String.Empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_DataField.SetValue(row, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
result.Add(row);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cmd.Connection = null;
|
|
||||||
return result.ToArray();
|
return result.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -286,9 +210,9 @@ namespace OpenSim.Data.MySQL
|
||||||
{
|
{
|
||||||
string query = String.Format("select * from {0} where {1}",
|
string query = String.Format("select * from {0} where {1}",
|
||||||
m_Realm, where);
|
m_Realm, where);
|
||||||
|
|
||||||
cmd.CommandText = query;
|
cmd.CommandText = query;
|
||||||
|
|
||||||
return DoQuery(cmd);
|
return DoQuery(cmd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -307,16 +231,16 @@ namespace OpenSim.Data.MySQL
|
||||||
{
|
{
|
||||||
names.Add(fi.Name);
|
names.Add(fi.Name);
|
||||||
values.Add("?" + fi.Name);
|
values.Add("?" + fi.Name);
|
||||||
|
|
||||||
// Temporarily return more information about what field is unexpectedly null for
|
// Temporarily return more information about what field is unexpectedly null for
|
||||||
// http://opensimulator.org/mantis/view.php?id=5403. This might be due to a bug in the
|
// http://opensimulator.org/mantis/view.php?id=5403. This might be due to a bug in the
|
||||||
// InventoryTransferModule or we may be required to substitute a DBNull here.
|
// InventoryTransferModule or we may be required to substitute a DBNull here.
|
||||||
if (fi.GetValue(row) == null)
|
if (fi.GetValue(row) == null)
|
||||||
throw new NullReferenceException(
|
throw new NullReferenceException(
|
||||||
string.Format(
|
string.Format(
|
||||||
"[MYSQL GENERIC TABLE HANDLER]: Trying to store field {0} for {1} which is unexpectedly null",
|
"[MYSQL GENERIC TABLE HANDLER]: Trying to store field {0} for {1} which is unexpectedly null",
|
||||||
fi.Name, row));
|
fi.Name, row));
|
||||||
|
|
||||||
cmd.Parameters.AddWithValue(fi.Name, fi.GetValue(row).ToString());
|
cmd.Parameters.AddWithValue(fi.Name, fi.GetValue(row).ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -355,26 +279,25 @@ namespace OpenSim.Data.MySQL
|
||||||
// "[MYSQL GENERIC TABLE HANDLER]: Delete(string[] fields, string[] keys) invoked with {0}:{1}",
|
// "[MYSQL GENERIC TABLE HANDLER]: Delete(string[] fields, string[] keys) invoked with {0}:{1}",
|
||||||
// string.Join(",", fields), string.Join(",", keys));
|
// string.Join(",", fields), string.Join(",", keys));
|
||||||
|
|
||||||
int flen = fields.Length;
|
if (fields.Length != keys.Length)
|
||||||
if (flen == 0 || flen != keys.Length)
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
int flast = flen - 1;
|
List<string> terms = new List<string>();
|
||||||
StringBuilder sb = new StringBuilder(1024);
|
|
||||||
sb.AppendFormat("delete from {0} where ", m_Realm);
|
|
||||||
|
|
||||||
using (MySqlCommand cmd = new MySqlCommand())
|
using (MySqlCommand cmd = new MySqlCommand())
|
||||||
{
|
{
|
||||||
for (int i = 0 ; i < flen ; i++)
|
for (int i = 0 ; i < fields.Length ; i++)
|
||||||
{
|
{
|
||||||
cmd.Parameters.AddWithValue(fields[i], keys[i]);
|
cmd.Parameters.AddWithValue(fields[i], keys[i]);
|
||||||
if(i < flast)
|
terms.Add("`" + fields[i] + "` = ?" + fields[i]);
|
||||||
sb.AppendFormat("`{0}` = ?{0} and ", fields[i]);
|
|
||||||
else
|
|
||||||
sb.AppendFormat("`{0}` = ?{0}", fields[i]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.CommandText = sb.ToString();
|
string where = String.Join(" and ", terms.ToArray());
|
||||||
|
|
||||||
|
string query = String.Format("delete from {0} where {1}", m_Realm, where);
|
||||||
|
|
||||||
|
cmd.CommandText = query;
|
||||||
|
|
||||||
return ExecuteNonQuery(cmd) > 0;
|
return ExecuteNonQuery(cmd) > 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -386,27 +309,27 @@ namespace OpenSim.Data.MySQL
|
||||||
|
|
||||||
public long GetCount(string[] fields, string[] keys)
|
public long GetCount(string[] fields, string[] keys)
|
||||||
{
|
{
|
||||||
int flen = fields.Length;
|
if (fields.Length != keys.Length)
|
||||||
if (flen == 0 || flen != keys.Length)
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
int flast = flen - 1;
|
List<string> terms = new List<string>();
|
||||||
StringBuilder sb = new StringBuilder(1024);
|
|
||||||
sb.AppendFormat("select count(*) from {0} where ", m_Realm);
|
|
||||||
|
|
||||||
using (MySqlCommand cmd = new MySqlCommand())
|
using (MySqlCommand cmd = new MySqlCommand())
|
||||||
{
|
{
|
||||||
for (int i = 0 ; i < flen ; i++)
|
for (int i = 0; i < fields.Length; i++)
|
||||||
{
|
{
|
||||||
cmd.Parameters.AddWithValue(fields[i], keys[i]);
|
cmd.Parameters.AddWithValue(fields[i], keys[i]);
|
||||||
if(i < flast)
|
terms.Add("`" + fields[i] + "` = ?" + fields[i]);
|
||||||
sb.AppendFormat("`{0}` = ?{0} and ", fields[i]);
|
|
||||||
else
|
|
||||||
sb.AppendFormat("`{0}` = ?{0}", fields[i]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.CommandText = sb.ToString();
|
string where = String.Join(" and ", terms.ToArray());
|
||||||
object result = DoQueryScalar(cmd);
|
|
||||||
|
string query = String.Format("select count(*) from {0} where {1}",
|
||||||
|
m_Realm, where);
|
||||||
|
|
||||||
|
cmd.CommandText = query;
|
||||||
|
|
||||||
|
Object result = DoQueryScalar(cmd);
|
||||||
|
|
||||||
return Convert.ToInt64(result);
|
return Convert.ToInt64(result);
|
||||||
}
|
}
|
||||||
|
@ -429,26 +352,14 @@ namespace OpenSim.Data.MySQL
|
||||||
|
|
||||||
public object DoQueryScalar(MySqlCommand cmd)
|
public object DoQueryScalar(MySqlCommand cmd)
|
||||||
{
|
{
|
||||||
if (m_trans == null)
|
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||||
{
|
{
|
||||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
dbcon.Open();
|
||||||
{
|
cmd.Connection = dbcon;
|
||||||
dbcon.Open();
|
|
||||||
cmd.Connection = dbcon;
|
|
||||||
|
|
||||||
object ret = cmd.ExecuteScalar();
|
|
||||||
cmd.Connection = null;
|
|
||||||
dbcon.Close();
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cmd.Connection = m_trans.Connection;
|
|
||||||
cmd.Transaction = m_trans;
|
|
||||||
|
|
||||||
return cmd.ExecuteScalar();
|
return cmd.ExecuteScalar();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -90,7 +90,7 @@ namespace OpenSim.Data.MySQL
|
||||||
else
|
else
|
||||||
pattern = string.Format("Name LIKE '%{0}%'", MySqlHelper.EscapeString(pattern));
|
pattern = string.Format("Name LIKE '%{0}%'", MySqlHelper.EscapeString(pattern));
|
||||||
|
|
||||||
return m_Groups.Get(string.Format("ShowInList=1 AND ({0})", pattern));
|
return m_Groups.Get(string.Format("ShowInList=1 AND ({0}) ORDER BY Name LIMIT 100", pattern));
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool DeleteGroup(UUID groupID)
|
public bool DeleteGroup(UUID groupID)
|
||||||
|
@ -133,10 +133,10 @@ namespace OpenSim.Data.MySQL
|
||||||
|
|
||||||
public bool DeleteMember(UUID groupID, string pricipalID)
|
public bool DeleteMember(UUID groupID, string pricipalID)
|
||||||
{
|
{
|
||||||
return m_Membership.Delete(new string[] { "GroupID", "PrincipalID" },
|
return m_Membership.Delete(new string[] { "GroupID", "PrincipalID" },
|
||||||
new string[] { groupID.ToString(), pricipalID });
|
new string[] { groupID.ToString(), pricipalID });
|
||||||
}
|
}
|
||||||
|
|
||||||
public int MemberCount(UUID groupID)
|
public int MemberCount(UUID groupID)
|
||||||
{
|
{
|
||||||
return (int)m_Membership.GetCount("GroupID", groupID.ToString());
|
return (int)m_Membership.GetCount("GroupID", groupID.ToString());
|
||||||
|
@ -168,7 +168,7 @@ namespace OpenSim.Data.MySQL
|
||||||
|
|
||||||
public bool DeleteRole(UUID groupID, UUID roleID)
|
public bool DeleteRole(UUID groupID, UUID roleID)
|
||||||
{
|
{
|
||||||
return m_Roles.Delete(new string[] { "GroupID", "RoleID" },
|
return m_Roles.Delete(new string[] { "GroupID", "RoleID" },
|
||||||
new string[] { groupID.ToString(), roleID.ToString() });
|
new string[] { groupID.ToString(), roleID.ToString() });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -360,7 +360,7 @@ namespace OpenSim.Data.MySQL
|
||||||
get { return GetType().Assembly; }
|
get { return GetType().Assembly; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public MySqlGroupsGroupsHandler(string connectionString, string realm, string store)
|
public MySqlGroupsGroupsHandler(string connectionString, string realm, string store)
|
||||||
: base(connectionString, realm, store)
|
: base(connectionString, realm, store)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -375,7 +375,7 @@ namespace OpenSim.Data.MySQL
|
||||||
get { return GetType().Assembly; }
|
get { return GetType().Assembly; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public MySqlGroupsMembershipHandler(string connectionString, string realm)
|
public MySqlGroupsMembershipHandler(string connectionString, string realm)
|
||||||
: base(connectionString, realm, string.Empty)
|
: base(connectionString, realm, string.Empty)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -390,7 +390,7 @@ namespace OpenSim.Data.MySQL
|
||||||
get { return GetType().Assembly; }
|
get { return GetType().Assembly; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public MySqlGroupsRolesHandler(string connectionString, string realm)
|
public MySqlGroupsRolesHandler(string connectionString, string realm)
|
||||||
: base(connectionString, realm, string.Empty)
|
: base(connectionString, realm, string.Empty)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -405,7 +405,7 @@ namespace OpenSim.Data.MySQL
|
||||||
get { return GetType().Assembly; }
|
get { return GetType().Assembly; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public MySqlGroupsRoleMembershipHandler(string connectionString, string realm)
|
public MySqlGroupsRoleMembershipHandler(string connectionString, string realm)
|
||||||
: base(connectionString, realm, string.Empty)
|
: base(connectionString, realm, string.Empty)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -420,7 +420,7 @@ namespace OpenSim.Data.MySQL
|
||||||
get { return GetType().Assembly; }
|
get { return GetType().Assembly; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public MySqlGroupsInvitesHandler(string connectionString, string realm)
|
public MySqlGroupsInvitesHandler(string connectionString, string realm)
|
||||||
: base(connectionString, realm, string.Empty)
|
: base(connectionString, realm, string.Empty)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -431,7 +431,8 @@ namespace OpenSim.Data.MySQL
|
||||||
|
|
||||||
using (MySqlCommand cmd = new MySqlCommand())
|
using (MySqlCommand cmd = new MySqlCommand())
|
||||||
{
|
{
|
||||||
cmd.CommandText = String.Format("delete from {0} where TMStamp < NOW() - INTERVAL 2 WEEK", m_Realm);
|
cmd.CommandText = String.Format("delete from {0} where TMStamp < ?tstamp", m_Realm);
|
||||||
|
cmd.Parameters.AddWithValue("?tstamp", now - 14 * 24 * 60 * 60); // > 2 weeks old
|
||||||
|
|
||||||
ExecuteNonQuery(cmd);
|
ExecuteNonQuery(cmd);
|
||||||
}
|
}
|
||||||
|
@ -447,7 +448,7 @@ namespace OpenSim.Data.MySQL
|
||||||
get { return GetType().Assembly; }
|
get { return GetType().Assembly; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public MySqlGroupsNoticesHandler(string connectionString, string realm)
|
public MySqlGroupsNoticesHandler(string connectionString, string realm)
|
||||||
: base(connectionString, realm, string.Empty)
|
: base(connectionString, realm, string.Empty)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -475,7 +476,7 @@ namespace OpenSim.Data.MySQL
|
||||||
get { return GetType().Assembly; }
|
get { return GetType().Assembly; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public MySqlGroupsPrincipalsHandler(string connectionString, string realm)
|
public MySqlGroupsPrincipalsHandler(string connectionString, string realm)
|
||||||
: base(connectionString, realm, string.Empty)
|
: base(connectionString, realm, string.Empty)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,7 +78,6 @@ namespace OpenSim.Data.MySQL
|
||||||
dbcon.Open();
|
dbcon.Open();
|
||||||
Migration m = new Migration(dbcon, assem, "InventoryStore");
|
Migration m = new Migration(dbcon, assem, "InventoryStore");
|
||||||
m.Update();
|
m.Update();
|
||||||
dbcon.Close();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,7 +130,6 @@ namespace OpenSim.Data.MySQL
|
||||||
items.Add(item);
|
items.Add(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
dbcon.Close();
|
|
||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -172,7 +170,6 @@ namespace OpenSim.Data.MySQL
|
||||||
while (reader.Read())
|
while (reader.Read())
|
||||||
items.Add(readInventoryFolder(reader));
|
items.Add(readInventoryFolder(reader));
|
||||||
|
|
||||||
dbcon.Close();
|
|
||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -224,7 +221,6 @@ namespace OpenSim.Data.MySQL
|
||||||
if (items.Count > 0)
|
if (items.Count > 0)
|
||||||
rootFolder = items[0];
|
rootFolder = items[0];
|
||||||
|
|
||||||
dbcon.Close();
|
|
||||||
return rootFolder;
|
return rootFolder;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -265,7 +261,6 @@ namespace OpenSim.Data.MySQL
|
||||||
while (reader.Read())
|
while (reader.Read())
|
||||||
items.Add(readInventoryFolder(reader));
|
items.Add(readInventoryFolder(reader));
|
||||||
|
|
||||||
dbcon.Close();
|
|
||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -293,7 +288,7 @@ namespace OpenSim.Data.MySQL
|
||||||
// TODO: this is to handle a case where NULLs creep in there, which we are not sure is endemic to the system, or legacy. It would be nice to live fix these.
|
// TODO: this is to handle a case where NULLs creep in there, which we are not sure is endemic to the system, or legacy. It would be nice to live fix these.
|
||||||
// (DBGuid.FromDB() reads db NULLs as well, returns UUID.Zero)
|
// (DBGuid.FromDB() reads db NULLs as well, returns UUID.Zero)
|
||||||
item.CreatorId = reader["creatorID"].ToString();
|
item.CreatorId = reader["creatorID"].ToString();
|
||||||
|
|
||||||
// Be a bit safer in parsing these because the
|
// Be a bit safer in parsing these because the
|
||||||
// database doesn't enforce them to be not null, and
|
// database doesn't enforce them to be not null, and
|
||||||
// the inventory still works if these are weird in the
|
// the inventory still works if these are weird in the
|
||||||
|
@ -357,7 +352,6 @@ namespace OpenSim.Data.MySQL
|
||||||
if (reader.Read())
|
if (reader.Read())
|
||||||
item = readInventoryItem(reader);
|
item = readInventoryItem(reader);
|
||||||
|
|
||||||
dbcon.Close();
|
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -423,7 +417,6 @@ namespace OpenSim.Data.MySQL
|
||||||
if (reader.Read())
|
if (reader.Read())
|
||||||
folder = readInventoryFolder(reader);
|
folder = readInventoryFolder(reader);
|
||||||
|
|
||||||
dbcon.Close();
|
|
||||||
return folder;
|
return folder;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -460,7 +453,7 @@ namespace OpenSim.Data.MySQL
|
||||||
itemName = item.Name.Substring(0, 64);
|
itemName = item.Name.Substring(0, 64);
|
||||||
m_log.Warn("[INVENTORY DB]: Name field truncated from " + item.Name.Length + " to " + itemName.Length + " characters on add item");
|
m_log.Warn("[INVENTORY DB]: Name field truncated from " + item.Name.Length + " to " + itemName.Length + " characters on add item");
|
||||||
}
|
}
|
||||||
|
|
||||||
string itemDesc = item.Description;
|
string itemDesc = item.Description;
|
||||||
if (item.Description.Length > 128)
|
if (item.Description.Length > 128)
|
||||||
{
|
{
|
||||||
|
@ -497,10 +490,10 @@ namespace OpenSim.Data.MySQL
|
||||||
result.Parameters.AddWithValue("?groupID", item.GroupID);
|
result.Parameters.AddWithValue("?groupID", item.GroupID);
|
||||||
result.Parameters.AddWithValue("?groupOwned", item.GroupOwned);
|
result.Parameters.AddWithValue("?groupOwned", item.GroupOwned);
|
||||||
result.Parameters.AddWithValue("?flags", item.Flags);
|
result.Parameters.AddWithValue("?flags", item.Flags);
|
||||||
|
|
||||||
lock (m_dbLock)
|
lock (m_dbLock)
|
||||||
result.ExecuteNonQuery();
|
result.ExecuteNonQuery();
|
||||||
|
|
||||||
result.Dispose();
|
result.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -511,7 +504,6 @@ namespace OpenSim.Data.MySQL
|
||||||
lock (m_dbLock)
|
lock (m_dbLock)
|
||||||
result.ExecuteNonQuery();
|
result.ExecuteNonQuery();
|
||||||
}
|
}
|
||||||
dbcon.Close();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (MySqlException e)
|
catch (MySqlException e)
|
||||||
|
@ -548,7 +540,6 @@ namespace OpenSim.Data.MySQL
|
||||||
lock (m_dbLock)
|
lock (m_dbLock)
|
||||||
cmd.ExecuteNonQuery();
|
cmd.ExecuteNonQuery();
|
||||||
}
|
}
|
||||||
dbcon.Close();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (MySqlException e)
|
catch (MySqlException e)
|
||||||
|
@ -609,7 +600,6 @@ namespace OpenSim.Data.MySQL
|
||||||
m_log.Error(e.ToString());
|
m_log.Error(e.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dbcon.Close();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -640,7 +630,7 @@ namespace OpenSim.Data.MySQL
|
||||||
{
|
{
|
||||||
cmd.Parameters.AddWithValue("?folderID", folder.ID.ToString());
|
cmd.Parameters.AddWithValue("?folderID", folder.ID.ToString());
|
||||||
cmd.Parameters.AddWithValue("?parentFolderID", folder.ParentID.ToString());
|
cmd.Parameters.AddWithValue("?parentFolderID", folder.ParentID.ToString());
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
lock (m_dbLock)
|
lock (m_dbLock)
|
||||||
|
@ -653,7 +643,6 @@ namespace OpenSim.Data.MySQL
|
||||||
m_log.Error(e.ToString());
|
m_log.Error(e.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dbcon.Close();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -817,7 +806,6 @@ namespace OpenSim.Data.MySQL
|
||||||
lock (m_dbLock)
|
lock (m_dbLock)
|
||||||
cmd.ExecuteNonQuery();
|
cmd.ExecuteNonQuery();
|
||||||
}
|
}
|
||||||
dbcon.Close();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (MySqlException e)
|
catch (MySqlException e)
|
||||||
|
@ -845,7 +833,6 @@ namespace OpenSim.Data.MySQL
|
||||||
lock (m_dbLock)
|
lock (m_dbLock)
|
||||||
cmd.ExecuteNonQuery();
|
cmd.ExecuteNonQuery();
|
||||||
}
|
}
|
||||||
dbcon.Close();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (MySqlException e)
|
catch (MySqlException e)
|
||||||
|
@ -873,7 +860,7 @@ namespace OpenSim.Data.MySQL
|
||||||
deleteOneFolder(folderID);
|
deleteOneFolder(folderID);
|
||||||
deleteItemsInFolder(folderID);
|
deleteItemsInFolder(folderID);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<InventoryItemBase> fetchActiveGestures(UUID avatarID)
|
public List<InventoryItemBase> fetchActiveGestures(UUID avatarID)
|
||||||
{
|
{
|
||||||
lock (m_dbLock)
|
lock (m_dbLock)
|
||||||
|
@ -899,7 +886,6 @@ namespace OpenSim.Data.MySQL
|
||||||
if (item != null)
|
if (item != null)
|
||||||
list.Add(item);
|
list.Add(item);
|
||||||
}
|
}
|
||||||
dbcon.Close();
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,16 +39,16 @@ namespace OpenSim.Data.MySQL
|
||||||
{
|
{
|
||||||
/// <summary>This is a MySQL-customized migration processor. The only difference is in how
|
/// <summary>This is a MySQL-customized migration processor. The only difference is in how
|
||||||
/// it executes SQL scripts (using MySqlScript instead of MyCommand)
|
/// it executes SQL scripts (using MySqlScript instead of MyCommand)
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class MySqlMigration : Migration
|
public class MySqlMigration : Migration
|
||||||
{
|
{
|
||||||
public MySqlMigration()
|
public MySqlMigration()
|
||||||
: base()
|
: base()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public MySqlMigration(DbConnection conn, Assembly assem, string subtype, string type) :
|
public MySqlMigration(DbConnection conn, Assembly assem, string subtype, string type) :
|
||||||
base(conn, assem, subtype, type)
|
base(conn, assem, subtype, type)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@ namespace OpenSim.Data.MySQL
|
||||||
using (MySqlCommand cmd = new MySqlCommand())
|
using (MySqlCommand cmd = new MySqlCommand())
|
||||||
{
|
{
|
||||||
cmd.CommandText = String.Format("delete from {0} where TMStamp < NOW() - INTERVAL 2 WEEK", m_Realm);
|
cmd.CommandText = String.Format("delete from {0} where TMStamp < NOW() - INTERVAL 2 WEEK", m_Realm);
|
||||||
|
|
||||||
ExecuteNonQuery(cmd);
|
ExecuteNonQuery(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -66,9 +66,9 @@ namespace OpenSim.Data.MySQL
|
||||||
using (MySqlCommand cmd = new MySqlCommand())
|
using (MySqlCommand cmd = new MySqlCommand())
|
||||||
{
|
{
|
||||||
cmd.CommandText = String.Format("delete from {0} where `RegionID`=?RegionID", m_Realm);
|
cmd.CommandText = String.Format("delete from {0} where `RegionID`=?RegionID", m_Realm);
|
||||||
|
|
||||||
cmd.Parameters.AddWithValue("?RegionID", regionID.ToString());
|
cmd.Parameters.AddWithValue("?RegionID", regionID.ToString());
|
||||||
|
|
||||||
ExecuteNonQuery(cmd);
|
ExecuteNonQuery(cmd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -85,10 +85,10 @@ namespace OpenSim.Data.MySQL
|
||||||
using (MySqlCommand cmd = new MySqlCommand())
|
using (MySqlCommand cmd = new MySqlCommand())
|
||||||
{
|
{
|
||||||
cmd.CommandText = String.Format("update {0} set RegionID=?RegionID, LastSeen=NOW() where `SessionID`=?SessionID", m_Realm);
|
cmd.CommandText = String.Format("update {0} set RegionID=?RegionID, LastSeen=NOW() where `SessionID`=?SessionID", m_Realm);
|
||||||
|
|
||||||
cmd.Parameters.AddWithValue("?SessionID", sessionID.ToString());
|
cmd.Parameters.AddWithValue("?SessionID", sessionID.ToString());
|
||||||
cmd.Parameters.AddWithValue("?RegionID", regionID.ToString());
|
cmd.Parameters.AddWithValue("?RegionID", regionID.ToString());
|
||||||
|
|
||||||
if (ExecuteNonQuery(cmd) == 0)
|
if (ExecuteNonQuery(cmd) == 0)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,6 @@ namespace OpenSim.Data.MySQL
|
||||||
dbcon.Open();
|
dbcon.Open();
|
||||||
Migration m = new Migration(dbcon, Assembly, "GridStore");
|
Migration m = new Migration(dbcon, Assembly, "GridStore");
|
||||||
m.Update();
|
m.Update();
|
||||||
dbcon.Close();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,15 +80,16 @@ namespace OpenSim.Data.MySQL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public RegionData GetSpecific(string regionName, UUID scopeID)
|
public RegionData Get(int posX, int posY, UUID scopeID)
|
||||||
{
|
{
|
||||||
string command = "select * from `" + m_Realm + "` where regionName = ?regionName";
|
string command = "select * from `"+m_Realm+"` where locX = ?posX and locY = ?posY";
|
||||||
if (scopeID != UUID.Zero)
|
if (scopeID != UUID.Zero)
|
||||||
command += " and ScopeID = ?scopeID";
|
command += " and ScopeID = ?scopeID";
|
||||||
|
|
||||||
using (MySqlCommand cmd = new MySqlCommand(command))
|
using (MySqlCommand cmd = new MySqlCommand(command))
|
||||||
{
|
{
|
||||||
cmd.Parameters.AddWithValue("?regionName", regionName);
|
cmd.Parameters.AddWithValue("?posX", posX.ToString());
|
||||||
|
cmd.Parameters.AddWithValue("?posY", posY.ToString());
|
||||||
cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString());
|
cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString());
|
||||||
|
|
||||||
List<RegionData> ret = RunCommand(cmd);
|
List<RegionData> ret = RunCommand(cmd);
|
||||||
|
@ -98,48 +98,6 @@ namespace OpenSim.Data.MySQL
|
||||||
|
|
||||||
return ret[0];
|
return ret[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public RegionData Get(int posX, int posY, UUID scopeID)
|
|
||||||
{
|
|
||||||
string command = "select * from `" + m_Realm + "` where locX between ?startX and ?endX and locY between ?startY and ?endY";
|
|
||||||
if (scopeID != UUID.Zero)
|
|
||||||
command += " and ScopeID = ?scopeID";
|
|
||||||
|
|
||||||
int startX = posX - (int)Constants.MaximumRegionSize;
|
|
||||||
int startY = posY - (int)Constants.MaximumRegionSize;
|
|
||||||
int endX = posX;
|
|
||||||
int endY = posY;
|
|
||||||
|
|
||||||
List<RegionData> ret;
|
|
||||||
using (MySqlCommand cmd = new MySqlCommand(command))
|
|
||||||
{
|
|
||||||
cmd.Parameters.AddWithValue("?startX", startX.ToString());
|
|
||||||
cmd.Parameters.AddWithValue("?startY", startY.ToString());
|
|
||||||
cmd.Parameters.AddWithValue("?endX", endX.ToString());
|
|
||||||
cmd.Parameters.AddWithValue("?endY", endY.ToString());
|
|
||||||
cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString());
|
|
||||||
|
|
||||||
ret = RunCommand(cmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret.Count == 0)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
// find the first that contains pos
|
|
||||||
RegionData rg = null;
|
|
||||||
foreach (RegionData r in ret)
|
|
||||||
{
|
|
||||||
if (posX >= r.posX && posX < r.posX + r.sizeX
|
|
||||||
&& posY >= r.posY && posY < r.posY + r.sizeY)
|
|
||||||
{
|
|
||||||
rg = r;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return rg;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public RegionData Get(UUID regionID, UUID scopeID)
|
public RegionData Get(UUID regionID, UUID scopeID)
|
||||||
|
@ -163,7 +121,6 @@ namespace OpenSim.Data.MySQL
|
||||||
|
|
||||||
public List<RegionData> Get(int startX, int startY, int endX, int endY, UUID scopeID)
|
public List<RegionData> Get(int startX, int startY, int endX, int endY, UUID scopeID)
|
||||||
{
|
{
|
||||||
/* fix size regions
|
|
||||||
string command = "select * from `"+m_Realm+"` where locX between ?startX and ?endX and locY between ?startY and ?endY";
|
string command = "select * from `"+m_Realm+"` where locX between ?startX and ?endX and locY between ?startY and ?endY";
|
||||||
if (scopeID != UUID.Zero)
|
if (scopeID != UUID.Zero)
|
||||||
command += " and ScopeID = ?scopeID";
|
command += " and ScopeID = ?scopeID";
|
||||||
|
@ -178,38 +135,6 @@ namespace OpenSim.Data.MySQL
|
||||||
|
|
||||||
return RunCommand(cmd);
|
return RunCommand(cmd);
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
string command = "select * from `" + m_Realm + "` where locX between ?startX and ?endX and locY between ?startY and ?endY";
|
|
||||||
if (scopeID != UUID.Zero)
|
|
||||||
command += " and ScopeID = ?scopeID";
|
|
||||||
|
|
||||||
int qstartX = startX - (int)Constants.MaximumRegionSize;
|
|
||||||
int qstartY = startY - (int)Constants.MaximumRegionSize;
|
|
||||||
|
|
||||||
List<RegionData> dbret;
|
|
||||||
using (MySqlCommand cmd = new MySqlCommand(command))
|
|
||||||
{
|
|
||||||
cmd.Parameters.AddWithValue("?startX", qstartX.ToString());
|
|
||||||
cmd.Parameters.AddWithValue("?startY", qstartY.ToString());
|
|
||||||
cmd.Parameters.AddWithValue("?endX", endX.ToString());
|
|
||||||
cmd.Parameters.AddWithValue("?endY", endY.ToString());
|
|
||||||
cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString());
|
|
||||||
|
|
||||||
dbret = RunCommand(cmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
List<RegionData> ret = new List<RegionData>();
|
|
||||||
|
|
||||||
if (dbret.Count == 0)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
foreach (RegionData r in dbret)
|
|
||||||
{
|
|
||||||
if (r.posX + r.sizeX > startX && r.posX <= endX
|
|
||||||
&& r.posY + r.sizeY > startY && r.posY <= endY)
|
|
||||||
ret.Add(r);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<RegionData> RunCommand(MySqlCommand cmd)
|
public List<RegionData> RunCommand(MySqlCommand cmd)
|
||||||
|
@ -262,8 +187,6 @@ namespace OpenSim.Data.MySQL
|
||||||
retList.Add(ret);
|
retList.Add(ret);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cmd.Connection = null;
|
|
||||||
dbcon.Close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return retList;
|
return retList;
|
||||||
|
@ -414,7 +337,7 @@ namespace OpenSim.Data.MySQL
|
||||||
using (MySqlCommand cmd = new MySqlCommand(command))
|
using (MySqlCommand cmd = new MySqlCommand(command))
|
||||||
{
|
{
|
||||||
cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString());
|
cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString());
|
||||||
|
|
||||||
return RunCommand(cmd);
|
return RunCommand(cmd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue