Compare commits
80 Commits
master
...
cpu-perfor
Author | SHA1 | Date |
---|---|---|
Diva Canto | 47ce1a47bb | |
Diva Canto | 10def95c27 | |
Diva Canto | dab01a10d9 | |
Diva Canto | b44d96618c | |
Diva Canto | 3a6c690e69 | |
Diva Canto | 051cf81c9f | |
Diva Canto | c7a3714c37 | |
Diva Canto | 1815c2f98c | |
Diva Canto | 7c884d16f4 | |
Diva Canto | f3d31e6e53 | |
Diva Canto | 701e15760c | |
Diva Canto | 2b696bc0c8 | |
Justin Clark-Casey (justincc) | 9e277b54b9 | |
Justin Clark-Casey (justincc) | 805ac6435e | |
Justin Clark-Casey (justincc) | 511801c607 | |
Diva Canto | ff294dce6c | |
Diva Canto | 9c1ec98415 | |
Diva Canto | 01561166aa | |
Diva Canto | 8d1108e542 | |
Diva Canto | be4034fd1c | |
Diva Canto | 87a19d4cab | |
Justin Clark-Casey (justincc) | 35e46c2836 | |
Justin Clark-Casey (justincc) | 0d90834f86 | |
Justin Clark-Casey (justincc) | 0755fc2f65 | |
Justin Clark-Casey (justincc) | 94072fb633 | |
Robert Adams | 882efc1a2e | |
Justin Clark-Casey (justincc) | deace1f344 | |
Justin Clark-Casey (justincc) | 7f0f3cc011 | |
Diva Canto | c163276032 | |
Diva Canto | a2a05d470e | |
Diva Canto | d5f8b7924c | |
Diva Canto | d70a0c09cb | |
Diva Canto | df09fdf65d | |
Diva Canto | 37337a4de9 | |
Diva Canto | 8d98d287bd | |
Diva Canto | e1404adac6 | |
Diva Canto | 1d27c9f4d1 | |
Diva Canto | 428b51ffda | |
Diva Canto | fe2487f8d3 | |
Diva Canto | b69ddbb66b | |
Diva Canto | 1cb5e31716 | |
Diva Canto | 7f60800ca6 | |
Diva Canto | ceaa7e9a54 | |
Diva Canto | cab3e9978b | |
Diva Canto | 049022717c | |
Diva Canto | 40c54a718f | |
Diva Canto | 315097b8b9 | |
Diva Canto | 5e5aa5fba7 | |
Diva Canto | 9801d0d4c8 | |
Diva Canto | d95a470442 | |
Diva Canto | 74a341fd22 | |
Diva Canto | 95b248e9e5 | |
Diva Canto | 340abd1110 | |
Diva Canto | 0910c5c101 | |
Diva Canto | f0126a1575 | |
Diva Canto | 0d5b2dd5ce | |
Diva Canto | 64cda1b26e | |
Diva Canto | 778babaab2 | |
Diva Canto | d30e5f7ded | |
Robert Adams | f05654d8d6 | |
Diva Canto | 52bb732692 | |
Diva Canto | dc88ffc5b4 | |
Justin Clark-Casey (justincc) | 07420a3b4d | |
Justin Clark-Casey (justincc) | 42e5856464 | |
Justin Clark-Casey (justincc) | 3b8e7ff013 | |
Justin Clark-Casey (justincc) | 5c74f3ec9c | |
Diva Canto | d1e9beead8 | |
Justin Clark-Casey (justincc) | 35aa6c86fe | |
Justin Clark-Casey (justincc) | 5cdc21aac7 | |
Justin Clark-Casey (justincc) | cbb47f8489 | |
Justin Clark-Casey (justincc) | b2b29b7ec0 | |
Diva Canto | 27377194cd | |
Justin Clark-Casey (justincc) | 8c6761c152 | |
Diva Canto | 553d9cc5d2 | |
Diva Canto | c685cc1799 | |
Justin Clark-Casey (justincc) | 1ba5a05cf7 | |
Justin Clark-Casey (justincc) | 0af3b5ed9a | |
Justin Clark-Casey (justincc) | a94a43d249 | |
Justin Clark-Casey (justincc) | 7c544c0d4e | |
Justin Clark-Casey (justincc) | b402220dbb |
|
@ -1,6 +1,5 @@
|
||||||
.project
|
.project
|
||||||
.settings
|
.settings
|
||||||
.gitignore
|
|
||||||
*.csproj
|
*.csproj
|
||||||
*.csproj.user
|
*.csproj.user
|
||||||
*.build
|
*.build
|
||||||
|
@ -11,13 +10,6 @@
|
||||||
*.pidb
|
*.pidb
|
||||||
*.dll.build
|
*.dll.build
|
||||||
*.dll
|
*.dll
|
||||||
*.log
|
|
||||||
|
|
||||||
# Ignore .user and .suo files as these are user preference specific
|
|
||||||
# http://stackoverflow.com/questions/72298/should-i-add-the-visual-studio-suo-and-user-files-to-source-control
|
|
||||||
*.suo
|
|
||||||
*.user
|
|
||||||
|
|
||||||
*.VisualState.xml
|
*.VisualState.xml
|
||||||
*/*/obj
|
*/*/obj
|
||||||
*/*/*/obj
|
*/*/*/obj
|
||||||
|
@ -31,8 +23,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
|
||||||
|
@ -58,7 +48,6 @@ bin/Regions/*
|
||||||
bin/UserAssets
|
bin/UserAssets
|
||||||
bin/assetcache
|
bin/assetcache
|
||||||
bin/maptiles
|
bin/maptiles
|
||||||
bin/bakes
|
|
||||||
bin/estate_settings.xml
|
bin/estate_settings.xml
|
||||||
bin/config-include/CenomeCache.ini
|
bin/config-include/CenomeCache.ini
|
||||||
bin/config-include/FlotsamCache.ini
|
bin/config-include/FlotsamCache.ini
|
||||||
|
@ -71,17 +60,12 @@ 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
|
||||||
OpenSim.build
|
OpenSim.build
|
||||||
OpenSim.sln
|
OpenSim.sln
|
||||||
|
OpenSim.suo
|
||||||
OpenSim.userprefs
|
OpenSim.userprefs
|
||||||
Prebuild/Prebuild.build
|
Prebuild/Prebuild.build
|
||||||
Prebuild/Prebuild.sln
|
Prebuild/Prebuild.sln
|
||||||
|
@ -94,6 +78,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 +97,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">
|
||||||
|
|
31
BUILDING.md
31
BUILDING.md
|
@ -1,35 +1,34 @@
|
||||||
# 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
|
|
||||||
* linux: run ./opensim.sh
|
# Using Monodevelop
|
||||||
* msbuild (xbuild) option switches
|
|
||||||
* clean: msbuild /target:clean
|
From the distribution type:
|
||||||
* debug: (default) msbuild /property:Configuration=Debug
|
* ./runprebuild.sh
|
||||||
* release: msbuild /property:Configuration=Release
|
* type monodevelop OpenSim.sln
|
||||||
|
|
||||||
# References
|
# References
|
||||||
|
|
||||||
|
|
104
CONTRIBUTORS.txt
104
CONTRIBUTORS.txt
|
@ -1,22 +1,39 @@
|
||||||
The following people have contributed to OpenSim (Thank you for your effort!)
|
<<<>>>>The following people have contributed to OpenSim (Thank you
|
||||||
|
for your effort!)
|
||||||
|
|
||||||
= Current OpenSim Developers (in very rough order of appearance) =
|
= Current OpenSim Developers (in very rough order of appearance) =
|
||||||
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 (Intel)
|
||||||
* Kevin Cozens
|
* Marck
|
||||||
* Leal Duarte (Ubit Umarov)
|
* Mic Bowman (Intel)
|
||||||
|
* BlueWall (James Hughes)
|
||||||
|
* Nebadon Izumi (Michael Cerquoni, OSgrid)
|
||||||
|
* Snoopy Pfeffer
|
||||||
|
* Robert Adams (Intel)
|
||||||
|
|
||||||
= 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,86 +55,49 @@ 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
|
||||||
what it is today.
|
what it is today.
|
||||||
|
|
||||||
* A_Biondi
|
|
||||||
* aduffy70
|
* aduffy70
|
||||||
* Ai Austin
|
* A_Biondi
|
||||||
* alex_carnell
|
* alex_carnell
|
||||||
* Alan Webb (IBM)
|
* Alan Webb (IBM)
|
||||||
* Aleric
|
|
||||||
* Allen Kerensky
|
* Allen Kerensky
|
||||||
* BigFootAg
|
* BigFootAg
|
||||||
* Bill Blight
|
|
||||||
* BlueWall Slade
|
* BlueWall Slade
|
||||||
* bobshaffer2
|
|
||||||
* brianw/Sir_Ahzz
|
* brianw/Sir_Ahzz
|
||||||
* CharlieO
|
* CharlieO
|
||||||
* ChrisDown
|
* ChrisDown
|
||||||
* Chris Yeoh (IBM)
|
* Chris Yeoh (IBM)
|
||||||
* cinderblocks
|
|
||||||
* controlbreak
|
* controlbreak
|
||||||
* coyled
|
* coyled
|
||||||
* ctrlaltdavid (David Rowe)
|
|
||||||
* Daedius
|
* Daedius
|
||||||
* daTwitch
|
* daTwitch
|
||||||
* Dev Random
|
|
||||||
* devalnor-#708
|
* devalnor-#708
|
||||||
* dmiles (Daxtron Labs)
|
* dmiles (Daxtron Labs)
|
||||||
* Dong Jun Lan (IBM)
|
* Dong Jun Lan (IBM)
|
||||||
* DoranZemlja
|
* DoranZemlja
|
||||||
* Drake Arconis
|
|
||||||
* dr0b3rts
|
* dr0b3rts
|
||||||
* dslake
|
* dslake (Intel)
|
||||||
* eeyore
|
|
||||||
* FredoChaplin
|
* FredoChaplin
|
||||||
* FreakyTech
|
|
||||||
* Garmin Kawaguichi
|
* Garmin Kawaguichi
|
||||||
* Gavin Hird
|
|
||||||
* Gerhard
|
* Gerhard
|
||||||
* Godfrey
|
* Godfrey
|
||||||
* Greg C.
|
|
||||||
* Grumly57
|
* Grumly57
|
||||||
* GuduleLapointe
|
* GuduleLapointe
|
||||||
* Ewe Loon
|
* Ewe Loon
|
||||||
* 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)
|
|
||||||
* Hiro Lecker
|
* Hiro Lecker
|
||||||
* Iain Oliver
|
* Iain Oliver
|
||||||
* Imaze Rhiano
|
* Imaze Rhiano
|
||||||
* Intimidated
|
* Intimidated
|
||||||
* Jak Daniels
|
|
||||||
* Jeff Kelly
|
|
||||||
* Jeremy Bongio (IBM)
|
* Jeremy Bongio (IBM)
|
||||||
* jhurliman
|
* jhurliman
|
||||||
* John R Sohn (XenReborn)
|
* John R Sohn (XenReborn)
|
||||||
|
@ -125,36 +105,25 @@ what it is today.
|
||||||
* Jon Cundill
|
* Jon Cundill
|
||||||
* Junta Kohime
|
* Junta Kohime
|
||||||
* Kayne
|
* Kayne
|
||||||
|
* Kevin Cozens
|
||||||
* kinoc (Daxtron Labs)
|
* kinoc (Daxtron Labs)
|
||||||
* Kira
|
|
||||||
* Kitto Flora
|
* Kitto Flora
|
||||||
* KittyLiu
|
* KittyLiu
|
||||||
* Kurt Taylor (IBM)
|
* Kurt Taylor (IBM)
|
||||||
* Lani Global
|
|
||||||
* lickx
|
|
||||||
* lillith_xue
|
|
||||||
* lkalif
|
* lkalif
|
||||||
* LuciusSirnah
|
|
||||||
* lulurun
|
* lulurun
|
||||||
* M.Igarashi
|
* M.Igarashi
|
||||||
* Magnuz Binder
|
|
||||||
* maimedleech
|
* maimedleech
|
||||||
* Mana Janus
|
* Mana Janus
|
||||||
* Mandarinka Tasty
|
|
||||||
* MarcelEdward
|
* MarcelEdward
|
||||||
* 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
|
|
||||||
* mikkopa/_someone - RealXtend
|
* mikkopa/_someone - RealXtend
|
||||||
* Misterblue
|
* Misterblue (Intel)
|
||||||
* Mircea Kitsune
|
* Mircea Kitsune
|
||||||
* mpallari
|
* mpallari
|
||||||
* MrMonkE
|
* MrMonkE
|
||||||
|
@ -163,42 +132,32 @@ what it is today.
|
||||||
* nornalbion
|
* nornalbion
|
||||||
* Omar Vera Ustariz (IBM)
|
* Omar Vera Ustariz (IBM)
|
||||||
* openlifegrid.com
|
* openlifegrid.com
|
||||||
|
* Oren Hurvitz (Kitely)
|
||||||
* 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)
|
|
||||||
* rtomita
|
* rtomita
|
||||||
* Ruud Lathorp
|
* Ruud Lathorp
|
||||||
* SachaMagne
|
* SachaMagne
|
||||||
* Salahzar Stenvaag
|
* Salahzar Stenvaag
|
||||||
* satguru p srivastava
|
* satguru p srivastava
|
||||||
* sempuki
|
* sempuki
|
||||||
* Shy Robbiani
|
|
||||||
* 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)
|
||||||
|
@ -210,18 +169,23 @@ what it is today.
|
||||||
* Zha Ewry
|
* Zha Ewry
|
||||||
* ziah
|
* ziah
|
||||||
|
|
||||||
|
|
||||||
= LSL Devs =
|
= LSL Devs =
|
||||||
|
|
||||||
* Alondria
|
* Alondria
|
||||||
* CharlieO
|
* CharlieO
|
||||||
* Tedd
|
* Tedd
|
||||||
* Melanie Thielker
|
* Melanie Thielker
|
||||||
|
|
||||||
|
|
||||||
= Testers =
|
= Testers =
|
||||||
|
|
||||||
* Ai Austin
|
* Ai Austin
|
||||||
* CharlieO (LSL)
|
* CharlieO (LSL)
|
||||||
* Ckrinke
|
* Ckrinke
|
||||||
* openlifegrid.com
|
* openlifegrid.com
|
||||||
|
|
||||||
|
|
||||||
This software uses components from the following developers:
|
This software uses components from the following developers:
|
||||||
* Sleepycat Software (Berkeley DB)
|
* Sleepycat Software (Berkeley DB)
|
||||||
* Aurora-Sim (http://aurora-sim.org)
|
* Aurora-Sim (http://aurora-sim.org)
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -30,7 +30,6 @@ using System.Collections.Generic;
|
||||||
|
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
using OpenSim.Region.Framework.Interfaces;
|
||||||
using OpenSim.Services.Interfaces;
|
|
||||||
|
|
||||||
namespace OpenSim.Groups
|
namespace OpenSim.Groups
|
||||||
{
|
{
|
||||||
|
|
|
@ -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
|
||||||
|
@ -174,7 +174,7 @@ namespace OpenSim.Groups
|
||||||
if (dict.ContainsKey("ServiceLocation") && dict["ServiceLocation"] != null)
|
if (dict.ContainsKey("ServiceLocation") && dict["ServiceLocation"] != null)
|
||||||
grec.ServiceLocation = dict["ServiceLocation"].ToString();
|
grec.ServiceLocation = dict["ServiceLocation"].ToString();
|
||||||
else
|
else
|
||||||
grec.ServiceLocation = string.Empty;
|
grec.GroupName = string.Empty;
|
||||||
|
|
||||||
if (dict.ContainsKey("ShownInList") && dict["ShownInList"] != null)
|
if (dict.ContainsKey("ShownInList") && dict["ShownInList"] != null)
|
||||||
grec.ShowInList = bool.Parse(dict["ShownInList"].ToString());
|
grec.ShowInList = bool.Parse(dict["ShownInList"].ToString());
|
||||||
|
@ -504,30 +504,6 @@ namespace OpenSim.Groups
|
||||||
|
|
||||||
return notice;
|
return notice;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Dictionary<string, object> DirGroupsReplyData(DirGroupsReplyData g)
|
|
||||||
{
|
|
||||||
Dictionary<string, object> dict = new Dictionary<string, object>();
|
|
||||||
|
|
||||||
dict["GroupID"] = g.groupID;
|
|
||||||
dict["Name"] = g.groupName;
|
|
||||||
dict["NMembers"] = g.members;
|
|
||||||
dict["SearchOrder"] = g.searchOrder;
|
|
||||||
|
|
||||||
return dict;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static DirGroupsReplyData DirGroupsReplyData(Dictionary<string, object> dict)
|
|
||||||
{
|
|
||||||
DirGroupsReplyData g;
|
|
||||||
|
|
||||||
g.groupID = new UUID(dict["GroupID"].ToString());
|
|
||||||
g.groupName = dict["Name"].ToString();
|
|
||||||
Int32.TryParse(dict["NMembers"].ToString(), out g.members);
|
|
||||||
float.TryParse(dict["SearchOrder"].ToString(), out g.searchOrder);
|
|
||||||
|
|
||||||
return g;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,6 @@ using OpenSim.Region.Framework.Interfaces;
|
||||||
using OpenSim.Region.Framework.Scenes;
|
using OpenSim.Region.Framework.Scenes;
|
||||||
using OpenSim.Services.Interfaces;
|
using OpenSim.Services.Interfaces;
|
||||||
using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo;
|
using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo;
|
||||||
using GridRegion = OpenSim.Services.Interfaces.GridRegion;
|
|
||||||
|
|
||||||
namespace OpenSim.Groups
|
namespace OpenSim.Groups
|
||||||
{
|
{
|
||||||
|
@ -52,12 +51,12 @@ namespace OpenSim.Groups
|
||||||
private IPresenceService m_presenceService;
|
private IPresenceService m_presenceService;
|
||||||
|
|
||||||
private IMessageTransferModule m_msgTransferModule = null;
|
private IMessageTransferModule m_msgTransferModule = null;
|
||||||
private IUserManagement m_UserManagement = null;
|
|
||||||
private IGroupsServicesConnector m_groupData = null;
|
private IGroupsServicesConnector m_groupData = null;
|
||||||
|
|
||||||
// Config Options
|
// Config Options
|
||||||
private bool m_groupMessagingEnabled;
|
private bool m_groupMessagingEnabled = false;
|
||||||
private bool m_debugEnabled;
|
private bool m_debugEnabled = true;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// If enabled, module only tries to send group IMs to online users by querying cached presence information.
|
/// If enabled, module only tries to send group IMs to online users by querying cached presence information.
|
||||||
|
@ -80,9 +79,6 @@ namespace OpenSim.Groups
|
||||||
|
|
||||||
private int m_usersOnlineCacheExpirySeconds = 20;
|
private int m_usersOnlineCacheExpirySeconds = 20;
|
||||||
|
|
||||||
private Dictionary<UUID, List<string>> m_groupsAgentsDroppedFromChatSession = new Dictionary<UUID, List<string>>();
|
|
||||||
private Dictionary<UUID, List<string>> m_groupsAgentsInvitedToChatSession = new Dictionary<UUID, List<string>>();
|
|
||||||
|
|
||||||
#region Region Module interfaceBase Members
|
#region Region Module interfaceBase Members
|
||||||
|
|
||||||
public void Initialise(IConfigSource config)
|
public void Initialise(IConfigSource config)
|
||||||
|
@ -110,17 +106,9 @@ namespace OpenSim.Groups
|
||||||
m_messageOnlineAgentsOnly = groupsConfig.GetBoolean("MessageOnlineUsersOnly", false);
|
m_messageOnlineAgentsOnly = groupsConfig.GetBoolean("MessageOnlineUsersOnly", false);
|
||||||
|
|
||||||
if (m_messageOnlineAgentsOnly)
|
if (m_messageOnlineAgentsOnly)
|
||||||
{
|
|
||||||
m_usersOnlineCache = new ExpiringCache<UUID, PresenceInfo[]>();
|
m_usersOnlineCache = new ExpiringCache<UUID, PresenceInfo[]>();
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_log.Error("[Groups.Messaging]: GroupsMessagingModule V2 requires MessageOnlineUsersOnly = true");
|
|
||||||
m_groupMessagingEnabled = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_debugEnabled = groupsConfig.GetBoolean("MessagingDebugEnabled", m_debugEnabled);
|
m_debugEnabled = groupsConfig.GetBoolean("DebugEnabled", true);
|
||||||
|
|
||||||
m_log.InfoFormat(
|
m_log.InfoFormat(
|
||||||
"[Groups.Messaging]: GroupsMessagingModule enabled with MessageOnlineOnly = {0}, DebugEnabled = {1}",
|
"[Groups.Messaging]: GroupsMessagingModule enabled with MessageOnlineOnly = {0}, DebugEnabled = {1}",
|
||||||
|
@ -131,25 +119,15 @@ 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);
|
||||||
|
|
||||||
scene.EventManager.OnNewClient += OnNewClient;
|
scene.EventManager.OnNewClient += OnNewClient;
|
||||||
scene.EventManager.OnMakeRootAgent += OnMakeRootAgent;
|
|
||||||
scene.EventManager.OnMakeChildAgent += OnMakeChildAgent;
|
|
||||||
scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage;
|
scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage;
|
||||||
scene.EventManager.OnClientLogin += OnClientLogin;
|
scene.EventManager.OnClientLogin += OnClientLogin;
|
||||||
|
|
||||||
scene.AddCommand(
|
|
||||||
"Debug",
|
|
||||||
this,
|
|
||||||
"debug groups messaging verbose",
|
|
||||||
"debug groups messaging verbose <true|false>",
|
|
||||||
"This setting turns on very verbose groups messaging debugging",
|
|
||||||
HandleDebugGroupsMessagingVerbose);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RegionLoaded(Scene scene)
|
public void RegionLoaded(Scene scene)
|
||||||
{
|
{
|
||||||
if (!m_groupMessagingEnabled)
|
if (!m_groupMessagingEnabled)
|
||||||
|
@ -163,7 +141,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,18 +155,9 @@ namespace OpenSim.Groups
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_UserManagement = scene.RequestModuleInterface<IUserManagement>();
|
|
||||||
|
|
||||||
// No groups module, no groups messaging
|
|
||||||
if (m_UserManagement == null)
|
|
||||||
{
|
|
||||||
m_log.Error("[Groups.Messaging]: Could not get IUserManagement, GroupsMessagingModule is now disabled.");
|
|
||||||
RemoveRegion(scene);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_presenceService == null)
|
if (m_presenceService == null)
|
||||||
m_presenceService = scene.PresenceService;
|
m_presenceService = scene.PresenceService;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveRegion(Scene scene)
|
public void RemoveRegion(Scene scene)
|
||||||
|
@ -218,7 +187,7 @@ namespace OpenSim.Groups
|
||||||
m_msgTransferModule = null;
|
m_msgTransferModule = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Type ReplaceableInterface
|
public Type ReplaceableInterface
|
||||||
{
|
{
|
||||||
get { return null; }
|
get { return null; }
|
||||||
}
|
}
|
||||||
|
@ -235,25 +204,6 @@ namespace OpenSim.Groups
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
private void HandleDebugGroupsMessagingVerbose(object modules, string[] args)
|
|
||||||
{
|
|
||||||
if (args.Length < 5)
|
|
||||||
{
|
|
||||||
MainConsole.Instance.Output("Usage: debug groups messaging verbose <true|false>");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool verbose = false;
|
|
||||||
if (!bool.TryParse(args[4], out verbose))
|
|
||||||
{
|
|
||||||
MainConsole.Instance.Output("Usage: debug groups messaging verbose <true|false>");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_debugEnabled = verbose;
|
|
||||||
|
|
||||||
MainConsole.Instance.Output("{0} verbose logging set to {1}", Name, m_debugEnabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Not really needed, but does confirm that the group exists.
|
/// Not really needed, but does confirm that the group exists.
|
||||||
|
@ -262,7 +212,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)
|
||||||
|
@ -274,147 +224,95 @@ namespace OpenSim.Groups
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendMessageToGroup(GridInstantMessage im, UUID groupID)
|
public void SendMessageToGroup(GridInstantMessage im, UUID groupID)
|
||||||
{
|
{
|
||||||
SendMessageToGroup(im, groupID, UUID.Zero, null);
|
List<GroupMembersData> groupMembers = m_groupData.GetGroupMembers(new UUID(im.fromAgentID).ToString(), groupID);
|
||||||
}
|
|
||||||
|
|
||||||
public void SendMessageToGroup(
|
|
||||||
GridInstantMessage im, UUID groupID, UUID sendingAgentForGroupCalls, Func<GroupMembersData, bool> sendCondition)
|
|
||||||
{
|
|
||||||
int requestStartTick = Environment.TickCount;
|
|
||||||
|
|
||||||
UUID fromAgentID = new UUID(im.fromAgentID);
|
|
||||||
|
|
||||||
// Unlike current XmlRpcGroups, Groups V2 can accept UUID.Zero when a perms check for the requesting agent
|
|
||||||
// is not necessary.
|
|
||||||
List<GroupMembersData> groupMembers = m_groupData.GetGroupMembers(UUID.Zero.ToString(), groupID);
|
|
||||||
|
|
||||||
int groupMembersCount = groupMembers.Count;
|
int groupMembersCount = groupMembers.Count;
|
||||||
PresenceInfo[] onlineAgents = null;
|
|
||||||
|
|
||||||
// In V2 we always only send to online members.
|
if (m_messageOnlineAgentsOnly)
|
||||||
// Sending to offline members is not an option.
|
|
||||||
string[] t1 = groupMembers.ConvertAll<string>(gmd => gmd.AgentID.ToString()).ToArray();
|
|
||||||
|
|
||||||
// We cache in order not to overwhelm the presence service on large grids with many groups. This does
|
|
||||||
// mean that members coming online will not see all group members until after m_usersOnlineCacheExpirySeconds has elapsed.
|
|
||||||
// (assuming this is the same across all grid simulators).
|
|
||||||
if (!m_usersOnlineCache.TryGetValue(groupID, out onlineAgents))
|
|
||||||
{
|
{
|
||||||
onlineAgents = m_presenceService.GetAgents(t1);
|
string[] t1 = groupMembers.ConvertAll<string>(gmd => gmd.AgentID.ToString()).ToArray();
|
||||||
m_usersOnlineCache.Add(groupID, onlineAgents, m_usersOnlineCacheExpirySeconds);
|
|
||||||
}
|
|
||||||
|
|
||||||
HashSet<string> onlineAgentsUuidSet = new HashSet<string>();
|
// We cache in order not to overwhlem the presence service on large grids with many groups. This does
|
||||||
Array.ForEach<PresenceInfo>(onlineAgents, pi => onlineAgentsUuidSet.Add(pi.UserID));
|
// mean that members coming online will not see all group members until after m_usersOnlineCacheExpirySeconds has elapsed.
|
||||||
|
// (assuming this is the same across all grid simulators).
|
||||||
|
PresenceInfo[] onlineAgents;
|
||||||
|
if (!m_usersOnlineCache.TryGetValue(groupID, out onlineAgents))
|
||||||
|
{
|
||||||
|
onlineAgents = m_presenceService.GetAgents(t1);
|
||||||
|
m_usersOnlineCache.Add(groupID, onlineAgents, m_usersOnlineCacheExpirySeconds);
|
||||||
|
}
|
||||||
|
|
||||||
groupMembers = groupMembers.Where(gmd => onlineAgentsUuidSet.Contains(gmd.AgentID.ToString())).ToList();
|
HashSet<string> onlineAgentsUuidSet = new HashSet<string>();
|
||||||
|
Array.ForEach<PresenceInfo>(onlineAgents, pi => onlineAgentsUuidSet.Add(pi.UserID));
|
||||||
|
|
||||||
// if (m_debugEnabled)
|
groupMembers = groupMembers.Where(gmd => onlineAgentsUuidSet.Contains(gmd.AgentID.ToString())).ToList();
|
||||||
|
|
||||||
|
// if (m_debugEnabled)
|
||||||
// m_log.DebugFormat(
|
// m_log.DebugFormat(
|
||||||
// "[Groups.Messaging]: SendMessageToGroup called for group {0} with {1} visible members, {2} online",
|
// "[Groups.Messaging]: SendMessageToGroup called for group {0} with {1} visible members, {2} online",
|
||||||
// groupID, groupMembersCount, groupMembers.Count());
|
// groupID, groupMembersCount, groupMembers.Count());
|
||||||
|
}
|
||||||
im.imSessionID = groupID.Guid;
|
else
|
||||||
im.fromGroup = true;
|
|
||||||
IClientAPI thisClient = GetActiveClient(fromAgentID);
|
|
||||||
if (thisClient != null)
|
|
||||||
{
|
{
|
||||||
im.RegionID = thisClient.Scene.RegionInfo.RegionID.Guid;
|
if (m_debugEnabled)
|
||||||
|
m_log.DebugFormat(
|
||||||
|
"[Groups.Messaging]: SendMessageToGroup called for group {0} with {1} visible members",
|
||||||
|
groupID, groupMembers.Count);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((im.binaryBucket == null) || (im.binaryBucket.Length == 0) || ((im.binaryBucket.Length == 1 && im.binaryBucket[0] == 0)))
|
int requestStartTick = Environment.TickCount;
|
||||||
{
|
|
||||||
ExtendedGroupRecord groupInfo = m_groupData.GetGroupRecord(UUID.Zero.ToString(), groupID, null);
|
|
||||||
if (groupInfo != null)
|
|
||||||
im.binaryBucket = Util.StringToBytes256(groupInfo.GroupName);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send to self first of all
|
|
||||||
im.toAgentID = im.fromAgentID;
|
|
||||||
im.fromGroup = true;
|
|
||||||
ProcessMessageFromGroupSession(im);
|
|
||||||
|
|
||||||
List<UUID> regions = new List<UUID>();
|
|
||||||
List<UUID> clientsAlreadySent = new List<UUID>();
|
|
||||||
|
|
||||||
// Then send to everybody else
|
|
||||||
foreach (GroupMembersData member in groupMembers)
|
foreach (GroupMembersData member in groupMembers)
|
||||||
{
|
{
|
||||||
if (member.AgentID.Guid == im.fromAgentID)
|
if (m_groupData.hasAgentDroppedGroupChatSession(member.AgentID.ToString(), groupID))
|
||||||
continue;
|
|
||||||
|
|
||||||
if (clientsAlreadySent.Contains(member.AgentID))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
clientsAlreadySent.Add(member.AgentID);
|
|
||||||
|
|
||||||
if (sendCondition != null)
|
|
||||||
{
|
|
||||||
if (!sendCondition(member))
|
|
||||||
{
|
|
||||||
if (m_debugEnabled)
|
|
||||||
m_log.DebugFormat(
|
|
||||||
"[Groups.Messaging]: Not sending to {0} as they do not fulfill send condition",
|
|
||||||
member.AgentID);
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (hasAgentDroppedGroupChatSession(member.AgentID.ToString(), groupID))
|
|
||||||
{
|
{
|
||||||
// Don't deliver messages to people who have dropped this session
|
// 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
im.toAgentID = member.AgentID.Guid;
|
// Copy Message
|
||||||
|
GridInstantMessage msg = new GridInstantMessage();
|
||||||
|
msg.imSessionID = groupID.Guid;
|
||||||
|
msg.fromAgentName = im.fromAgentName;
|
||||||
|
msg.message = im.message;
|
||||||
|
msg.dialog = im.dialog;
|
||||||
|
msg.offline = im.offline;
|
||||||
|
msg.ParentEstateID = im.ParentEstateID;
|
||||||
|
msg.Position = im.Position;
|
||||||
|
msg.RegionID = im.RegionID;
|
||||||
|
msg.binaryBucket = im.binaryBucket;
|
||||||
|
msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
|
||||||
|
|
||||||
|
msg.fromAgentID = im.fromAgentID;
|
||||||
|
msg.fromGroup = true;
|
||||||
|
|
||||||
|
msg.toAgentID = member.AgentID.Guid;
|
||||||
|
|
||||||
IClientAPI client = GetActiveClient(member.AgentID);
|
IClientAPI client = GetActiveClient(member.AgentID);
|
||||||
if (client == null)
|
if (client == null)
|
||||||
{
|
{
|
||||||
// If they're not local, forward across the grid
|
// If they're not local, forward across the grid
|
||||||
// BUT do it only once per region, please! Sim would be even better!
|
|
||||||
if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Delivering to {0} via Grid", member.AgentID);
|
if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Delivering to {0} via Grid", member.AgentID);
|
||||||
|
m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { });
|
||||||
bool reallySend = true;
|
|
||||||
if (onlineAgents != null)
|
|
||||||
{
|
|
||||||
PresenceInfo presence = onlineAgents.First(p => p.UserID == member.AgentID.ToString());
|
|
||||||
if (regions.Contains(presence.RegionID))
|
|
||||||
reallySend = false;
|
|
||||||
else
|
|
||||||
regions.Add(presence.RegionID);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (reallySend)
|
|
||||||
{
|
|
||||||
// We have to create a new IM structure because the transfer module
|
|
||||||
// uses async send
|
|
||||||
GridInstantMessage msg = new GridInstantMessage(im, true);
|
|
||||||
m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Deliver locally, directly
|
// Deliver locally, directly
|
||||||
if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Passing to ProcessMessageFromGroupSession to deliver to {0} locally", client.Name);
|
if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Passing to ProcessMessageFromGroupSession to deliver to {0} locally", client.Name);
|
||||||
|
ProcessMessageFromGroupSession(msg);
|
||||||
ProcessMessageFromGroupSession(im);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_debugEnabled)
|
// Temporary for assessing how long it still takes to send messages to large online groups.
|
||||||
|
if (m_messageOnlineAgentsOnly)
|
||||||
m_log.DebugFormat(
|
m_log.DebugFormat(
|
||||||
"[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)
|
||||||
|
@ -426,113 +324,32 @@ namespace OpenSim.Groups
|
||||||
{
|
{
|
||||||
if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: OnInstantMessage registered for {0}", client.Name);
|
if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: OnInstantMessage registered for {0}", client.Name);
|
||||||
|
|
||||||
ResetAgentGroupChatSessions(client.AgentId.ToString());
|
client.OnInstantMessage += OnInstantMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnMakeRootAgent(ScenePresence sp)
|
|
||||||
{
|
|
||||||
sp.ControllingClient.OnInstantMessage += OnInstantMessage;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnMakeChildAgent(ScenePresence sp)
|
|
||||||
{
|
|
||||||
sp.ControllingClient.OnInstantMessage -= OnInstantMessage;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void OnGridInstantMessage(GridInstantMessage msg)
|
private void OnGridInstantMessage(GridInstantMessage msg)
|
||||||
{
|
{
|
||||||
// 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);
|
|
||||||
if (m_debugEnabled)
|
if (m_debugEnabled)
|
||||||
{
|
{
|
||||||
m_log.DebugFormat("[Groups.Messaging]: {0} called, IM from region {1}",
|
m_log.DebugFormat("[Groups.Messaging]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
|
||||||
System.Reflection.MethodBase.GetCurrentMethod().Name, regionID);
|
|
||||||
|
|
||||||
DebugGridInstantMessage(msg);
|
DebugGridInstantMessage(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Incoming message from a group
|
// Incoming message from a group
|
||||||
if ((msg.fromGroup == true) && (msg.dialog == (byte)InstantMessageDialog.SessionSend))
|
if ((msg.fromGroup == true) &&
|
||||||
|
((msg.dialog == (byte)InstantMessageDialog.SessionSend)
|
||||||
|
|| (msg.dialog == (byte)InstantMessageDialog.SessionAdd)
|
||||||
|
|| (msg.dialog == (byte)InstantMessageDialog.SessionDrop)))
|
||||||
{
|
{
|
||||||
// We have to redistribute the message across all members of the group who are here
|
ProcessMessageFromGroupSession(msg);
|
||||||
// on this sim
|
|
||||||
|
|
||||||
UUID GroupID = new UUID(msg.imSessionID);
|
|
||||||
|
|
||||||
Scene aScene = m_sceneList[0];
|
|
||||||
GridRegion regionOfOrigin = aScene.GridService.GetRegionByUUID(aScene.RegionInfo.ScopeID, regionID);
|
|
||||||
|
|
||||||
List<GroupMembersData> groupMembers = m_groupData.GetGroupMembers(UUID.Zero.ToString(), GroupID);
|
|
||||||
|
|
||||||
//if (m_debugEnabled)
|
|
||||||
// foreach (GroupMembersData m in groupMembers)
|
|
||||||
// m_log.DebugFormat("[Groups.Messaging]: member {0}", m.AgentID);
|
|
||||||
|
|
||||||
foreach (Scene s in m_sceneList)
|
|
||||||
{
|
|
||||||
s.ForEachScenePresence(sp =>
|
|
||||||
{
|
|
||||||
// If we got this via grid messaging, it's because the caller thinks
|
|
||||||
// that the root agent is here. We should only send the IM to root agents.
|
|
||||||
if (sp.IsChildAgent)
|
|
||||||
return;
|
|
||||||
|
|
||||||
GroupMembersData m = groupMembers.Find(gmd =>
|
|
||||||
{
|
|
||||||
return gmd.AgentID == sp.UUID;
|
|
||||||
});
|
|
||||||
if (m.AgentID == UUID.Zero)
|
|
||||||
{
|
|
||||||
if (m_debugEnabled)
|
|
||||||
m_log.DebugFormat("[Groups.Messaging]: skipping agent {0} because he is not a member of the group", sp.UUID);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the user has an agent in the region where
|
|
||||||
// the IM came from, and if so, skip it, because the IM
|
|
||||||
// was already sent via that agent
|
|
||||||
if (regionOfOrigin != null)
|
|
||||||
{
|
|
||||||
AgentCircuitData aCircuit = s.AuthenticateHandler.GetAgentCircuitData(sp.UUID);
|
|
||||||
if (aCircuit != null)
|
|
||||||
{
|
|
||||||
if (aCircuit.ChildrenCapSeeds.Keys.Contains(regionOfOrigin.RegionHandle))
|
|
||||||
{
|
|
||||||
if (m_debugEnabled)
|
|
||||||
m_log.DebugFormat("[Groups.Messaging]: skipping agent {0} because he has an agent in region of origin", sp.UUID);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (m_debugEnabled)
|
|
||||||
m_log.DebugFormat("[Groups.Messaging]: not skipping agent {0}", sp.UUID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
UUID AgentID = sp.UUID;
|
|
||||||
msg.toAgentID = AgentID.Guid;
|
|
||||||
|
|
||||||
if (!hasAgentDroppedGroupChatSession(AgentID.ToString(), GroupID))
|
|
||||||
{
|
|
||||||
if (!hasAgentBeenInvitedToGroupChatSession(AgentID.ToString(), GroupID))
|
|
||||||
AddAgentToSession(AgentID, GroupID, msg);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Passing to ProcessMessageFromGroupSession to deliver to {0} locally", sp.Name);
|
|
||||||
|
|
||||||
ProcessMessageFromGroupSession(msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -542,40 +359,82 @@ namespace OpenSim.Groups
|
||||||
|
|
||||||
UUID AgentID = new UUID(msg.fromAgentID);
|
UUID AgentID = new UUID(msg.fromAgentID);
|
||||||
UUID GroupID = new UUID(msg.imSessionID);
|
UUID GroupID = new UUID(msg.imSessionID);
|
||||||
UUID toAgentID = new UUID(msg.toAgentID);
|
|
||||||
|
|
||||||
switch (msg.dialog)
|
switch (msg.dialog)
|
||||||
{
|
{
|
||||||
case (byte)InstantMessageDialog.SessionAdd:
|
case (byte)InstantMessageDialog.SessionAdd:
|
||||||
AgentInvitedToGroupChatSession(AgentID.ToString(), GroupID);
|
m_groupData.AgentInvitedToGroupChatSession(AgentID.ToString(), GroupID);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case (byte)InstantMessageDialog.SessionDrop:
|
case (byte)InstantMessageDialog.SessionDrop:
|
||||||
AgentDroppedFromGroupChatSession(AgentID.ToString(), GroupID);
|
m_groupData.AgentDroppedFromGroupChatSession(AgentID.ToString(), GroupID);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case (byte)InstantMessageDialog.SessionSend:
|
case (byte)InstantMessageDialog.SessionSend:
|
||||||
// User hasn't dropped, so they're in the session,
|
if (!m_groupData.hasAgentDroppedGroupChatSession(AgentID.ToString(), GroupID)
|
||||||
// maybe we should deliver it.
|
&& !m_groupData.hasAgentBeenInvitedToGroupChatSession(AgentID.ToString(), GroupID)
|
||||||
IClientAPI client = GetActiveClient(new UUID(msg.toAgentID));
|
)
|
||||||
if (client != null)
|
|
||||||
{
|
{
|
||||||
// Deliver locally, directly
|
// Agent not in session and hasn't dropped from session
|
||||||
if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Delivering to {0} locally", client.Name);
|
// Add them to the session for now, and Invite them
|
||||||
|
m_groupData.AgentInvitedToGroupChatSession(AgentID.ToString(), GroupID);
|
||||||
|
|
||||||
if (!hasAgentDroppedGroupChatSession(toAgentID.ToString(), GroupID))
|
UUID toAgentID = new UUID(msg.toAgentID);
|
||||||
|
IClientAPI activeClient = GetActiveClient(toAgentID);
|
||||||
|
if (activeClient != null)
|
||||||
{
|
{
|
||||||
if (!hasAgentBeenInvitedToGroupChatSession(toAgentID.ToString(), GroupID))
|
GroupRecord groupInfo = m_groupData.GetGroupRecord(UUID.Zero.ToString(), GroupID, null);
|
||||||
// This actually sends the message too, so no need to resend it
|
if (groupInfo != null)
|
||||||
// with client.SendInstantMessage
|
{
|
||||||
AddAgentToSession(toAgentID, GroupID, msg);
|
if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Sending chatterbox invite instant message");
|
||||||
else
|
|
||||||
client.SendInstantMessage(msg);
|
// Force? open the group session dialog???
|
||||||
|
// and simultanously deliver the message, so we don't need to do a seperate client.SendInstantMessage(msg);
|
||||||
|
IEventQueue eq = activeClient.Scene.RequestModuleInterface<IEventQueue>();
|
||||||
|
eq.ChatterboxInvitation(
|
||||||
|
GroupID
|
||||||
|
, groupInfo.GroupName
|
||||||
|
, new UUID(msg.fromAgentID)
|
||||||
|
, msg.message
|
||||||
|
, new UUID(msg.toAgentID)
|
||||||
|
, msg.fromAgentName
|
||||||
|
, msg.dialog
|
||||||
|
, msg.timestamp
|
||||||
|
, msg.offline == 1
|
||||||
|
, (int)msg.ParentEstateID
|
||||||
|
, msg.Position
|
||||||
|
, 1
|
||||||
|
, new UUID(msg.imSessionID)
|
||||||
|
, msg.fromGroup
|
||||||
|
, OpenMetaverse.Utils.StringToBytes(groupInfo.GroupName)
|
||||||
|
);
|
||||||
|
|
||||||
|
eq.ChatterBoxSessionAgentListUpdates(
|
||||||
|
new UUID(GroupID)
|
||||||
|
, new UUID(msg.fromAgentID)
|
||||||
|
, new UUID(msg.toAgentID)
|
||||||
|
, false //canVoiceChat
|
||||||
|
, false //isModerator
|
||||||
|
, false //text mute
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else if (!m_groupData.hasAgentDroppedGroupChatSession(AgentID.ToString(), GroupID))
|
||||||
{
|
{
|
||||||
m_log.WarnFormat("[Groups.Messaging]: Received a message over the grid for a client that isn't here: {0}", msg.toAgentID);
|
// User hasn't dropped, so they're in the session,
|
||||||
|
// maybe we should deliver it.
|
||||||
|
IClientAPI client = GetActiveClient(new UUID(msg.toAgentID));
|
||||||
|
if (client != null)
|
||||||
|
{
|
||||||
|
// Deliver locally, directly
|
||||||
|
if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Delivering to {0} locally", client.Name);
|
||||||
|
client.SendInstantMessage(msg);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_log.WarnFormat("[Groups.Messaging]: Received a message over the grid for a client that isn't here: {0}", msg.toAgentID);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -585,52 +444,6 @@ namespace OpenSim.Groups
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AddAgentToSession(UUID AgentID, UUID GroupID, GridInstantMessage msg)
|
|
||||||
{
|
|
||||||
// Agent not in session and hasn't dropped from session
|
|
||||||
// Add them to the session for now, and Invite them
|
|
||||||
AgentInvitedToGroupChatSession(AgentID.ToString(), GroupID);
|
|
||||||
|
|
||||||
IClientAPI activeClient = GetActiveClient(AgentID);
|
|
||||||
if (activeClient != null)
|
|
||||||
{
|
|
||||||
GroupRecord groupInfo = m_groupData.GetGroupRecord(UUID.Zero.ToString(), GroupID, null);
|
|
||||||
if (groupInfo != null)
|
|
||||||
{
|
|
||||||
if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Sending chatterbox invite instant message");
|
|
||||||
|
|
||||||
UUID fromAgent = new UUID(msg.fromAgentID);
|
|
||||||
// Force? open the group session dialog???
|
|
||||||
// and simultanously deliver the message, so we don't need to do a seperate client.SendInstantMessage(msg);
|
|
||||||
IEventQueue eq = activeClient.Scene.RequestModuleInterface<IEventQueue>();
|
|
||||||
if (eq != null)
|
|
||||||
{
|
|
||||||
eq.ChatterboxInvitation(
|
|
||||||
GroupID
|
|
||||||
, groupInfo.GroupName
|
|
||||||
, fromAgent
|
|
||||||
, msg.message
|
|
||||||
, AgentID
|
|
||||||
, msg.fromAgentName
|
|
||||||
, msg.dialog
|
|
||||||
, msg.timestamp
|
|
||||||
, msg.offline == 1
|
|
||||||
, (int)msg.ParentEstateID
|
|
||||||
, msg.Position
|
|
||||||
, 1
|
|
||||||
, new UUID(msg.imSessionID)
|
|
||||||
, msg.fromGroup
|
|
||||||
, OpenMetaverse.Utils.StringToBytes(groupInfo.GroupName)
|
|
||||||
);
|
|
||||||
|
|
||||||
var update = new GroupChatListAgentUpdateData(AgentID);
|
|
||||||
var updates = new List<GroupChatListAgentUpdateData> { update };
|
|
||||||
eq.ChatterBoxSessionAgentListUpdates(GroupID, new UUID(msg.toAgentID), updates);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
@ -653,20 +466,22 @@ 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);
|
m_groupData.AgentInvitedToGroupChatSession(AgentID.ToString(), GroupID);
|
||||||
|
|
||||||
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,11 +491,11 @@ 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
|
||||||
AgentInvitedToGroupChatSession(AgentID.ToString(), GroupID);
|
m_groupData.AgentInvitedToGroupChatSession(AgentID.ToString(), GroupID);
|
||||||
|
|
||||||
SendMessageToGroup(im, GroupID);
|
SendMessageToGroup(im, GroupID);
|
||||||
}
|
}
|
||||||
|
@ -708,7 +523,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)
|
||||||
|
@ -747,12 +566,12 @@ namespace OpenSim.Groups
|
||||||
{
|
{
|
||||||
if (!sp.IsChildAgent)
|
if (!sp.IsChildAgent)
|
||||||
{
|
{
|
||||||
if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Found root agent for client : {0}", sp.ControllingClient.Name);
|
if (m_debugEnabled) m_log.WarnFormat("[Groups.Messaging]: Found root agent for client : {0}", sp.ControllingClient.Name);
|
||||||
return sp.ControllingClient;
|
return sp.ControllingClient;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Found child agent for client : {0}", sp.ControllingClient.Name);
|
if (m_debugEnabled) m_log.WarnFormat("[Groups.Messaging]: Found child agent for client : {0}", sp.ControllingClient.Name);
|
||||||
child = sp.ControllingClient;
|
child = sp.ControllingClient;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -771,71 +590,5 @@ namespace OpenSim.Groups
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region GroupSessionTracking
|
|
||||||
|
|
||||||
public void ResetAgentGroupChatSessions(string agentID)
|
|
||||||
{
|
|
||||||
foreach (List<string> agentList in m_groupsAgentsDroppedFromChatSession.Values)
|
|
||||||
agentList.Remove(agentID);
|
|
||||||
|
|
||||||
foreach (List<string> agentList in m_groupsAgentsInvitedToChatSession.Values)
|
|
||||||
agentList.Remove(agentID);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool hasAgentBeenInvitedToGroupChatSession(string agentID, UUID groupID)
|
|
||||||
{
|
|
||||||
// If we're tracking this group, and we can find them in the tracking, then they've been invited
|
|
||||||
return m_groupsAgentsInvitedToChatSession.ContainsKey(groupID)
|
|
||||||
&& m_groupsAgentsInvitedToChatSession[groupID].Contains(agentID);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool hasAgentDroppedGroupChatSession(string agentID, UUID groupID)
|
|
||||||
{
|
|
||||||
// If we're tracking drops for this group,
|
|
||||||
// and we find them, well... then they've dropped
|
|
||||||
return m_groupsAgentsDroppedFromChatSession.ContainsKey(groupID)
|
|
||||||
&& m_groupsAgentsDroppedFromChatSession[groupID].Contains(agentID);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void AgentDroppedFromGroupChatSession(string agentID, UUID groupID)
|
|
||||||
{
|
|
||||||
if (m_groupsAgentsDroppedFromChatSession.ContainsKey(groupID))
|
|
||||||
{
|
|
||||||
// If not in dropped list, add
|
|
||||||
if (!m_groupsAgentsDroppedFromChatSession[groupID].Contains(agentID))
|
|
||||||
{
|
|
||||||
m_groupsAgentsDroppedFromChatSession[groupID].Add(agentID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void AgentInvitedToGroupChatSession(string agentID, UUID groupID)
|
|
||||||
{
|
|
||||||
// Add Session Status if it doesn't exist for this session
|
|
||||||
CreateGroupChatSessionTracking(groupID);
|
|
||||||
|
|
||||||
// If nessesary, remove from dropped list
|
|
||||||
if (m_groupsAgentsDroppedFromChatSession[groupID].Contains(agentID))
|
|
||||||
{
|
|
||||||
m_groupsAgentsDroppedFromChatSession[groupID].Remove(agentID);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add to invited
|
|
||||||
if (!m_groupsAgentsInvitedToChatSession[groupID].Contains(agentID))
|
|
||||||
m_groupsAgentsInvitedToChatSession[groupID].Add(agentID);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CreateGroupChatSessionTracking(UUID groupID)
|
|
||||||
{
|
|
||||||
if (!m_groupsAgentsDroppedFromChatSession.ContainsKey(groupID))
|
|
||||||
{
|
|
||||||
m_groupsAgentsDroppedFromChatSession.Add(groupID, new List<string>());
|
|
||||||
m_groupsAgentsInvitedToChatSession.Add(groupID, new List<string>());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -101,7 +101,7 @@ namespace OpenSim.Groups
|
||||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
||||||
if (GroupID != UUID.Zero)
|
if (GroupID != UUID.Zero)
|
||||||
sendData["GroupID"] = GroupID.ToString();
|
sendData["GroupID"] = GroupID.ToString();
|
||||||
if (!string.IsNullOrEmpty(GroupName))
|
if (GroupName != null && GroupName != string.Empty)
|
||||||
sendData["Name"] = GroupsDataUtils.Sanitize(GroupName);
|
sendData["Name"] = GroupsDataUtils.Sanitize(GroupName);
|
||||||
|
|
||||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
sendData["RequestingAgentID"] = RequestingAgentID;
|
||||||
|
@ -275,7 +275,7 @@ namespace OpenSim.Groups
|
||||||
|
|
||||||
//m_log.DebugFormat("[XXX]: reply was {0}", reply);
|
//m_log.DebugFormat("[XXX]: reply was {0}", reply);
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(reply))
|
if (reply == string.Empty || reply == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(
|
Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(
|
||||||
|
|
|
@ -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.
|
||||||
*
|
*
|
||||||
|
@ -32,7 +32,6 @@ using System.Reflection;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
using OpenSim.Framework.Monitoring;
|
|
||||||
using OpenSim.Framework.Servers;
|
using OpenSim.Framework.Servers;
|
||||||
using OpenSim.Region.Framework.Scenes;
|
using OpenSim.Region.Framework.Scenes;
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
using OpenSim.Region.Framework.Interfaces;
|
||||||
|
@ -103,7 +102,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 +134,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 +169,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 +183,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 +197,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,19 +245,16 @@ 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)
|
||||||
{
|
{
|
||||||
string url = string.Empty, gname = string.Empty;
|
string url = string.Empty, gname = string.Empty;
|
||||||
if (IsLocal(GroupID, out url, out gname))
|
if (IsLocal(GroupID, out url, out gname))
|
||||||
{
|
return m_LocalGroupsConnector.GetGroupMembers(AgentUUI(RequestingAgentID), GroupID);
|
||||||
string agentID = AgentUUI(RequestingAgentID);
|
|
||||||
return m_LocalGroupsConnector.GetGroupMembers(agentID, GroupID);
|
|
||||||
}
|
|
||||||
else if (!string.IsNullOrEmpty(url))
|
else if (!string.IsNullOrEmpty(url))
|
||||||
{
|
{
|
||||||
ExtendedGroupMembershipData membership = m_LocalGroupsConnector.GetAgentGroupMembership(RequestingAgentID, RequestingAgentID, GroupID);
|
ExtendedGroupMembershipData membership = m_LocalGroupsConnector.GetAgentGroupMembership(RequestingAgentID, RequestingAgentID, GroupID);
|
||||||
|
@ -374,7 +370,7 @@ namespace OpenSim.Groups
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new List<GroupRoleMembersData>();
|
return new List<GroupRoleMembersData>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -400,21 +396,17 @@ namespace OpenSim.Groups
|
||||||
|
|
||||||
if (success)
|
if (success)
|
||||||
{
|
{
|
||||||
// Here we always return true. The user has been added to the local group,
|
|
||||||
// independent of whether the remote operation succeeds or not
|
|
||||||
url = m_UserManagement.GetUserServerURL(uid, "GroupsServerURI");
|
url = m_UserManagement.GetUserServerURL(uid, "GroupsServerURI");
|
||||||
if (url == string.Empty)
|
if (url == string.Empty)
|
||||||
{
|
{
|
||||||
reason = "You don't have an accessible groups server in your home world. You membership to this group in only within this grid.";
|
reason = "User doesn't have a groups server";
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
GroupsServiceHGConnector c = GetConnector(url);
|
GroupsServiceHGConnector c = GetConnector(url);
|
||||||
if (c != null)
|
if (c != null)
|
||||||
c.CreateProxy(AgentUUI(RequestingAgentID), AgentID, token, GroupID, m_LocalGroupsServiceLocation, name, out reason);
|
return c.CreateProxy(AgentUUI(RequestingAgentID), AgentID, token, GroupID, m_LocalGroupsServiceLocation, name, out reason);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (m_UserManagement.IsLocalGridUser(uid)) // local user
|
else if (m_UserManagement.IsLocalGridUser(uid)) // local user
|
||||||
|
@ -561,7 +553,7 @@ namespace OpenSim.Groups
|
||||||
|
|
||||||
// so we have the list of urls to send the notice to
|
// so we have the list of urls to send the notice to
|
||||||
// this may take a long time...
|
// this may take a long time...
|
||||||
WorkManager.RunInThread(delegate
|
Util.FireAndForget(delegate
|
||||||
{
|
{
|
||||||
foreach (string u in urls)
|
foreach (string u in urls)
|
||||||
{
|
{
|
||||||
|
@ -572,7 +564,7 @@ namespace OpenSim.Groups
|
||||||
hasAttachment, attType, attName, attItemID, AgentUUIForOutside(attOwnerID));
|
hasAttachment, attType, attName, attItemID, AgentUUIForOutside(attOwnerID));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, null, string.Format("AddGroupNotice (agent {0}, group {1})", RequestingAgentID, groupID));
|
});
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -598,6 +590,28 @@ namespace OpenSim.Groups
|
||||||
return m_LocalGroupsConnector.GetGroupNotices(AgentUUI(RequestingAgentID), GroupID);
|
return m_LocalGroupsConnector.GetGroupNotices(AgentUUI(RequestingAgentID), GroupID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ResetAgentGroupChatSessions(string agentID)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool hasAgentBeenInvitedToGroupChatSession(string agentID, UUID groupID)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool hasAgentDroppedGroupChatSession(string agentID, UUID groupID)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AgentDroppedFromGroupChatSession(string agentID, UUID groupID)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AgentInvitedToGroupChatSession(string agentID, UUID groupID)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region hypergrid groups
|
#region hypergrid groups
|
||||||
|
@ -605,8 +619,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();
|
||||||
|
@ -618,20 +638,23 @@ namespace OpenSim.Groups
|
||||||
if (agent != null)
|
if (agent != null)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (agent != null)
|
if (agent == null) // oops
|
||||||
return Util.ProduceUserUniversalIdentifier(agent);
|
return AgentID.ToString();
|
||||||
|
|
||||||
// we don't know anything about this foreign user
|
|
||||||
// try asking the user management module, which may know more
|
|
||||||
return m_UserManagement.GetUserUUI(AgentID);
|
|
||||||
|
|
||||||
|
return Util.ProduceUserUniversalIdentifier(agent);
|
||||||
}
|
}
|
||||||
|
|
||||||
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 +675,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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.
|
||||||
*
|
*
|
||||||
|
@ -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);
|
||||||
|
@ -159,7 +158,7 @@ namespace OpenSim.Groups
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
m_log.Error(string.Format("[Groups.RobustHGConnector]: Exception {0} ", e.Message), e);
|
m_log.DebugFormat("[Groups.RobustHGConnector]: Exception {0}", e.StackTrace);
|
||||||
}
|
}
|
||||||
|
|
||||||
return FailureResult();
|
return FailureResult();
|
||||||
|
@ -210,13 +209,11 @@ namespace OpenSim.Groups
|
||||||
string agentID = request["AgentID"].ToString();
|
string agentID = request["AgentID"].ToString();
|
||||||
string token = request["AccessToken"].ToString();
|
string token = request["AccessToken"].ToString();
|
||||||
|
|
||||||
if (!m_GroupsService.RemoveAgentFromGroup(agentID, agentID, groupID, token))
|
m_GroupsService.RemoveAgentFromGroup(agentID, agentID, groupID, token);
|
||||||
NullResult(result, "Internal error");
|
|
||||||
else
|
|
||||||
result["RESULT"] = "true";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
|
//m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
|
||||||
|
result["RESULT"] = "true";
|
||||||
return Util.UTF8NoBomEncoding.GetBytes(ServerUtils.BuildXmlResponse(result));
|
return Util.UTF8NoBomEncoding.GetBytes(ServerUtils.BuildXmlResponse(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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,11 +87,17 @@ 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);
|
||||||
|
|
||||||
|
void ResetAgentGroupChatSessions(string agentID);
|
||||||
|
bool hasAgentBeenInvitedToGroupChatSession(string agentID, UUID groupID);
|
||||||
|
bool hasAgentDroppedGroupChatSession(string agentID, UUID groupID);
|
||||||
|
void AgentDroppedFromGroupChatSession(string agentID, UUID groupID);
|
||||||
|
void AgentInvitedToGroupChatSession(string agentID, UUID groupID);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class GroupInviteInfo
|
public class GroupInviteInfo
|
||||||
|
|
|
@ -34,7 +34,6 @@ using System.Text;
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
using OpenSim.Region.Framework.Scenes;
|
using OpenSim.Region.Framework.Scenes;
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
using OpenSim.Region.Framework.Interfaces;
|
||||||
using OpenSim.Services.Interfaces;
|
|
||||||
|
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
using Mono.Addins;
|
using Mono.Addins;
|
||||||
|
@ -108,7 +107,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 +145,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 +172,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 +295,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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -321,6 +320,28 @@ namespace OpenSim.Groups
|
||||||
return m_GroupsService.GetGroupNotices(RequestingAgentID, GroupID);
|
return m_GroupsService.GetGroupNotices(RequestingAgentID, GroupID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ResetAgentGroupChatSessions(string agentID)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool hasAgentBeenInvitedToGroupChatSession(string agentID, UUID groupID)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool hasAgentDroppedGroupChatSession(string agentID, UUID groupID)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AgentDroppedFromGroupChatSession(string agentID, UUID groupID)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AgentInvitedToGroupChatSession(string agentID, UUID groupID)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.7.6.*")]
|
||||||
|
|
||||||
[assembly: Addin("OpenSim.Groups", OpenSim.VersionInfo.VersionNumber)]
|
[assembly: Addin("OpenSim.Groups", "0.1")]
|
||||||
[assembly: AddinDependency("OpenSim.Region.Framework", OpenSim.VersionInfo.VersionNumber)]
|
[assembly: AddinDependency("OpenSim", "0.5")]
|
||||||
|
|
|
@ -32,12 +32,10 @@ using System.Reflection;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
using OpenSim.Framework.ServiceAuth;
|
|
||||||
using OpenSim.Server.Base;
|
using OpenSim.Server.Base;
|
||||||
|
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
using log4net;
|
using log4net;
|
||||||
using Nini.Config;
|
|
||||||
|
|
||||||
namespace OpenSim.Groups
|
namespace OpenSim.Groups
|
||||||
{
|
{
|
||||||
|
@ -46,33 +44,15 @@ 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);
|
||||||
|
|
||||||
private string m_ServerURI;
|
private string m_ServerURI;
|
||||||
private IServiceAuth m_Auth;
|
|
||||||
private object m_Lock = new object();
|
private object m_Lock = new object();
|
||||||
|
|
||||||
public GroupsServiceRemoteConnector(IConfigSource config)
|
public GroupsServiceRemoteConnector(string url)
|
||||||
{
|
{
|
||||||
IConfig groupsConfig = config.Configs["Groups"];
|
|
||||||
string url = groupsConfig.GetString("GroupsServerURI", string.Empty);
|
|
||||||
if (!Uri.IsWellFormedUriString(url, UriKind.Absolute))
|
|
||||||
throw new Exception(string.Format("[Groups.RemoteConnector]: Malformed groups server URL {0}. Fix it or disable the Groups feature.", url));
|
|
||||||
|
|
||||||
m_ServerURI = url;
|
m_ServerURI = url;
|
||||||
if (!m_ServerURI.EndsWith("/"))
|
if (!m_ServerURI.EndsWith("/"))
|
||||||
m_ServerURI += "/";
|
m_ServerURI += "/";
|
||||||
|
|
||||||
/// This is from BaseServiceConnector
|
m_log.DebugFormat("[Groups.RemoteConnector]: Groups server at {0}", m_ServerURI);
|
||||||
string authType = Util.GetConfigVarFromSections<string>(config, "AuthType", new string[] { "Network", "Groups" }, "None");
|
|
||||||
|
|
||||||
switch (authType)
|
|
||||||
{
|
|
||||||
case "BasicHttpAuthentication":
|
|
||||||
m_Auth = new BasicHttpAuthentication(config, "Groups");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
///
|
|
||||||
|
|
||||||
m_log.DebugFormat("[Groups.RemoteConnector]: Groups server at {0}, authentication {1}",
|
|
||||||
m_ServerURI, (m_Auth == null ? "None" : m_Auth.GetType().ToString()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ExtendedGroupRecord CreateGroup(string RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment,
|
public ExtendedGroupRecord CreateGroup(string RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment,
|
||||||
|
@ -126,7 +106,7 @@ namespace OpenSim.Groups
|
||||||
sendData["OP"] = "UPDATE";
|
sendData["OP"] = "UPDATE";
|
||||||
Dictionary<string, object> ret = MakeRequest("PUTGROUP", sendData);
|
Dictionary<string, object> ret = MakeRequest("PUTGROUP", sendData);
|
||||||
|
|
||||||
if (ret == null || (ret != null && (!ret.ContainsKey("RESULT") || ret["RESULT"].ToString() == "NULL")))
|
if (ret == null || (ret != null && ret["RESULT"].ToString() == "NULL"))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
return GroupsDataUtils.GroupRecord((Dictionary<string, object>)ret["RESULT"]);
|
return GroupsDataUtils.GroupRecord((Dictionary<string, object>)ret["RESULT"]);
|
||||||
|
@ -140,49 +120,19 @@ namespace OpenSim.Groups
|
||||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
||||||
if (GroupID != UUID.Zero)
|
if (GroupID != UUID.Zero)
|
||||||
sendData["GroupID"] = GroupID.ToString();
|
sendData["GroupID"] = GroupID.ToString();
|
||||||
if (!string.IsNullOrEmpty(GroupName))
|
if (GroupName != null && GroupName != string.Empty)
|
||||||
sendData["Name"] = GroupsDataUtils.Sanitize(GroupName);
|
sendData["Name"] = GroupsDataUtils.Sanitize(GroupName);
|
||||||
|
|
||||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
sendData["RequestingAgentID"] = RequestingAgentID;
|
||||||
|
|
||||||
Dictionary<string, object> ret = MakeRequest("GETGROUP", sendData);
|
Dictionary<string, object> ret = MakeRequest("GETGROUP", sendData);
|
||||||
|
|
||||||
if (ret == null || (ret != null && (!ret.ContainsKey("RESULT") || ret["RESULT"].ToString() == "NULL")))
|
if (ret == null || (ret != null && ret["RESULT"].ToString() == "NULL"))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
return GroupsDataUtils.GroupRecord((Dictionary<string, object>)ret["RESULT"]);
|
return GroupsDataUtils.GroupRecord((Dictionary<string, object>)ret["RESULT"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<DirGroupsReplyData> FindGroups(string RequestingAgentIDstr, string query)
|
|
||||||
{
|
|
||||||
List<DirGroupsReplyData> hits = new List<DirGroupsReplyData>();
|
|
||||||
if (string.IsNullOrEmpty(query))
|
|
||||||
return hits;
|
|
||||||
|
|
||||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
|
||||||
sendData["Query"] = query;
|
|
||||||
sendData["RequestingAgentID"] = RequestingAgentIDstr;
|
|
||||||
|
|
||||||
Dictionary<string, object> ret = MakeRequest("FINDGROUPS", sendData);
|
|
||||||
|
|
||||||
if (ret == null)
|
|
||||||
return hits;
|
|
||||||
|
|
||||||
if (!ret.ContainsKey("RESULT"))
|
|
||||||
return hits;
|
|
||||||
|
|
||||||
if (ret["RESULT"].ToString() == "NULL")
|
|
||||||
return hits;
|
|
||||||
|
|
||||||
foreach (object v in ((Dictionary<string, object>)ret["RESULT"]).Values)
|
|
||||||
{
|
|
||||||
DirGroupsReplyData m = GroupsDataUtils.DirGroupsReplyData((Dictionary<string, object>)v);
|
|
||||||
hits.Add(m);
|
|
||||||
}
|
|
||||||
|
|
||||||
return hits;
|
|
||||||
}
|
|
||||||
|
|
||||||
public GroupMembershipData AddAgentToGroup(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID, string token, out string reason)
|
public GroupMembershipData AddAgentToGroup(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID, string token, out string reason)
|
||||||
{
|
{
|
||||||
reason = string.Empty;
|
reason = string.Empty;
|
||||||
|
@ -276,7 +226,6 @@ namespace OpenSim.Groups
|
||||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
||||||
sendData["GroupID"] = GroupID.ToString();
|
sendData["GroupID"] = GroupID.ToString();
|
||||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
sendData["RequestingAgentID"] = RequestingAgentID;
|
||||||
|
|
||||||
Dictionary<string, object> ret = MakeRequest("GETGROUPMEMBERS", sendData);
|
Dictionary<string, object> ret = MakeRequest("GETGROUPMEMBERS", sendData);
|
||||||
|
|
||||||
if (ret == null)
|
if (ret == null)
|
||||||
|
@ -287,7 +236,6 @@ namespace OpenSim.Groups
|
||||||
|
|
||||||
if (ret["RESULT"].ToString() == "NULL")
|
if (ret["RESULT"].ToString() == "NULL")
|
||||||
return members;
|
return members;
|
||||||
|
|
||||||
foreach (object v in ((Dictionary<string, object>)ret["RESULT"]).Values)
|
foreach (object v in ((Dictionary<string, object>)ret["RESULT"]).Values)
|
||||||
{
|
{
|
||||||
ExtendedGroupMembersData m = GroupsDataUtils.GroupMembersData((Dictionary<string, object>)v);
|
ExtendedGroupMembersData m = GroupsDataUtils.GroupMembersData((Dictionary<string, object>)v);
|
||||||
|
@ -378,7 +326,6 @@ namespace OpenSim.Groups
|
||||||
|
|
||||||
if (ret["RESULT"].ToString() == "NULL")
|
if (ret["RESULT"].ToString() == "NULL")
|
||||||
return roles;
|
return roles;
|
||||||
|
|
||||||
foreach (object v in ((Dictionary<string, object>)ret["RESULT"]).Values)
|
foreach (object v in ((Dictionary<string, object>)ret["RESULT"]).Values)
|
||||||
{
|
{
|
||||||
GroupRolesData m = GroupsDataUtils.GroupRolesData((Dictionary<string, object>)v);
|
GroupRolesData m = GroupsDataUtils.GroupRolesData((Dictionary<string, object>)v);
|
||||||
|
@ -679,8 +626,7 @@ namespace OpenSim.Groups
|
||||||
lock (m_Lock)
|
lock (m_Lock)
|
||||||
reply = SynchronousRestFormsRequester.MakeRequest("POST",
|
reply = SynchronousRestFormsRequester.MakeRequest("POST",
|
||||||
m_ServerURI + "groups",
|
m_ServerURI + "groups",
|
||||||
ServerUtils.BuildQueryString(sendData),
|
ServerUtils.BuildQueryString(sendData));
|
||||||
m_Auth);
|
|
||||||
|
|
||||||
if (reply == string.Empty)
|
if (reply == string.Empty)
|
||||||
return null;
|
return null;
|
||||||
|
@ -690,7 +636,7 @@ namespace OpenSim.Groups
|
||||||
|
|
||||||
return replyData;
|
return replyData;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,6 @@ using OpenSim.Framework;
|
||||||
using OpenSim.Region.Framework.Scenes;
|
using OpenSim.Region.Framework.Scenes;
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
using OpenSim.Region.Framework.Interfaces;
|
||||||
using OpenSim.Server.Base;
|
using OpenSim.Server.Base;
|
||||||
using OpenSim.Services.Interfaces;
|
|
||||||
|
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
using Mono.Addins;
|
using Mono.Addins;
|
||||||
|
@ -73,7 +72,12 @@ namespace OpenSim.Groups
|
||||||
|
|
||||||
private void Init(IConfigSource config)
|
private void Init(IConfigSource config)
|
||||||
{
|
{
|
||||||
m_GroupsService = new GroupsServiceRemoteConnector(config);
|
IConfig groupsConfig = config.Configs["Groups"];
|
||||||
|
string url = groupsConfig.GetString("GroupsServerURI", string.Empty);
|
||||||
|
if (!Uri.IsWellFormedUriString(url, UriKind.Absolute))
|
||||||
|
throw new Exception(string.Format("[Groups.RemoteConnector]: Malformed groups server URL {0}. Fix it or disable the Groups feature.", url));
|
||||||
|
|
||||||
|
m_GroupsService = new GroupsServiceRemoteConnector(url);
|
||||||
m_Scenes = new List<Scene>();
|
m_Scenes = new List<Scene>();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -113,7 +117,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 +155,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 +171,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 +190,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 new List<DirGroupsReplyData>();
|
||||||
}
|
}
|
||||||
|
|
||||||
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 +366,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();
|
||||||
|
@ -402,6 +406,28 @@ namespace OpenSim.Groups
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ResetAgentGroupChatSessions(string agentID)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool hasAgentBeenInvitedToGroupChatSession(string agentID, UUID groupID)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool hasAgentDroppedGroupChatSession(string agentID, UUID groupID)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AgentDroppedFromGroupChatSession(string agentID, UUID groupID)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AgentInvitedToGroupChatSession(string agentID, UUID groupID)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,6 @@ using OpenSim.Framework;
|
||||||
using OpenSim.Server.Base;
|
using OpenSim.Server.Base;
|
||||||
using OpenSim.Services.Interfaces;
|
using OpenSim.Services.Interfaces;
|
||||||
using OpenSim.Framework.Servers.HttpServer;
|
using OpenSim.Framework.Servers.HttpServer;
|
||||||
using OpenSim.Framework.ServiceAuth;
|
|
||||||
using OpenSim.Server.Handlers.Base;
|
using OpenSim.Server.Handlers.Base;
|
||||||
using log4net;
|
using log4net;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
|
@ -53,26 +52,14 @@ namespace OpenSim.Groups
|
||||||
public GroupsServiceRobustConnector(IConfigSource config, IHttpServer server, string configName) :
|
public GroupsServiceRobustConnector(IConfigSource config, IHttpServer server, string configName) :
|
||||||
base(config, server, configName)
|
base(config, server, configName)
|
||||||
{
|
{
|
||||||
string key = string.Empty;
|
|
||||||
if (configName != String.Empty)
|
if (configName != String.Empty)
|
||||||
m_ConfigName = configName;
|
m_ConfigName = configName;
|
||||||
|
|
||||||
m_log.DebugFormat("[Groups.RobustConnector]: Starting with config name {0}", m_ConfigName);
|
m_log.DebugFormat("[Groups.RobustConnector]: Starting with config name {0}", m_ConfigName);
|
||||||
|
|
||||||
IConfig groupsConfig = config.Configs[m_ConfigName];
|
|
||||||
if (groupsConfig != null)
|
|
||||||
{
|
|
||||||
key = groupsConfig.GetString("SecretKey", string.Empty);
|
|
||||||
m_log.DebugFormat("[Groups.RobustConnector]: Starting with secret key {0}", key);
|
|
||||||
}
|
|
||||||
// else
|
|
||||||
// m_log.DebugFormat("[Groups.RobustConnector]: Unable to find {0} section in configuration", m_ConfigName);
|
|
||||||
|
|
||||||
m_GroupsService = new GroupsService(config);
|
m_GroupsService = new GroupsService(config);
|
||||||
|
|
||||||
IServiceAuth auth = ServiceAuth.Create(config, m_ConfigName);
|
server.AddStreamHandler(new GroupsServicePostHandler(m_GroupsService));
|
||||||
|
|
||||||
server.AddStreamHandler(new GroupsServicePostHandler(m_GroupsService, auth));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,8 +69,8 @@ namespace OpenSim.Groups
|
||||||
|
|
||||||
private GroupsService m_GroupsService;
|
private GroupsService m_GroupsService;
|
||||||
|
|
||||||
public GroupsServicePostHandler(GroupsService service, IServiceAuth auth) :
|
public GroupsServicePostHandler(GroupsService service) :
|
||||||
base("POST", "/groups", auth)
|
base("POST", "/groups")
|
||||||
{
|
{
|
||||||
m_GroupsService = service;
|
m_GroupsService = service;
|
||||||
}
|
}
|
||||||
|
@ -91,10 +78,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);
|
||||||
|
@ -110,7 +96,7 @@ namespace OpenSim.Groups
|
||||||
string method = request["METHOD"].ToString();
|
string method = request["METHOD"].ToString();
|
||||||
request.Remove("METHOD");
|
request.Remove("METHOD");
|
||||||
|
|
||||||
// m_log.DebugFormat("[Groups.Handler]: {0}", method);
|
m_log.DebugFormat("[Groups.Handler]: {0}", method);
|
||||||
switch (method)
|
switch (method)
|
||||||
{
|
{
|
||||||
case "PUTGROUP":
|
case "PUTGROUP":
|
||||||
|
@ -147,14 +133,12 @@ namespace OpenSim.Groups
|
||||||
return HandleAddNotice(request);
|
return HandleAddNotice(request);
|
||||||
case "GETNOTICES":
|
case "GETNOTICES":
|
||||||
return HandleGetNotices(request);
|
return HandleGetNotices(request);
|
||||||
case "FINDGROUPS":
|
|
||||||
return HandleFindGroups(request);
|
|
||||||
}
|
}
|
||||||
m_log.DebugFormat("[GROUPS HANDLER]: unknown method request: {0}", method);
|
m_log.DebugFormat("[GROUPS HANDLER]: unknown method request: {0}", method);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
m_log.Error(string.Format("[GROUPS HANDLER]: Exception {0} ", e.Message), e);
|
m_log.DebugFormat("[GROUPS HANDLER]: Exception {0}", e.StackTrace);
|
||||||
}
|
}
|
||||||
|
|
||||||
return FailureResult();
|
return FailureResult();
|
||||||
|
@ -286,13 +270,11 @@ namespace OpenSim.Groups
|
||||||
string agentID = request["AgentID"].ToString();
|
string agentID = request["AgentID"].ToString();
|
||||||
string requestingAgentID = request["RequestingAgentID"].ToString();
|
string requestingAgentID = request["RequestingAgentID"].ToString();
|
||||||
|
|
||||||
if (!m_GroupsService.RemoveAgentFromGroup(requestingAgentID, agentID, groupID))
|
m_GroupsService.RemoveAgentFromGroup(requestingAgentID, agentID, groupID);
|
||||||
NullResult(result, string.Format("Insufficient permissions. {0}", agentID));
|
|
||||||
else
|
|
||||||
result["RESULT"] = "true";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
|
//m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
|
||||||
|
result["RESULT"] = "true";
|
||||||
return Util.UTF8NoBomEncoding.GetBytes(ServerUtils.BuildXmlResponse(result));
|
return Util.UTF8NoBomEncoding.GetBytes(ServerUtils.BuildXmlResponse(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -394,7 +376,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 +502,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 +630,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,14 +647,10 @@ 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)
|
result["RESULT"] = GroupsDataUtils.GroupInviteInfo(invite);
|
||||||
result["RESULT"] = GroupsDataUtils.GroupInviteInfo(invite);
|
|
||||||
else
|
|
||||||
result["RESULT"] = "NULL";
|
|
||||||
|
|
||||||
return Util.UTF8NoBomEncoding.GetBytes(ServerUtils.BuildXmlResponse(result));
|
return Util.UTF8NoBomEncoding.GetBytes(ServerUtils.BuildXmlResponse(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -762,32 +740,6 @@ namespace OpenSim.Groups
|
||||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] HandleFindGroups(Dictionary<string, object> request)
|
|
||||||
{
|
|
||||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
|
||||||
|
|
||||||
if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("Query"))
|
|
||||||
NullResult(result, "Bad network data");
|
|
||||||
|
|
||||||
List<DirGroupsReplyData> hits = m_GroupsService.FindGroups(request["RequestingAgentID"].ToString(), request["Query"].ToString());
|
|
||||||
|
|
||||||
if (hits == null || (hits != null && hits.Count == 0))
|
|
||||||
NullResult(result, "No hits");
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Dictionary<string, object> dict = new Dictionary<string, object>();
|
|
||||||
int i = 0;
|
|
||||||
foreach (DirGroupsReplyData n in hits)
|
|
||||||
dict["n-" + i++] = GroupsDataUtils.DirGroupsReplyData(n);
|
|
||||||
|
|
||||||
result["RESULT"] = dict;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
string xmlString = ServerUtils.BuildXmlResponse(result);
|
|
||||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#region Helpers
|
#region Helpers
|
||||||
|
|
||||||
|
@ -804,14 +756,6 @@ namespace OpenSim.Groups
|
||||||
string xmlString = ServerUtils.BuildXmlResponse(result);
|
string xmlString = ServerUtils.BuildXmlResponse(result);
|
||||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte[] FailureResult(string reason)
|
|
||||||
{
|
|
||||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
|
||||||
NullResult(result, reason);
|
|
||||||
string xmlString = ServerUtils.BuildXmlResponse(result);
|
|
||||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
|
||||||
}
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,8 +31,7 @@ using System.Reflection;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
//using OpenSim.Region.Framework.Interfaces;
|
using OpenSim.Region.Framework.Interfaces;
|
||||||
using OpenSim.Services.Interfaces;
|
|
||||||
|
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
|
|
||||||
|
@ -145,20 +144,14 @@ namespace OpenSim.Groups
|
||||||
|
|
||||||
if (firstCall)
|
if (firstCall)
|
||||||
{
|
{
|
||||||
try
|
//group = m_GroupsService.GetGroupRecord(RequestingAgentID, GroupID, GroupName);
|
||||||
{
|
group = d();
|
||||||
//group = m_GroupsService.GetGroupRecord(RequestingAgentID, GroupID, GroupName);
|
|
||||||
group = d();
|
|
||||||
|
|
||||||
lock (m_Cache)
|
lock (m_Cache)
|
||||||
{
|
|
||||||
m_Cache.AddOrUpdate(cacheKey, group, GROUPS_CACHE_TIMEOUT);
|
|
||||||
return (ExtendedGroupRecord)group;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
{
|
||||||
|
m_Cache.AddOrUpdate(cacheKey, group, GROUPS_CACHE_TIMEOUT);
|
||||||
m_ActiveRequests.Remove(cacheKey);
|
m_ActiveRequests.Remove(cacheKey);
|
||||||
|
return (ExtendedGroupRecord)group;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -250,19 +243,13 @@ namespace OpenSim.Groups
|
||||||
|
|
||||||
if (firstCall)
|
if (firstCall)
|
||||||
{
|
{
|
||||||
try
|
membership = d();
|
||||||
{
|
|
||||||
membership = d();
|
|
||||||
|
|
||||||
lock (m_Cache)
|
lock (m_Cache)
|
||||||
{
|
|
||||||
m_Cache.AddOrUpdate(cacheKey, membership, GROUPS_CACHE_TIMEOUT);
|
|
||||||
return (ExtendedGroupMembershipData)membership;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
{
|
||||||
|
m_Cache.AddOrUpdate(cacheKey, membership, GROUPS_CACHE_TIMEOUT);
|
||||||
m_ActiveRequests.Remove(cacheKey);
|
m_ActiveRequests.Remove(cacheKey);
|
||||||
|
return (ExtendedGroupMembershipData)membership;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -299,18 +286,12 @@ namespace OpenSim.Groups
|
||||||
|
|
||||||
if (firstCall)
|
if (firstCall)
|
||||||
{
|
{
|
||||||
try
|
membership = d();
|
||||||
{
|
lock (m_Cache)
|
||||||
membership = d();
|
|
||||||
lock (m_Cache)
|
|
||||||
{
|
|
||||||
m_Cache.AddOrUpdate(cacheKey, membership, GROUPS_CACHE_TIMEOUT);
|
|
||||||
return (ExtendedGroupMembershipData)membership;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
{
|
||||||
|
m_Cache.AddOrUpdate(cacheKey, membership, GROUPS_CACHE_TIMEOUT);
|
||||||
m_ActiveRequests.Remove(cacheKey);
|
m_ActiveRequests.Remove(cacheKey);
|
||||||
|
return (ExtendedGroupMembershipData)membership;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -346,18 +327,12 @@ namespace OpenSim.Groups
|
||||||
|
|
||||||
if (firstCall)
|
if (firstCall)
|
||||||
{
|
{
|
||||||
try
|
memberships = d();
|
||||||
{
|
lock (m_Cache)
|
||||||
memberships = d();
|
|
||||||
lock (m_Cache)
|
|
||||||
{
|
|
||||||
m_Cache.AddOrUpdate(cacheKey, memberships, GROUPS_CACHE_TIMEOUT);
|
|
||||||
return (List<GroupMembershipData>)memberships;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
{
|
||||||
|
m_Cache.AddOrUpdate(cacheKey, memberships, GROUPS_CACHE_TIMEOUT);
|
||||||
m_ActiveRequests.Remove(cacheKey);
|
m_ActiveRequests.Remove(cacheKey);
|
||||||
|
return (List<GroupMembershipData>)memberships;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -394,26 +369,20 @@ namespace OpenSim.Groups
|
||||||
|
|
||||||
if (firstCall)
|
if (firstCall)
|
||||||
{
|
{
|
||||||
try
|
List<ExtendedGroupMembersData> _members = d();
|
||||||
{
|
|
||||||
List<ExtendedGroupMembersData> _members = d();
|
if (_members != null && _members.Count > 0)
|
||||||
|
members = _members.ConvertAll<GroupMembersData>(new Converter<ExtendedGroupMembersData, GroupMembersData>(m_ForeignImporter.ConvertGroupMembersData));
|
||||||
if (_members != null && _members.Count > 0)
|
else
|
||||||
members = _members.ConvertAll<GroupMembersData>(new Converter<ExtendedGroupMembersData, GroupMembersData>(m_ForeignImporter.ConvertGroupMembersData));
|
members = new List<GroupMembersData>();
|
||||||
else
|
|
||||||
members = new List<GroupMembersData>();
|
lock (m_Cache)
|
||||||
|
|
||||||
lock (m_Cache)
|
|
||||||
{
|
|
||||||
//m_Cache.AddOrUpdate(cacheKey, members, GROUPS_CACHE_TIMEOUT);
|
|
||||||
m_Cache.AddOrUpdate(cacheKey, _members, GROUPS_CACHE_TIMEOUT);
|
|
||||||
|
|
||||||
return (List<GroupMembersData>)members;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
{
|
||||||
|
//m_Cache.AddOrUpdate(cacheKey, members, GROUPS_CACHE_TIMEOUT);
|
||||||
|
m_Cache.AddOrUpdate(cacheKey, _members, GROUPS_CACHE_TIMEOUT);
|
||||||
m_ActiveRequests.Remove(cacheKey);
|
m_ActiveRequests.Remove(cacheKey);
|
||||||
|
|
||||||
|
return (List<GroupMembersData>)members;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -528,22 +497,16 @@ namespace OpenSim.Groups
|
||||||
|
|
||||||
if (firstCall)
|
if (firstCall)
|
||||||
{
|
{
|
||||||
try
|
roles = d();
|
||||||
|
if (roles != null)
|
||||||
{
|
{
|
||||||
roles = d();
|
lock (m_Cache)
|
||||||
if (roles != null)
|
|
||||||
{
|
{
|
||||||
lock (m_Cache)
|
m_Cache.AddOrUpdate(cacheKey, roles, GROUPS_CACHE_TIMEOUT);
|
||||||
{
|
m_ActiveRequests.Remove(cacheKey);
|
||||||
m_Cache.AddOrUpdate(cacheKey, roles, GROUPS_CACHE_TIMEOUT);
|
return (List<GroupRolesData>)roles;
|
||||||
return (List<GroupRolesData>)roles;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally
|
|
||||||
{
|
|
||||||
m_ActiveRequests.Remove(cacheKey);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Thread.Sleep(50);
|
Thread.Sleep(50);
|
||||||
|
@ -578,29 +541,23 @@ namespace OpenSim.Groups
|
||||||
|
|
||||||
if (firstCall)
|
if (firstCall)
|
||||||
{
|
{
|
||||||
try
|
List<ExtendedGroupRoleMembersData> _rmembers = d();
|
||||||
{
|
|
||||||
List<ExtendedGroupRoleMembersData> _rmembers = d();
|
|
||||||
|
|
||||||
if (_rmembers != null && _rmembers.Count > 0)
|
if (_rmembers != null && _rmembers.Count > 0)
|
||||||
rmembers = _rmembers.ConvertAll<GroupRoleMembersData>(new Converter<ExtendedGroupRoleMembersData, GroupRoleMembersData>(m_ForeignImporter.ConvertGroupRoleMembersData));
|
rmembers = _rmembers.ConvertAll<GroupRoleMembersData>(new Converter<ExtendedGroupRoleMembersData, GroupRoleMembersData>(m_ForeignImporter.ConvertGroupRoleMembersData));
|
||||||
else
|
else
|
||||||
rmembers = new List<GroupRoleMembersData>();
|
rmembers = new List<GroupRoleMembersData>();
|
||||||
|
|
||||||
lock (m_Cache)
|
lock (m_Cache)
|
||||||
{
|
|
||||||
// For some strange reason, when I cache the list of GroupRoleMembersData,
|
|
||||||
// it gets emptied out. The TryGet gets an empty list...
|
|
||||||
//m_Cache.AddOrUpdate(cacheKey, rmembers, GROUPS_CACHE_TIMEOUT);
|
|
||||||
// Caching the list of ExtendedGroupRoleMembersData doesn't show that issue
|
|
||||||
// I don't get it.
|
|
||||||
m_Cache.AddOrUpdate(cacheKey, _rmembers, GROUPS_CACHE_TIMEOUT);
|
|
||||||
return (List<GroupRoleMembersData>)rmembers;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
{
|
||||||
|
// For some strange reason, when I cache the list of GroupRoleMembersData,
|
||||||
|
// it gets emptied out. The TryGet gets an empty list...
|
||||||
|
//m_Cache.AddOrUpdate(cacheKey, rmembers, GROUPS_CACHE_TIMEOUT);
|
||||||
|
// Caching the list of ExtendedGroupRoleMembersData doesn't show that issue
|
||||||
|
// I don't get it.
|
||||||
|
m_Cache.AddOrUpdate(cacheKey, _rmembers, GROUPS_CACHE_TIMEOUT);
|
||||||
m_ActiveRequests.Remove(cacheKey);
|
m_ActiveRequests.Remove(cacheKey);
|
||||||
|
return (List<GroupRoleMembersData>)rmembers;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -709,19 +666,12 @@ namespace OpenSim.Groups
|
||||||
|
|
||||||
if (firstCall)
|
if (firstCall)
|
||||||
{
|
{
|
||||||
try
|
roles = d();
|
||||||
{
|
lock (m_Cache)
|
||||||
roles = d();
|
|
||||||
lock (m_Cache)
|
|
||||||
{
|
|
||||||
m_Cache.AddOrUpdate(cacheKey, roles, GROUPS_CACHE_TIMEOUT);
|
|
||||||
m_ActiveRequests.Remove(cacheKey);
|
|
||||||
return (List<GroupRolesData>)roles;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
{
|
||||||
|
m_Cache.AddOrUpdate(cacheKey, roles, GROUPS_CACHE_TIMEOUT);
|
||||||
m_ActiveRequests.Remove(cacheKey);
|
m_ActiveRequests.Remove(cacheKey);
|
||||||
|
return (List<GroupRolesData>)roles;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -817,19 +767,13 @@ namespace OpenSim.Groups
|
||||||
|
|
||||||
if (firstCall)
|
if (firstCall)
|
||||||
{
|
{
|
||||||
try
|
GroupNoticeInfo _notice = d();
|
||||||
{
|
|
||||||
GroupNoticeInfo _notice = d();
|
|
||||||
|
|
||||||
lock (m_Cache)
|
lock (m_Cache)
|
||||||
{
|
|
||||||
m_Cache.AddOrUpdate(cacheKey, _notice, GROUPS_CACHE_TIMEOUT);
|
|
||||||
return _notice;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
{
|
||||||
|
m_Cache.AddOrUpdate(cacheKey, _notice, GROUPS_CACHE_TIMEOUT);
|
||||||
m_ActiveRequests.Remove(cacheKey);
|
m_ActiveRequests.Remove(cacheKey);
|
||||||
|
return _notice;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -865,24 +809,20 @@ namespace OpenSim.Groups
|
||||||
|
|
||||||
if (firstCall)
|
if (firstCall)
|
||||||
{
|
{
|
||||||
try
|
notices = d();
|
||||||
{
|
|
||||||
notices = d();
|
|
||||||
|
|
||||||
lock (m_Cache)
|
lock (m_Cache)
|
||||||
{
|
|
||||||
m_Cache.AddOrUpdate(cacheKey, notices, GROUPS_CACHE_TIMEOUT);
|
|
||||||
return (List<ExtendedGroupNoticeData>)notices;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
{
|
||||||
|
m_Cache.AddOrUpdate(cacheKey, notices, GROUPS_CACHE_TIMEOUT);
|
||||||
m_ActiveRequests.Remove(cacheKey);
|
m_ActiveRequests.Remove(cacheKey);
|
||||||
|
return (List<ExtendedGroupNoticeData>)notices;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Thread.Sleep(50);
|
Thread.Sleep(50);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,63 +43,59 @@ 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.Invite |
|
||||||
GroupPowers.LandManageAllowed |
|
GroupPowers.JoinChat |
|
||||||
GroupPowers.LandManageBanned |
|
GroupPowers.LandChangeIdentity |
|
||||||
GroupPowers.LandManagePasses |
|
GroupPowers.LandDeed |
|
||||||
GroupPowers.LandOptions |
|
GroupPowers.LandDivideJoin |
|
||||||
GroupPowers.LandRelease |
|
GroupPowers.LandEdit |
|
||||||
GroupPowers.LandSetSale |
|
GroupPowers.LandEjectAndFreeze |
|
||||||
GroupPowers.MemberVisible |
|
GroupPowers.LandGardening |
|
||||||
GroupPowers.ModerateChat |
|
GroupPowers.LandManageAllowed |
|
||||||
GroupPowers.ObjectManipulate |
|
GroupPowers.LandManageBanned |
|
||||||
GroupPowers.ObjectSetForSale |
|
GroupPowers.LandManagePasses |
|
||||||
GroupPowers.ReturnGroupOwned |
|
GroupPowers.LandOptions |
|
||||||
GroupPowers.ReturnGroupSet |
|
GroupPowers.LandRelease |
|
||||||
GroupPowers.ReturnNonGroup |
|
GroupPowers.LandSetSale |
|
||||||
GroupPowers.RoleProperties |
|
GroupPowers.ModerateChat |
|
||||||
GroupPowers.SendNotices |
|
GroupPowers.ObjectManipulate |
|
||||||
GroupPowers.SetLandingPoint;
|
GroupPowers.ObjectSetForSale |
|
||||||
|
GroupPowers.ReceiveNotices |
|
||||||
public const GroupPowers OwnerPowers = OfficersPowers |
|
GroupPowers.RemoveMember |
|
||||||
GroupPowers.Accountable |
|
GroupPowers.ReturnGroupOwned |
|
||||||
GroupPowers.AllowEditLand |
|
GroupPowers.ReturnGroupSet |
|
||||||
GroupPowers.AssignMember |
|
GroupPowers.ReturnNonGroup |
|
||||||
GroupPowers.ChangeActions |
|
GroupPowers.RoleProperties |
|
||||||
GroupPowers.CreateRole |
|
GroupPowers.SendNotices |
|
||||||
GroupPowers.DeleteRole |
|
GroupPowers.SetLandingPoint |
|
||||||
GroupPowers.ExperienceAdmin |
|
GroupPowers.StartProposal |
|
||||||
GroupPowers.ExperienceCreator |
|
GroupPowers.VoteOnProposal;
|
||||||
GroupPowers.GroupBanAccess |
|
|
||||||
GroupPowers.HostEvent |
|
|
||||||
GroupPowers.RemoveMember;
|
|
||||||
|
|
||||||
#region Daily Cleanup
|
#region Daily Cleanup
|
||||||
|
|
||||||
|
@ -129,7 +125,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 +150,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();
|
data.Data["OwnerRoleID"] = UUID.Random().ToString();
|
||||||
data.Data["OwnerRoleID"] = ownerRoleID.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);
|
UUID roleID = UUID.Random();
|
||||||
|
_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 +222,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);
|
||||||
}
|
}
|
||||||
|
@ -263,9 +247,6 @@ namespace OpenSim.Groups
|
||||||
if (group == null)
|
if (group == null)
|
||||||
return members;
|
return members;
|
||||||
|
|
||||||
// Unfortunately this doesn't quite work on legacy group data because of a bug
|
|
||||||
// that's also being fixed here on CreateGroup. The OwnerRoleID sent to the DB was wrong.
|
|
||||||
// See how to find the ownerRoleID a few lines below.
|
|
||||||
UUID ownerRoleID = new UUID(group.Data["OwnerRoleID"]);
|
UUID ownerRoleID = new UUID(group.Data["OwnerRoleID"]);
|
||||||
|
|
||||||
RoleData[] roles = m_Database.RetrieveRoles(GroupID);
|
RoleData[] roles = m_Database.RetrieveRoles(GroupID);
|
||||||
|
@ -274,25 +255,13 @@ namespace OpenSim.Groups
|
||||||
return members;
|
return members;
|
||||||
List<RoleData> rolesList = new List<RoleData>(roles);
|
List<RoleData> rolesList = new List<RoleData>(roles);
|
||||||
|
|
||||||
// Let's find the "real" ownerRoleID
|
// Is the requester a member of the group?
|
||||||
RoleData ownerRole = rolesList.Find(r => r.Data["Powers"] == ((long)OwnerPowers).ToString());
|
bool isInGroup = false;
|
||||||
if (ownerRole != null)
|
if (m_Database.RetrieveMember(GroupID, RequestingAgentID) != null)
|
||||||
ownerRoleID = ownerRole.RoleID;
|
isInGroup = true;
|
||||||
|
|
||||||
// Check visibility?
|
if (!isInGroup) // reduce the roles to the visible ones
|
||||||
// When we don't want to check visibility, we pass it "all" as the requestingAgentID
|
rolesList = rolesList.FindAll(r => (UInt64.Parse(r.Data["Powers"]) & (ulong)GroupPowers.MemberVisible) != 0);
|
||||||
bool checkVisibility = !RequestingAgentID.Equals(UUID.Zero.ToString());
|
|
||||||
|
|
||||||
if (checkVisibility)
|
|
||||||
{
|
|
||||||
// Is the requester a member of the group?
|
|
||||||
bool isInGroup = false;
|
|
||||||
if (m_Database.RetrieveMember(GroupID, RequestingAgentID) != null)
|
|
||||||
isInGroup = true;
|
|
||||||
|
|
||||||
if (!isInGroup) // reduce the roles to the visible ones
|
|
||||||
rolesList = rolesList.FindAll(r => (UInt64.Parse(r.Data["Powers"]) & (ulong)GroupPowers.MemberVisible) != 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
MembershipData[] datas = m_Database.RetrieveMembers(GroupID);
|
MembershipData[] datas = m_Database.RetrieveMembers(GroupID);
|
||||||
if (datas == null || (datas != null && datas.Length == 0))
|
if (datas == null || (datas != null && datas.Length == 0))
|
||||||
|
@ -315,32 +284,17 @@ namespace OpenSim.Groups
|
||||||
{
|
{
|
||||||
m.Title = selected.Data["Title"];
|
m.Title = selected.Data["Title"];
|
||||||
m.AgentPowers = UInt64.Parse(selected.Data["Powers"]);
|
m.AgentPowers = UInt64.Parse(selected.Data["Powers"]);
|
||||||
|
|
||||||
|
m.AgentID = d.PrincipalID;
|
||||||
|
m.AcceptNotices = d.Data["AcceptNotices"] == "1" ? true : false;
|
||||||
|
m.Contribution = Int32.Parse(d.Data["Contribution"]);
|
||||||
|
m.ListInProfile = d.Data["ListInProfile"] == "1" ? true : false;
|
||||||
|
|
||||||
|
// Is this person an owner of the group?
|
||||||
|
m.IsOwner = (rolemembershipsList.Find(r => r.RoleID == ownerRoleID) != null) ? true : false;
|
||||||
|
|
||||||
|
members.Add(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
m.AgentID = d.PrincipalID;
|
|
||||||
m.AcceptNotices = d.Data["AcceptNotices"] == "1" ? true : false;
|
|
||||||
m.Contribution = Int32.Parse(d.Data["Contribution"]);
|
|
||||||
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?
|
|
||||||
m.IsOwner = (rolemembershipsList.Find(r => r.RoleID == ownerRoleID) != null) ? true : false;
|
|
||||||
|
|
||||||
members.Add(m);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return members;
|
return members;
|
||||||
|
@ -432,15 +386,13 @@ namespace OpenSim.Groups
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool RemoveAgentFromGroup(string RequestingAgentID, string AgentID, UUID GroupID)
|
public void RemoveAgentFromGroup(string RequestingAgentID, string AgentID, UUID GroupID)
|
||||||
{
|
{
|
||||||
// check perms
|
// check perms
|
||||||
if (RequestingAgentID != AgentID && !HasPower(RequestingAgentID, GroupID, GroupPowers.Eject))
|
if (RequestingAgentID != AgentID && !HasPower(RequestingAgentID, GroupID, GroupPowers.Eject))
|
||||||
return false;
|
return;
|
||||||
|
|
||||||
_RemoveAgentFromGroup(RequestingAgentID, AgentID, GroupID);
|
_RemoveAgentFromGroup(RequestingAgentID, AgentID, GroupID);
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool AddAgentToGroupInvite(string RequestingAgentID, UUID inviteID, UUID groupID, UUID roleID, string agentID)
|
public bool AddAgentToGroupInvite(string RequestingAgentID, UUID inviteID, UUID groupID, UUID roleID, string agentID)
|
||||||
|
@ -500,8 +452,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 +463,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 +483,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 +507,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 +666,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 +779,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 +797,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
|
||||||
|
@ -131,27 +131,19 @@ namespace OpenSim.Groups
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool RemoveAgentFromGroup(string RequestingAgentID, string AgentID, UUID GroupID, string token)
|
public void RemoveAgentFromGroup(string RequestingAgentID, string AgentID, UUID GroupID, string token)
|
||||||
{
|
{
|
||||||
// check the token
|
// check the token
|
||||||
MembershipData membership = m_Database.RetrieveMember(GroupID, AgentID);
|
MembershipData membership = m_Database.RetrieveMember(GroupID, AgentID);
|
||||||
if (membership != null)
|
if (membership != null)
|
||||||
{
|
{
|
||||||
if (token != string.Empty && token.Equals(membership.Data["AccessToken"]))
|
if (token != string.Empty && token.Equals(membership.Data["AccessToken"]))
|
||||||
{
|
RemoveAgentFromGroup(RequestingAgentID, AgentID, GroupID);
|
||||||
return RemoveAgentFromGroup(RequestingAgentID, AgentID, GroupID);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
m_log.DebugFormat("[Groups.HGGroupsService]: access token {0} did not match stored one {1}", token, membership.Data["AccessToken"]);
|
m_log.DebugFormat("[Groups.HGGroupsService]: access token {0} did not match stored one {1}", token, membership.Data["AccessToken"]);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
m_log.DebugFormat("[Groups.HGGroupsService]: membership not found for {0}", AgentID);
|
m_log.DebugFormat("[Groups.HGGroupsService]: membership not found for {0}", AgentID);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ExtendedGroupRecord GetGroupRecord(string RequestingAgentID, UUID GroupID, string groupName, string token)
|
public ExtendedGroupRecord GetGroupRecord(string RequestingAgentID, UUID GroupID, string groupName, string token)
|
||||||
|
|
|
@ -66,7 +66,7 @@ namespace OpenSim.OfflineIM
|
||||||
if (serviceLocation == string.Empty)
|
if (serviceLocation == string.Empty)
|
||||||
m_OfflineIMService = new OfflineIMService(config);
|
m_OfflineIMService = new OfflineIMService(config);
|
||||||
else
|
else
|
||||||
m_OfflineIMService = new OfflineIMServiceRemoteConnector(config);
|
m_OfflineIMService = new OfflineIMServiceRemoteConnector(serviceLocation);
|
||||||
|
|
||||||
m_ForwardOfflineGroupMessages = cnf.GetBoolean("ForwardOfflineGroupMessages", m_ForwardOfflineGroupMessages);
|
m_ForwardOfflineGroupMessages = cnf.GetBoolean("ForwardOfflineGroupMessages", m_ForwardOfflineGroupMessages);
|
||||||
m_log.DebugFormat("[OfflineIM.V2]: Offline messages enabled by {0}", Name);
|
m_log.DebugFormat("[OfflineIM.V2]: Offline messages enabled by {0}", Name);
|
||||||
|
@ -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 &&
|
||||||
|
@ -210,6 +226,10 @@ namespace OpenSim.OfflineIM
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Scene scene = FindScene(new UUID(im.fromAgentID));
|
||||||
|
if (scene == null)
|
||||||
|
scene = m_SceneList[0];
|
||||||
|
|
||||||
string reason = string.Empty;
|
string reason = string.Empty;
|
||||||
bool success = m_OfflineIMService.StoreMessage(im, out reason);
|
bool success = m_OfflineIMService.StoreMessage(im, out reason);
|
||||||
|
|
||||||
|
@ -241,11 +261,6 @@ namespace OpenSim.OfflineIM
|
||||||
return m_OfflineIMService.StoreMessage(im, out reason);
|
return m_OfflineIMService.StoreMessage(im, out reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DeleteMessages(UUID userID)
|
|
||||||
{
|
|
||||||
m_OfflineIMService.DeleteMessages(userID);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.7.6.*")]
|
||||||
|
|
||||||
[assembly: Addin("OpenSim.OfflineIM", OpenSim.VersionInfo.VersionNumber)]
|
[assembly: Addin("OpenSim.OfflineIM", "0.1")]
|
||||||
[assembly: AddinDependency("OpenSim.Region.Framework", OpenSim.VersionInfo.VersionNumber)]
|
[assembly: AddinDependency("OpenSim", "0.5")]
|
||||||
|
|
|
@ -32,7 +32,6 @@ using System.Reflection;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
using OpenSim.Framework.ServiceAuth;
|
|
||||||
using OpenSim.Server.Base;
|
using OpenSim.Server.Base;
|
||||||
using OpenSim.Services.Interfaces;
|
using OpenSim.Services.Interfaces;
|
||||||
|
|
||||||
|
@ -47,7 +46,6 @@ namespace OpenSim.OfflineIM
|
||||||
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_ServerURI = string.Empty;
|
private string m_ServerURI = string.Empty;
|
||||||
private IServiceAuth m_Auth;
|
|
||||||
private object m_Lock = new object();
|
private object m_Lock = new object();
|
||||||
|
|
||||||
public OfflineIMServiceRemoteConnector(string url)
|
public OfflineIMServiceRemoteConnector(string url)
|
||||||
|
@ -67,18 +65,6 @@ namespace OpenSim.OfflineIM
|
||||||
|
|
||||||
m_ServerURI = cnf.GetString("OfflineMessageURL", string.Empty);
|
m_ServerURI = cnf.GetString("OfflineMessageURL", string.Empty);
|
||||||
|
|
||||||
/// This is from BaseServiceConnector
|
|
||||||
string authType = Util.GetConfigVarFromSections<string>(config, "AuthType", new string[] { "Network", "Messaging" }, "None");
|
|
||||||
|
|
||||||
switch (authType)
|
|
||||||
{
|
|
||||||
case "BasicHttpAuthentication":
|
|
||||||
m_Auth = new BasicHttpAuthentication(config, "Messaging");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
///
|
|
||||||
m_log.DebugFormat("[OfflineIM.V2.RemoteConnector]: Offline IM server at {0} with auth {1}",
|
|
||||||
m_ServerURI, (m_Auth == null ? "None" : m_Auth.GetType().ToString()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#region IOfflineIMService
|
#region IOfflineIMService
|
||||||
|
@ -96,13 +82,8 @@ namespace OpenSim.OfflineIM
|
||||||
if (!ret.ContainsKey("RESULT"))
|
if (!ret.ContainsKey("RESULT"))
|
||||||
return ims;
|
return ims;
|
||||||
|
|
||||||
string result = ret["RESULT"].ToString();
|
if (ret["RESULT"].ToString() == "NULL")
|
||||||
if (result == "NULL" || result.ToLower() == "false")
|
|
||||||
{
|
|
||||||
string reason = ret.ContainsKey("REASON") ? ret["REASON"].ToString() : "Unknown error";
|
|
||||||
m_log.DebugFormat("[OfflineIM.V2.RemoteConnector]: GetMessages for {0} failed: {1}", principalID, reason);
|
|
||||||
return ims;
|
return ims;
|
||||||
}
|
|
||||||
|
|
||||||
foreach (object v in ((Dictionary<string, object>)ret["RESULT"]).Values)
|
foreach (object v in ((Dictionary<string, object>)ret["RESULT"]).Values)
|
||||||
{
|
{
|
||||||
|
@ -129,21 +110,13 @@ namespace OpenSim.OfflineIM
|
||||||
string result = ret["RESULT"].ToString();
|
string result = ret["RESULT"].ToString();
|
||||||
if (result == "NULL" || result.ToLower() == "false")
|
if (result == "NULL" || result.ToLower() == "false")
|
||||||
{
|
{
|
||||||
reason = ret.ContainsKey("REASON") ? ret["REASON"].ToString() : "Unknown error";
|
reason = ret["REASON"].ToString();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DeleteMessages(UUID userID)
|
|
||||||
{
|
|
||||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
|
||||||
sendData["UserID"] = userID;
|
|
||||||
|
|
||||||
MakeRequest("DELETE", sendData);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
@ -157,8 +130,7 @@ namespace OpenSim.OfflineIM
|
||||||
lock (m_Lock)
|
lock (m_Lock)
|
||||||
reply = SynchronousRestFormsRequester.MakeRequest("POST",
|
reply = SynchronousRestFormsRequester.MakeRequest("POST",
|
||||||
m_ServerURI + "/offlineim",
|
m_ServerURI + "/offlineim",
|
||||||
ServerUtils.BuildQueryString(sendData),
|
ServerUtils.BuildQueryString(sendData));
|
||||||
m_Auth);
|
|
||||||
|
|
||||||
Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(
|
Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(
|
||||||
reply);
|
reply);
|
||||||
|
|
|
@ -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.
|
||||||
*
|
*
|
||||||
|
@ -36,7 +36,6 @@ using OpenSim.Framework;
|
||||||
using OpenSim.Server.Base;
|
using OpenSim.Server.Base;
|
||||||
using OpenSim.Services.Interfaces;
|
using OpenSim.Services.Interfaces;
|
||||||
using OpenSim.Framework.Servers.HttpServer;
|
using OpenSim.Framework.Servers.HttpServer;
|
||||||
using OpenSim.Framework.ServiceAuth;
|
|
||||||
using OpenSim.Server.Handlers.Base;
|
using OpenSim.Server.Handlers.Base;
|
||||||
using log4net;
|
using log4net;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
|
@ -60,9 +59,7 @@ namespace OpenSim.OfflineIM
|
||||||
|
|
||||||
m_OfflineIMService = new OfflineIMService(config);
|
m_OfflineIMService = new OfflineIMService(config);
|
||||||
|
|
||||||
IServiceAuth auth = ServiceAuth.Create(config, m_ConfigName);
|
server.AddStreamHandler(new OfflineIMServicePostHandler(m_OfflineIMService));
|
||||||
|
|
||||||
server.AddStreamHandler(new OfflineIMServicePostHandler(m_OfflineIMService, auth));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,8 +69,8 @@ namespace OpenSim.OfflineIM
|
||||||
|
|
||||||
private IOfflineIMService m_OfflineIMService;
|
private IOfflineIMService m_OfflineIMService;
|
||||||
|
|
||||||
public OfflineIMServicePostHandler(IOfflineIMService service, IServiceAuth auth) :
|
public OfflineIMServicePostHandler(IOfflineIMService service) :
|
||||||
base("POST", "/offlineim", auth)
|
base("POST", "/offlineim")
|
||||||
{
|
{
|
||||||
m_OfflineIMService = service;
|
m_OfflineIMService = service;
|
||||||
}
|
}
|
||||||
|
@ -99,20 +96,19 @@ namespace OpenSim.OfflineIM
|
||||||
string method = request["METHOD"].ToString();
|
string method = request["METHOD"].ToString();
|
||||||
request.Remove("METHOD");
|
request.Remove("METHOD");
|
||||||
|
|
||||||
|
m_log.DebugFormat("[OfflineIM.V2.Handler]: {0}", method);
|
||||||
switch (method)
|
switch (method)
|
||||||
{
|
{
|
||||||
case "GET":
|
case "GET":
|
||||||
return HandleGet(request);
|
return HandleGet(request);
|
||||||
case "STORE":
|
case "STORE":
|
||||||
return HandleStore(request);
|
return HandleStore(request);
|
||||||
case "DELETE":
|
|
||||||
return HandleDelete(request);
|
|
||||||
}
|
}
|
||||||
m_log.DebugFormat("[OFFLINE IM HANDLER]: unknown method request: {0}", method);
|
m_log.DebugFormat("[OFFLINE IM HANDLER]: unknown method request: {0}", method);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
m_log.Error(string.Format("[OFFLINE IM HANDLER]: Exception {0} ", e.Message), e);
|
m_log.DebugFormat("[OFFLINE IM HANDLER]: Exception {0}", e.StackTrace);
|
||||||
}
|
}
|
||||||
|
|
||||||
return FailureResult();
|
return FailureResult();
|
||||||
|
@ -163,21 +159,6 @@ namespace OpenSim.OfflineIM
|
||||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] HandleDelete(Dictionary<string, object> request)
|
|
||||||
{
|
|
||||||
if (!request.ContainsKey("UserID"))
|
|
||||||
{
|
|
||||||
return FailureResult();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UUID userID = new UUID(request["UserID"].ToString());
|
|
||||||
m_OfflineIMService.DeleteMessages(userID);
|
|
||||||
|
|
||||||
return SuccessResult();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#region Helpers
|
#region Helpers
|
||||||
|
|
||||||
private void NullResult(Dictionary<string, object> result, string reason)
|
private void NullResult(Dictionary<string, object> result, string reason)
|
||||||
|
@ -215,7 +196,18 @@ namespace OpenSim.OfflineIM
|
||||||
|
|
||||||
rootElement.AppendChild(result);
|
rootElement.AppendChild(result);
|
||||||
|
|
||||||
return Util.DocToBytes(doc);
|
return DocToBytes(doc);
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] DocToBytes(XmlDocument doc)
|
||||||
|
{
|
||||||
|
MemoryStream ms = new MemoryStream();
|
||||||
|
XmlTextWriter xw = new XmlTextWriter(ms, null);
|
||||||
|
xw.Formatting = Formatting.Indented;
|
||||||
|
doc.WriteTo(xw);
|
||||||
|
xw.Flush();
|
||||||
|
|
||||||
|
return ms.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
|
@ -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.
|
||||||
*
|
*
|
||||||
|
@ -90,8 +90,8 @@ 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
|
// TODO 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());
|
||||||
if (count >= MAX_IM)
|
if (count >= MAX_IM)
|
||||||
|
@ -100,35 +100,32 @@ namespace OpenSim.OfflineIM
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
string imXml;
|
string imXml = string.Empty;
|
||||||
using (MemoryStream mstream = new MemoryStream())
|
using (MemoryStream mstream = new MemoryStream())
|
||||||
{
|
{
|
||||||
XmlWriterSettings settings = new XmlWriterSettings();
|
XmlWriterSettings settings = new XmlWriterSettings();
|
||||||
settings.Encoding = Util.UTF8NoBomEncoding;
|
settings.Encoding = Encoding.UTF8;
|
||||||
|
|
||||||
using (XmlWriter writer = XmlWriter.Create(mstream, settings))
|
using (XmlWriter writer = XmlWriter.Create(mstream, settings))
|
||||||
{
|
{
|
||||||
m_serializer.Serialize(writer, im);
|
m_serializer.Serialize(writer, im);
|
||||||
writer.Flush();
|
writer.Flush();
|
||||||
imXml = Util.UTF8NoBomEncoding.GetString(mstream.ToArray());
|
|
||||||
|
mstream.Position = 0;
|
||||||
|
using (StreamReader sreader = new StreamReader(mstream))
|
||||||
|
{
|
||||||
|
imXml = sreader.ReadToEnd();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
OfflineIMData data = new OfflineIMData();
|
OfflineIMData data = new OfflineIMData();
|
||||||
data.PrincipalID = principalID;
|
data.PrincipalID = principalID;
|
||||||
data.FromID = new UUID(im.fromAgentID);
|
|
||||||
data.Data = new Dictionary<string, string>();
|
data.Data = new Dictionary<string, string>();
|
||||||
data.Data["Message"] = imXml;
|
data.Data["Message"] = imXml;
|
||||||
|
|
||||||
return m_Database.Store(data);
|
return m_Database.Store(data);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DeleteMessages(UUID userID)
|
|
||||||
{
|
|
||||||
m_Database.Delete("PrincipalID", userID.ToString());
|
|
||||||
m_Database.Delete("FromID", userID.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,17 +32,16 @@ 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;
|
||||||
using OpenSim.Region.CoreModules.Scripting.LoadImageURL;
|
using OpenSim.Region.CoreModules.Scripting.LoadImageURL;
|
||||||
using OpenSim.Region.CoreModules.Scripting.XMLRPC;
|
using OpenSim.Region.CoreModules.Scripting.XMLRPC;
|
||||||
using OpenSim.Services.Interfaces;
|
|
||||||
using Mono.Addins;
|
|
||||||
|
|
||||||
namespace OpenSim.ApplicationPlugins.LoadRegions
|
namespace OpenSim.ApplicationPlugins.LoadRegions
|
||||||
{
|
{
|
||||||
[Extension(Path="/OpenSim/Startup", Id="LoadRegions", NodeName="Plugin")]
|
|
||||||
public class LoadRegionsPlugin : IApplicationPlugin, IRegionCreator
|
public class LoadRegionsPlugin : IApplicationPlugin, IRegionCreator
|
||||||
{
|
{
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
@ -124,14 +123,14 @@ 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);
|
||||||
createdScenes.Add(scene);
|
createdScenes.Add(scene);
|
||||||
|
|
||||||
if (changed)
|
if (changed)
|
||||||
m_openSim.EstateDataService.StoreEstateSettings(regionsToLoad[i].EstateSettings);
|
regionsToLoad[i].EstateSettings.Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (IScene scene in createdScenes)
|
foreach (IScene scene in createdScenes)
|
||||||
|
|
|
@ -27,17 +27,16 @@
|
||||||
|
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
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.LoadRegions")]
|
[assembly : AssemblyTitle("OpenSim.Addin")]
|
||||||
[assembly : AssemblyDescription("")]
|
[assembly : AssemblyDescription("")]
|
||||||
[assembly : AssemblyConfiguration("")]
|
[assembly : AssemblyConfiguration("")]
|
||||||
[assembly : AssemblyCompany("http://opensimulator.org")]
|
[assembly : AssemblyCompany("http://opensimulator.org")]
|
||||||
[assembly : AssemblyProduct("OpenSim")]
|
[assembly : AssemblyProduct("OpenSim.Addin")]
|
||||||
[assembly : AssemblyCopyright("Copyright © OpenSimulator.org Developers 2007-2009")]
|
[assembly : AssemblyCopyright("Copyright © OpenSimulator.org Developers 2007-2009")]
|
||||||
[assembly : AssemblyTrademark("")]
|
[assembly : AssemblyTrademark("")]
|
||||||
[assembly : AssemblyCulture("")]
|
[assembly : AssemblyCulture("")]
|
||||||
|
@ -61,8 +60,6 @@ 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.7.6.*")]
|
||||||
|
|
||||||
[assembly: Addin("OpenSim.ApplicationPlugins.LoadRegions", OpenSim.VersionInfo.VersionNumber)]
|
|
||||||
[assembly: AddinDependency("OpenSim", OpenSim.VersionInfo.VersionNumber)]
|
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
<Addin id="OpenSim.ApplicationPlugins.LoadRegions" version="0.1">
|
||||||
|
<Runtime>
|
||||||
|
<Import assembly="OpenSim.ApplicationPlugins.LoadRegions.dll"/>
|
||||||
|
</Runtime>
|
||||||
|
<Dependencies>
|
||||||
|
<Addin id="OpenSim" version="0.5" />
|
||||||
|
</Dependencies>
|
||||||
|
<Extension path = "/OpenSim/Startup">
|
||||||
|
<Plugin id="LoadRegions" type="OpenSim.ApplicationPlugins.LoadRegions.LoadRegionsPlugin" />
|
||||||
|
</Extension>
|
||||||
|
</Addin>
|
|
@ -1,9 +1,8 @@
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
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 +14,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 +25,9 @@ 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.7.6.*")]
|
||||||
|
|
||||||
[assembly: Addin("OpenSim.ApplicationPlugins.RegionModulesController", OpenSim.VersionInfo.VersionNumber)]
|
|
||||||
[assembly: AddinDependency("OpenSim", OpenSim.VersionInfo.VersionNumber)]
|
|
||||||
|
|
|
@ -32,13 +32,11 @@ using log4net;
|
||||||
using Mono.Addins;
|
using Mono.Addins;
|
||||||
using Nini.Config;
|
using Nini.Config;
|
||||||
using OpenSim;
|
using OpenSim;
|
||||||
using OpenSim.Framework;
|
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
using OpenSim.Region.Framework.Interfaces;
|
||||||
using OpenSim.Region.Framework.Scenes;
|
using OpenSim.Region.Framework.Scenes;
|
||||||
|
|
||||||
namespace OpenSim.ApplicationPlugins.RegionModulesController
|
namespace OpenSim.ApplicationPlugins.RegionModulesController
|
||||||
{
|
{
|
||||||
[Extension(Path = "/OpenSim/Startup", Id = "LoadRegions", NodeName = "Plugin")]
|
|
||||||
public class RegionModulesControllerPlugin : IRegionModulesController,
|
public class RegionModulesControllerPlugin : IRegionModulesController,
|
||||||
IApplicationPlugin
|
IApplicationPlugin
|
||||||
{
|
{
|
||||||
|
@ -47,12 +45,6 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
|
||||||
LogManager.GetLogger(
|
LogManager.GetLogger(
|
||||||
MethodBase.GetCurrentMethod().DeclaringType);
|
MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Controls whether we load modules from Mono.Addins.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>For debug purposes. Defaults to true.</remarks>
|
|
||||||
public bool LoadModulesFromAddins { get; set; }
|
|
||||||
|
|
||||||
// Config access
|
// Config access
|
||||||
private OpenSimBase m_openSim;
|
private OpenSimBase m_openSim;
|
||||||
|
|
||||||
|
@ -69,22 +61,14 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
|
||||||
private List<ISharedRegionModule> m_sharedInstances =
|
private List<ISharedRegionModule> m_sharedInstances =
|
||||||
new List<ISharedRegionModule>();
|
new List<ISharedRegionModule>();
|
||||||
|
|
||||||
public RegionModulesControllerPlugin()
|
|
||||||
{
|
|
||||||
LoadModulesFromAddins = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
#region IApplicationPlugin implementation
|
#region IApplicationPlugin implementation
|
||||||
|
|
||||||
public void Initialise (OpenSimBase openSim)
|
public void Initialise (OpenSimBase openSim)
|
||||||
{
|
{
|
||||||
m_openSim = openSim;
|
m_openSim = openSim;
|
||||||
m_openSim.ApplicationRegistry.RegisterInterface<IRegionModulesController>(this);
|
m_openSim.ApplicationRegistry.RegisterInterface<IRegionModulesController>(this);
|
||||||
m_log.DebugFormat("[REGIONMODULES]: Initializing...");
|
m_log.DebugFormat("[REGIONMODULES]: Initializing...");
|
||||||
|
|
||||||
if (!LoadModulesFromAddins)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Who we are
|
// Who we are
|
||||||
string id = AddinManager.CurrentAddin.Id;
|
string id = AddinManager.CurrentAddin.Id;
|
||||||
|
|
||||||
|
@ -104,14 +88,46 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
|
||||||
Dictionary<RuntimeAddin, IList<int>> loadedModules = new Dictionary<RuntimeAddin, IList<int>>();
|
Dictionary<RuntimeAddin, IList<int>> loadedModules = new Dictionary<RuntimeAddin, IList<int>>();
|
||||||
|
|
||||||
// Scan modules and load all that aren't disabled
|
// Scan modules and load all that aren't disabled
|
||||||
foreach (TypeExtensionNode node in AddinManager.GetExtensionNodes("/OpenSim/RegionModules"))
|
foreach (TypeExtensionNode node in
|
||||||
AddNode(node, modulesConfig, loadedModules);
|
AddinManager.GetExtensionNodes("/OpenSim/RegionModules"))
|
||||||
|
{
|
||||||
|
IList<int> loadedModuleData;
|
||||||
|
|
||||||
|
if (!loadedModules.ContainsKey(node.Addin))
|
||||||
|
loadedModules.Add(node.Addin, new List<int> { 0, 0, 0 });
|
||||||
|
|
||||||
|
loadedModuleData = loadedModules[node.Addin];
|
||||||
|
|
||||||
|
if (node.Type.GetInterface(typeof(ISharedRegionModule).ToString()) != null)
|
||||||
|
{
|
||||||
|
if (CheckModuleEnabled(node, modulesConfig))
|
||||||
|
{
|
||||||
|
m_log.DebugFormat("[REGIONMODULES]: Found shared region module {0}, class {1}", node.Id, node.Type);
|
||||||
|
m_sharedModules.Add(node);
|
||||||
|
loadedModuleData[0]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (node.Type.GetInterface(typeof(INonSharedRegionModule).ToString()) != null)
|
||||||
|
{
|
||||||
|
if (CheckModuleEnabled(node, modulesConfig))
|
||||||
|
{
|
||||||
|
m_log.DebugFormat("[REGIONMODULES]: Found non-shared region module {0}, class {1}", node.Id, node.Type);
|
||||||
|
m_nonSharedModules.Add(node);
|
||||||
|
loadedModuleData[1]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_log.WarnFormat("[REGIONMODULES]: Found unknown type of module {0}, class {1}", node.Id, node.Type);
|
||||||
|
loadedModuleData[2]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
foreach (KeyValuePair<RuntimeAddin, IList<int>> loadedModuleData in loadedModules)
|
foreach (KeyValuePair<RuntimeAddin, IList<int>> loadedModuleData in loadedModules)
|
||||||
{
|
{
|
||||||
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 +147,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)
|
||||||
|
@ -181,41 +194,6 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
|
||||||
|
|
||||||
#region IPlugin implementation
|
#region IPlugin implementation
|
||||||
|
|
||||||
private void AddNode(
|
|
||||||
TypeExtensionNode node, IConfig modulesConfig, Dictionary<RuntimeAddin, IList<int>> loadedModules)
|
|
||||||
{
|
|
||||||
IList<int> loadedModuleData;
|
|
||||||
|
|
||||||
if (!loadedModules.ContainsKey(node.Addin))
|
|
||||||
loadedModules.Add(node.Addin, new List<int> { 0, 0, 0 });
|
|
||||||
|
|
||||||
loadedModuleData = loadedModules[node.Addin];
|
|
||||||
|
|
||||||
if (node.Type.GetInterface(typeof(ISharedRegionModule).ToString()) != null)
|
|
||||||
{
|
|
||||||
if (CheckModuleEnabled(node, modulesConfig))
|
|
||||||
{
|
|
||||||
m_log.DebugFormat("[REGIONMODULES]: Found shared region module {0}, class {1}", node.Id, node.Type);
|
|
||||||
m_sharedModules.Add(node);
|
|
||||||
loadedModuleData[0]++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (node.Type.GetInterface(typeof(INonSharedRegionModule).ToString()) != null)
|
|
||||||
{
|
|
||||||
if (CheckModuleEnabled(node, modulesConfig))
|
|
||||||
{
|
|
||||||
m_log.DebugFormat("[REGIONMODULES]: Found non-shared region module {0}, class {1}", node.Id, node.Type);
|
|
||||||
m_nonSharedModules.Add(node);
|
|
||||||
loadedModuleData[1]++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_log.WarnFormat("[REGIONMODULES]: Found unknown type of module {0}, class {1}", node.Id, node.Type);
|
|
||||||
loadedModuleData[2]++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// We don't do that here
|
// We don't do that here
|
||||||
//
|
//
|
||||||
public void Initialise ()
|
public void Initialise ()
|
||||||
|
@ -237,7 +215,6 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
|
||||||
m_sharedInstances[0].Close();
|
m_sharedInstances[0].Close();
|
||||||
m_sharedInstances.RemoveAt(0);
|
m_sharedInstances.RemoveAt(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_sharedModules.Clear();
|
m_sharedModules.Clear();
|
||||||
m_nonSharedModules.Clear();
|
m_nonSharedModules.Clear();
|
||||||
}
|
}
|
||||||
|
@ -261,7 +238,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 +270,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 +345,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 +482,6 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
|
||||||
{
|
{
|
||||||
module.RegionLoaded(scene);
|
module.RegionLoaded(scene);
|
||||||
}
|
}
|
||||||
|
|
||||||
scene.AllModulesLoaded();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveRegionFromModules (Scene scene)
|
public void RemoveRegionFromModules (Scene scene)
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
<Addin id="OpenSim.ApplicationPlugins.RegionModulesController" version="0.1">
|
||||||
|
<Runtime>
|
||||||
|
<Import assembly="OpenSim.ApplicationPlugins.RegionModulesController.dll"/>
|
||||||
|
</Runtime>
|
||||||
|
|
||||||
|
<Dependencies>
|
||||||
|
<Addin id="OpenSim" version="0.5" />
|
||||||
|
</Dependencies>
|
||||||
|
|
||||||
|
<Extension path = "/OpenSim/Startup">
|
||||||
|
<Plugin id="RegionModulesController" type="OpenSim.ApplicationPlugins.RegionModulesController.RegionModulesControllerPlugin" />
|
||||||
|
</Extension>
|
||||||
|
</Addin>
|
|
@ -1,9 +1,8 @@
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
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 +14,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 +25,9 @@ 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.7.6.*")]
|
||||||
|
|
||||||
[assembly: Addin("OpenSim.ApplicationPlugins.RemoteController", OpenSim.VersionInfo.VersionNumber)]
|
|
||||||
[assembly: AddinDependency("OpenSim", OpenSim.VersionInfo.VersionNumber)]
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,11 @@
|
||||||
|
<Addin id="OpenSim.ApplicationPlugins.RemoteController" version="0.1">
|
||||||
|
<Runtime>
|
||||||
|
<Import assembly="OpenSim.ApplicationPlugins.RemoteController.dll"/>
|
||||||
|
</Runtime>
|
||||||
|
<Dependencies>
|
||||||
|
<Addin id="OpenSim" version="0.5" />
|
||||||
|
</Dependencies>
|
||||||
|
<Extension path = "/OpenSim/Startup">
|
||||||
|
<Plugin id="RemoteController" type="OpenSim.ApplicationPlugins.RemoteController.RemoteAdminPlugin" />
|
||||||
|
</Extension>
|
||||||
|
</Addin>
|
|
@ -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,10 @@ 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 +64,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 +118,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 +135,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 +150,16 @@ 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_pollServiceHandlers.Add(capName, pollServiceHandler);
|
||||||
// "[CAPS]: Registering handler with name {0}, url {1} for {2}",
|
|
||||||
// capName, pollServiceHandler.Url, m_agentID, m_regionName);
|
|
||||||
|
|
||||||
if(!m_pollServiceHandlers.TryAdd(capName, pollServiceHandler))
|
m_httpListener.AddPollServiceHTTPHandler(pollServiceHandler.Url, 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);
|
|
||||||
|
|
||||||
// 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 +194,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 +227,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 +250,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);
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -43,112 +43,73 @@ using Caps = OpenSim.Framework.Capabilities.Caps;
|
||||||
|
|
||||||
namespace OpenSim.Capabilities.Handlers
|
namespace OpenSim.Capabilities.Handlers
|
||||||
{
|
{
|
||||||
public class GetMeshHandler
|
public class GetMeshHandler
|
||||||
{
|
{
|
||||||
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(IAssetService assService)
|
public GetMeshHandler(IAssetService assService)
|
||||||
{
|
{
|
||||||
m_assetService = assService;
|
m_assetService = assService;
|
||||||
}
|
}
|
||||||
public Hashtable Handle(Hashtable request)
|
|
||||||
{
|
|
||||||
return ProcessGetMesh(request, UUID.Zero, null); ;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Hashtable ProcessGetMesh(Hashtable request, UUID AgentId, Caps cap)
|
public Hashtable ProcessGetMesh(Hashtable request, UUID AgentId, Caps cap)
|
||||||
{
|
{
|
||||||
Hashtable responsedata = new Hashtable();
|
Hashtable responsedata = new Hashtable();
|
||||||
if (m_assetService == null)
|
responsedata["int_response_code"] = 400; //501; //410; //404;
|
||||||
{
|
|
||||||
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["content_type"] = "text/plain";
|
||||||
responsedata["int_bytes"] = 0;
|
responsedata["keepalive"] = false;
|
||||||
|
responsedata["str_response_string"] = "Request wasn't what was expected";
|
||||||
|
|
||||||
string meshStr = string.Empty;
|
string meshStr = string.Empty;
|
||||||
|
|
||||||
if (request.ContainsKey("mesh_id"))
|
if (request.ContainsKey("mesh_id"))
|
||||||
meshStr = request["mesh_id"].ToString();
|
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.";
|
responsedata["int_response_code"] = 404; //501; //410; //404;
|
||||||
|
responsedata["content_type"] = "text/plain";
|
||||||
|
responsedata["keepalive"] = false;
|
||||||
|
responsedata["str_response_string"] = "The asset service is unavailable. So is your mesh.";
|
||||||
return responsedata;
|
return responsedata;
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data);
|
||||||
|
responsedata["content_type"] = "application/vnd.ll.mesh";
|
||||||
byte[] d = new byte[len];
|
responsedata["int_response_code"] = 200;
|
||||||
Array.Copy(mesh.Data, start, d, 0, len);
|
}
|
||||||
responsedata["bin_response_data"] = d;
|
// Optionally add additional mesh types here
|
||||||
responsedata["int_bytes"] = len;
|
else
|
||||||
return responsedata;
|
{
|
||||||
|
responsedata["int_response_code"] = 404; //501; //410; //404;
|
||||||
|
responsedata["content_type"] = "text/plain";
|
||||||
|
responsedata["keepalive"] = false;
|
||||||
|
responsedata["str_response_string"] = "Unfortunately, this asset isn't a mesh.";
|
||||||
|
return responsedata;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
responsedata["int_response_code"] = 404; //501; //410; //404;
|
||||||
|
responsedata["content_type"] = "text/plain";
|
||||||
|
responsedata["keepalive"] = false;
|
||||||
|
responsedata["str_response_string"] = "Your Mesh wasn't found. Sorry!";
|
||||||
|
return responsedata;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_log.Warn("[GETMESH]: Failed to parse a range from GetMesh request, sending full asset: " + (string)request["uri"]);
|
|
||||||
responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data);
|
|
||||||
responsedata["int_response_code"] = (int)System.Net.HttpStatusCode.OK;
|
|
||||||
return responsedata;
|
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,15 @@ 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");
|
|
||||||
|
|
||||||
GetMeshHandler gmeshHandler = new GetMeshHandler(m_AssetService);
|
GetMeshHandler gmeshHandler = new GetMeshHandler(m_AssetService);
|
||||||
IRequestHandler reqHandler
|
IRequestHandler reqHandler
|
||||||
= new RestHTTPHandler(
|
= new RestHTTPHandler(
|
||||||
"GET",
|
"GET",
|
||||||
"/" + UUID.Random(),
|
"/CAPS/" + UUID.Random(),
|
||||||
httpMethod => gmeshHandler.ProcessGetMesh(httpMethod, UUID.Zero, null),
|
httpMethod => gmeshHandler.ProcessGetMesh(httpMethod, UUID.Zero, null),
|
||||||
"GetMesh",
|
"GetMesh",
|
||||||
null);
|
null);
|
||||||
server.AddStreamHandler(reqHandler); ;
|
server.AddStreamHandler(reqHandler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -47,92 +47,85 @@ 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
|
||||||
|
const string REDIRECT_URL = null;
|
||||||
|
|
||||||
|
public GetTextureHandler(string path, IAssetService assService, string name, string description)
|
||||||
|
: base("GET", path, name, description)
|
||||||
{
|
{
|
||||||
m_assetService = assService;
|
m_assetService = assService;
|
||||||
}
|
}
|
||||||
|
|
||||||
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 (format != null && format != string.Empty)
|
||||||
{
|
{
|
||||||
formats = new string[1] { format.ToLower() };
|
formats = new string[1] { format.ToLower() };
|
||||||
}
|
}
|
||||||
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 +134,91 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
if (format != DefaultFormat)
|
if (format != DefaultFormat)
|
||||||
fullID = fullID + "-" + format;
|
fullID = fullID + "-" + format;
|
||||||
|
|
||||||
// try the cache
|
if (!String.IsNullOrEmpty(REDIRECT_URL))
|
||||||
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 = REDIRECT_URL + 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.RedirectLocation = textureUrl;
|
||||||
return true;
|
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 +240,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 +258,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 +305,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 +401,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 +424,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
|
||||||
|
@ -63,11 +62,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("GetTextureRedirectURL");
|
|
||||||
;
|
|
||||||
server.AddStreamHandler(
|
server.AddStreamHandler(
|
||||||
new GetTextureRobustHandler("/CAPS/GetTexture", m_AssetService, "GetTexture", null, rurl));
|
new GetTextureHandler("/CAPS/GetTexture/" /*+ UUID.Random() */, m_AssetService, "GetTexture", null));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,8 +37,8 @@ using OpenSim.Framework;
|
||||||
using OpenSim.Framework.Servers.HttpServer;
|
using OpenSim.Framework.Servers.HttpServer;
|
||||||
using OpenSim.Region.Framework.Scenes;
|
using OpenSim.Region.Framework.Scenes;
|
||||||
using OpenSim.Tests.Common;
|
using OpenSim.Tests.Common;
|
||||||
|
using OpenSim.Tests.Common.Mock;
|
||||||
|
|
||||||
/*
|
|
||||||
namespace OpenSim.Capabilities.Handlers.GetTexture.Tests
|
namespace OpenSim.Capabilities.Handlers.GetTexture.Tests
|
||||||
{
|
{
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
|
@ -52,7 +52,7 @@ namespace OpenSim.Capabilities.Handlers.GetTexture.Tests
|
||||||
// Overkill - we only really need the asset service, not a whole scene.
|
// Overkill - we only really need the asset service, not a whole scene.
|
||||||
Scene scene = new SceneHelpers().SetupScene();
|
Scene scene = new SceneHelpers().SetupScene();
|
||||||
|
|
||||||
GetTextureHandler handler = new GetTextureHandler("/gettexture", scene.AssetService, "TestGetTexture", null, null);
|
GetTextureHandler handler = new GetTextureHandler(null, scene.AssetService, "TestGetTexture", null);
|
||||||
TestOSHttpRequest req = new TestOSHttpRequest();
|
TestOSHttpRequest req = new TestOSHttpRequest();
|
||||||
TestOSHttpResponse resp = new TestOSHttpResponse();
|
TestOSHttpResponse resp = new TestOSHttpResponse();
|
||||||
req.Url = new Uri("http://localhost/?texture_id=00000000-0000-1111-9999-000000000012");
|
req.Url = new Uri("http://localhost/?texture_id=00000000-0000-1111-9999-000000000012");
|
||||||
|
@ -60,5 +60,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.7.6.*")]
|
||||||
|
|
||||||
|
|
|
@ -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,18 +29,18 @@ 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.BakedTextures
|
namespace OpenSim.Capabilities.Handlers
|
||||||
{
|
{
|
||||||
public class XBakesConnector : ServiceConnector
|
public class UploadBakedTextureServerConnector : ServiceConnector
|
||||||
{
|
{
|
||||||
private IBakedTextureService m_BakesService;
|
private IAssetService m_AssetService;
|
||||||
private string m_ConfigName = "BakedTextureService";
|
private string m_ConfigName = "CapsService";
|
||||||
|
|
||||||
public XBakesConnector(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)
|
if (configName != String.Empty)
|
||||||
|
@ -50,20 +50,27 @@ namespace OpenSim.Server.Handlers.BakedTextures
|
||||||
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 assetService = serverConfig.GetString("LocalServiceModule",
|
string assetService = serverConfig.GetString("AssetService", String.Empty);
|
||||||
String.Empty);
|
|
||||||
|
|
||||||
if (assetService == String.Empty)
|
if (assetService == String.Empty)
|
||||||
throw new Exception("No BakedTextureService in config file");
|
throw new Exception("No AssetService in config file");
|
||||||
|
|
||||||
Object[] args = new Object[] { config };
|
Object[] args = new Object[] { config };
|
||||||
m_BakesService =
|
m_AssetService =
|
||||||
ServerUtils.LoadPlugin<IBakedTextureService>(assetService, args);
|
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 BakesServerGetHandler(m_BakesService, auth));
|
// NEED TO FIX THIS
|
||||||
server.AddStreamHandler(new BakesServerPostHandler(m_BakesService, auth));
|
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"));
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,438 @@
|
||||||
|
/*
|
||||||
|
* 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 WebFetchInvDescHandler
|
||||||
|
{
|
||||||
|
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 WebFetchInvDescHandler(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)
|
||||||
|
{
|
||||||
|
contents = m_InventoryService.GetFolderContent(agentID, folderID);
|
||||||
|
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,22 +29,19 @@ 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
|
||||||
{
|
{
|
||||||
public class FetchInvDescServerConnector : ServiceConnector
|
public class WebFetchInvDescServerConnector : ServiceConnector
|
||||||
{
|
{
|
||||||
private IInventoryService m_InventoryService;
|
private IInventoryService m_InventoryService;
|
||||||
private ILibraryService m_LibraryService;
|
private ILibraryService m_LibraryService;
|
||||||
private string m_ConfigName = "CapsService";
|
private string m_ConfigName = "CapsService";
|
||||||
|
|
||||||
public FetchInvDescServerConnector(IConfigSource config, IHttpServer server, string configName) :
|
public WebFetchInvDescServerConnector(IConfigSource config, IHttpServer server, string configName) :
|
||||||
base(config, server, configName)
|
base(config, server, configName)
|
||||||
{
|
{
|
||||||
if (configName != String.Empty)
|
if (configName != String.Empty)
|
||||||
|
@ -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);
|
WebFetchInvDescHandler webFetchHandler = new WebFetchInvDescHandler(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);
|
"WebFetchInvDesc",
|
||||||
});
|
null);
|
||||||
|
server.AddStreamHandler(reqHandler);
|
||||||
server.AddSimpleStreamHandler(reqHandler);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -68,10 +68,7 @@ namespace OpenSim.Framework.Capabilities
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static object LLSDDeserialize(byte[] b)
|
public static object LLSDDeserialize(byte[] b)
|
||||||
{
|
{
|
||||||
using (MemoryStream ms = new MemoryStream(b, false))
|
return LLSDDeserialize(new MemoryStream(b, false));
|
||||||
{
|
|
||||||
return LLSDDeserialize(ms);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -81,23 +78,21 @@ namespace OpenSim.Framework.Capabilities
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static object LLSDDeserialize(Stream st)
|
public static object LLSDDeserialize(Stream st)
|
||||||
{
|
{
|
||||||
using (XmlTextReader reader = new XmlTextReader(st))
|
XmlTextReader reader = new XmlTextReader(st);
|
||||||
{
|
reader.Read();
|
||||||
reader.Read();
|
SkipWS(reader);
|
||||||
SkipWS(reader);
|
|
||||||
|
|
||||||
if (reader.NodeType != XmlNodeType.Element || reader.LocalName != "llsd")
|
if (reader.NodeType != XmlNodeType.Element || reader.LocalName != "llsd")
|
||||||
throw new LLSDParseException("Expected <llsd>");
|
throw new LLSDParseException("Expected <llsd>");
|
||||||
|
|
||||||
reader.Read();
|
reader.Read();
|
||||||
object ret = LLSDParseOne(reader);
|
object ret = LLSDParseOne(reader);
|
||||||
SkipWS(reader);
|
SkipWS(reader);
|
||||||
|
|
||||||
if (reader.NodeType != XmlNodeType.EndElement || reader.LocalName != "llsd")
|
if (reader.NodeType != XmlNodeType.EndElement || reader.LocalName != "llsd")
|
||||||
throw new LLSDParseException("Expected </llsd>");
|
throw new LLSDParseException("Expected </llsd>");
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -107,17 +102,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 +561,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,15 +25,17 @@
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using OpenMetaverse;
|
||||||
|
|
||||||
namespace Robust32
|
namespace OpenSim.Framework.Capabilities
|
||||||
{
|
{
|
||||||
class Program
|
[OSDMap]
|
||||||
|
public class LLSDItemUpdate
|
||||||
{
|
{
|
||||||
static void Main(string[] args)
|
public UUID item_id;
|
||||||
|
|
||||||
|
public LLSDItemUpdate()
|
||||||
{
|
{
|
||||||
global::OpenSim.Server.OpenSimServer.Main(args);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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,8 +37,9 @@ 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 bool[] AssetsExist(UUID[] uuids);
|
public abstract void StoreAsset(AssetBase asset);
|
||||||
|
public abstract bool ExistsAsset(UUID uuid);
|
||||||
|
|
||||||
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,8 +34,8 @@ 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 ExistsAsset(UUID uuid);
|
||||||
List<AssetMetadata> FetchAssetMetadataSet(int start, int count);
|
List<AssetMetadata> FetchAssetMetadataSet(int start, int count);
|
||||||
void Initialise(string connect);
|
void Initialise(string connect);
|
||||||
bool Delete(string id);
|
bool Delete(string id);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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.
|
||||||
*
|
*
|
||||||
|
@ -34,12 +34,11 @@ namespace OpenSim.Data
|
||||||
public class OfflineIMData
|
public class OfflineIMData
|
||||||
{
|
{
|
||||||
public UUID PrincipalID;
|
public UUID PrincipalID;
|
||||||
public UUID FromID;
|
|
||||||
public Dictionary<string, string> Data;
|
public Dictionary<string, string> 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,8 +48,6 @@ 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 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);
|
||||||
OSDArray GetUserImageAssets(UUID avatarId);
|
OSDArray GetUserImageAssets(UUID avatarId);
|
||||||
|
|
|
@ -52,14 +52,14 @@ namespace OpenSim.Data
|
||||||
public int sizeY;
|
public int sizeY;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Return the x-coordinate of this region in region units.
|
/// Return the x-coordinate of this region.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int coordX { get { return (int)Util.WorldToRegionLoc((uint)posX); } }
|
public int coordX { get { return posX / (int)Constants.RegionSize; } }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Return the y-coordinate of this region in region units.
|
/// Return the y-coordinate of this region.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int coordY { get { return (int)Util.WorldToRegionLoc((uint)posY); } }
|
public int coordY { get { return posY / (int)Constants.RegionSize; } }
|
||||||
|
|
||||||
public Dictionary<string, object> Data;
|
public Dictionary<string, object> Data;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -83,7 +81,6 @@ namespace OpenSim.Data
|
||||||
bool Delete(UUID regionID);
|
bool Delete(UUID regionID);
|
||||||
|
|
||||||
List<RegionData> GetDefaultRegions(UUID scopeID);
|
List<RegionData> GetDefaultRegions(UUID scopeID);
|
||||||
List<RegionData> GetDefaultHypergridRegions(UUID scopeID);
|
|
||||||
List<RegionData> GetFallbackRegions(UUID scopeID, int x, int y);
|
List<RegionData> GetFallbackRegions(UUID scopeID, int x, int y);
|
||||||
List<RegionData> GetHyperlinks(UUID scopeID);
|
List<RegionData> GetHyperlinks(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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ namespace OpenSim.Data
|
||||||
{
|
{
|
||||||
AssetBase GetAsset(UUID uuid);
|
AssetBase GetAsset(UUID uuid);
|
||||||
void StoreAsset(AssetBase asset);
|
void StoreAsset(AssetBase asset);
|
||||||
bool[] AssetsExist(UUID[] uuids);
|
bool ExistsAsset(UUID uuid);
|
||||||
List<AssetMetadata> FetchAssetMetadataSet(int start, int count);
|
List<AssetMetadata> FetchAssetMetadataSet(int start, int count);
|
||||||
void Initialise(string connect);
|
void Initialise(string connect);
|
||||||
bool Delete(string id);
|
bool Delete(string id);
|
||||||
|
|
|
@ -38,67 +38,19 @@ 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;
|
||||||
|
|
||||||
public Dictionary<UUID, XGroupMember> members = new Dictionary<UUID, XGroupMember>();
|
|
||||||
public Dictionary<UUID, XGroupNotice> notices = new Dictionary<UUID, XGroupNotice>();
|
|
||||||
|
|
||||||
public XGroup Clone()
|
public XGroup Clone()
|
||||||
{
|
{
|
||||||
XGroup clone = (XGroup)MemberwiseClone();
|
return (XGroup)MemberwiseClone();
|
||||||
clone.members = new Dictionary<UUID, XGroupMember>();
|
|
||||||
clone.notices = new Dictionary<UUID, XGroupNotice>();
|
|
||||||
|
|
||||||
foreach (KeyValuePair<UUID, XGroupMember> kvp in members)
|
|
||||||
clone.members[kvp.Key] = kvp.Value.Clone();
|
|
||||||
|
|
||||||
foreach (KeyValuePair<UUID, XGroupNotice> kvp in notices)
|
|
||||||
clone.notices[kvp.Key] = kvp.Value.Clone();
|
|
||||||
|
|
||||||
return clone;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class XGroupMember
|
|
||||||
{
|
|
||||||
public UUID agentID;
|
|
||||||
public UUID groupID;
|
|
||||||
public UUID roleID;
|
|
||||||
public bool acceptNotices = true;
|
|
||||||
public bool listInProfile = true;
|
|
||||||
|
|
||||||
public XGroupMember Clone()
|
|
||||||
{
|
|
||||||
return (XGroupMember)MemberwiseClone();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class XGroupNotice
|
|
||||||
{
|
|
||||||
public UUID groupID;
|
|
||||||
public UUID noticeID;
|
|
||||||
public uint timestamp;
|
|
||||||
public string fromName;
|
|
||||||
public string subject;
|
|
||||||
public string message;
|
|
||||||
public byte[] binaryBucket;
|
|
||||||
public bool hasAttachment;
|
|
||||||
public int assetType;
|
|
||||||
|
|
||||||
public XGroupNotice Clone()
|
|
||||||
{
|
|
||||||
XGroupNotice clone = (XGroupNotice)MemberwiseClone();
|
|
||||||
clone.binaryBucket = (byte[])binaryBucket.Clone();
|
|
||||||
|
|
||||||
return clone;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,13 +58,14 @@ namespace OpenSim.Data
|
||||||
/// Early stub interface for groups data, not final.
|
/// Early stub interface for groups data, not final.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// Currently in-use only for regression test purposes.
|
/// Currently in-use only for regression test purposes. Needs to be filled out over time.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public interface IXGroupData
|
public interface IXGroupData
|
||||||
{
|
{
|
||||||
bool StoreGroup(XGroup group);
|
bool StoreGroup(XGroup group);
|
||||||
XGroup GetGroup(UUID groupID);
|
XGroup[] GetGroups(string field, string val);
|
||||||
Dictionary<UUID, XGroup> GetGroups();
|
XGroup[] GetGroups(string[] fields, string[] vals);
|
||||||
bool DeleteGroup(UUID groupID);
|
bool DeleteGroups(string field, string val);
|
||||||
|
bool DeleteGroups(string[] fields, string[] vals);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -27,20 +27,19 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
|
using System.Data.SqlClient;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
using log4net;
|
using log4net;
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
using Npgsql;
|
|
||||||
using NpgsqlTypes;
|
|
||||||
|
|
||||||
namespace OpenSim.Data.PGSQL
|
namespace OpenSim.Data.MSSQL
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A PGSQL Interface for the Asset server
|
/// A MSSQL Interface for the Asset server
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class PGSQLAssetData : AssetDataBase
|
public class MSSQLAssetData : AssetDataBase
|
||||||
{
|
{
|
||||||
private const string _migrationStore = "AssetStore";
|
private const string _migrationStore = "AssetStore";
|
||||||
|
|
||||||
|
@ -49,14 +48,9 @@ namespace OpenSim.Data.PGSQL
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Database manager
|
/// Database manager
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private PGSQLManager m_database;
|
private MSSQLManager m_database;
|
||||||
private string m_connectionString;
|
private string m_connectionString;
|
||||||
|
|
||||||
protected virtual Assembly Assembly
|
|
||||||
{
|
|
||||||
get { return GetType().Assembly; }
|
|
||||||
}
|
|
||||||
|
|
||||||
#region IPlugin Members
|
#region IPlugin Members
|
||||||
|
|
||||||
override public void Dispose() { }
|
override public void Dispose() { }
|
||||||
|
@ -67,7 +61,7 @@ namespace OpenSim.Data.PGSQL
|
||||||
// [Obsolete("Cannot be default-initialized!")]
|
// [Obsolete("Cannot be default-initialized!")]
|
||||||
override public void Initialise()
|
override public void Initialise()
|
||||||
{
|
{
|
||||||
m_log.Info("[PGSQLAssetData]: " + Name + " cannot be default-initialized!");
|
m_log.Info("[MSSQLAssetData]: " + Name + " cannot be default-initialized!");
|
||||||
throw new PluginNotInitialisedException(Name);
|
throw new PluginNotInitialisedException(Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,7 +76,7 @@ namespace OpenSim.Data.PGSQL
|
||||||
{
|
{
|
||||||
m_ticksToEpoch = new System.DateTime(1970, 1, 1).Ticks;
|
m_ticksToEpoch = new System.DateTime(1970, 1, 1).Ticks;
|
||||||
|
|
||||||
m_database = new PGSQLManager(connectionString);
|
m_database = new MSSQLManager(connectionString);
|
||||||
m_connectionString = connectionString;
|
m_connectionString = connectionString;
|
||||||
|
|
||||||
//New migration to check for DB changes
|
//New migration to check for DB changes
|
||||||
|
@ -102,7 +96,7 @@ namespace OpenSim.Data.PGSQL
|
||||||
/// </summary>
|
/// </summary>
|
||||||
override public string Name
|
override public string Name
|
||||||
{
|
{
|
||||||
get { return "PGSQL Asset storage engine"; }
|
get { return "MSSQL Asset storage engine"; }
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -116,13 +110,13 @@ namespace OpenSim.Data.PGSQL
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
override public AssetBase GetAsset(UUID assetID)
|
override public AssetBase GetAsset(UUID assetID)
|
||||||
{
|
{
|
||||||
string sql = "SELECT * FROM assets WHERE id = :id";
|
string sql = "SELECT * FROM assets WHERE id = @id";
|
||||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||||
{
|
{
|
||||||
cmd.Parameters.Add(m_database.CreateParameter("id", assetID));
|
cmd.Parameters.Add(m_database.CreateParameter("id", assetID));
|
||||||
conn.Open();
|
conn.Open();
|
||||||
using (NpgsqlDataReader reader = cmd.ExecuteReader())
|
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||||
{
|
{
|
||||||
if (reader.Read())
|
if (reader.Read())
|
||||||
{
|
{
|
||||||
|
@ -149,42 +143,42 @@ namespace OpenSim.Data.PGSQL
|
||||||
/// Create asset in m_database
|
/// Create asset in m_database
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="asset">the asset</param>
|
/// <param name="asset">the asset</param>
|
||||||
override public bool StoreAsset(AssetBase asset)
|
override public void StoreAsset(AssetBase asset)
|
||||||
{
|
{
|
||||||
|
|
||||||
string sql =
|
string sql =
|
||||||
@"UPDATE assets set name = :name, description = :description, " + "\"assetType\" " + @" = :assetType,
|
@"IF EXISTS(SELECT * FROM assets WHERE id=@id)
|
||||||
local = :local, temporary = :temporary, creatorid = :creatorid, data = :data
|
UPDATE assets set name = @name, description = @description, assetType = @assetType,
|
||||||
WHERE id=:id;
|
local = @local, temporary = @temporary, creatorid = @creatorid, data = @data
|
||||||
|
WHERE id=@id
|
||||||
INSERT INTO assets
|
ELSE
|
||||||
(id, name, description, " + "\"assetType\" " + @", local,
|
INSERT INTO assets
|
||||||
temporary, create_time, access_time, creatorid, asset_flags, data)
|
([id], [name], [description], [assetType], [local],
|
||||||
Select :id, :name, :description, :assetType, :local,
|
[temporary], [create_time], [access_time], [creatorid], [asset_flags], [data])
|
||||||
:temporary, :create_time, :access_time, :creatorid, :asset_flags, :data
|
VALUES
|
||||||
Where not EXISTS(SELECT * FROM assets WHERE id=:id)
|
(@id, @name, @description, @assetType, @local,
|
||||||
";
|
@temporary, @create_time, @access_time, @creatorid, @asset_flags, @data)";
|
||||||
|
|
||||||
string assetName = asset.Name;
|
string assetName = asset.Name;
|
||||||
if (asset.Name.Length > AssetBase.MAX_ASSET_NAME)
|
if (asset.Name.Length > 64)
|
||||||
{
|
{
|
||||||
assetName = asset.Name.Substring(0, AssetBase.MAX_ASSET_NAME);
|
assetName = asset.Name.Substring(0, 64);
|
||||||
m_log.WarnFormat(
|
m_log.WarnFormat(
|
||||||
"[ASSET DB]: Name '{0}' for asset {1} truncated from {2} to {3} characters on add",
|
"[ASSET DB]: Name '{0}' for asset {1} truncated from {2} to {3} characters on add",
|
||||||
asset.Name, asset.ID, asset.Name.Length, assetName.Length);
|
asset.Name, asset.ID, asset.Name.Length, assetName.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
string assetDescription = asset.Description;
|
string assetDescription = asset.Description;
|
||||||
if (asset.Description.Length > AssetBase.MAX_ASSET_DESC)
|
if (asset.Description.Length > 64)
|
||||||
{
|
{
|
||||||
assetDescription = asset.Description.Substring(0, AssetBase.MAX_ASSET_DESC);
|
assetDescription = asset.Description.Substring(0, 64);
|
||||||
m_log.WarnFormat(
|
m_log.WarnFormat(
|
||||||
"[ASSET DB]: Description '{0}' for asset {1} truncated from {2} to {3} characters on add",
|
"[ASSET DB]: Description '{0}' for asset {1} truncated from {2} to {3} characters on add",
|
||||||
asset.Description, asset.ID, asset.Description.Length, assetDescription.Length);
|
asset.Description, asset.ID, asset.Description.Length, assetDescription.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||||
using (NpgsqlCommand command = new NpgsqlCommand(sql, conn))
|
using (SqlCommand command = new SqlCommand(sql, conn))
|
||||||
{
|
{
|
||||||
int now = (int)((System.DateTime.Now.Ticks - m_ticksToEpoch) / 10000000);
|
int now = (int)((System.DateTime.Now.Ticks - m_ticksToEpoch) / 10000000);
|
||||||
command.Parameters.Add(m_database.CreateParameter("id", asset.FullID));
|
command.Parameters.Add(m_database.CreateParameter("id", asset.FullID));
|
||||||
|
@ -205,21 +199,20 @@ namespace OpenSim.Data.PGSQL
|
||||||
}
|
}
|
||||||
catch(Exception e)
|
catch(Exception e)
|
||||||
{
|
{
|
||||||
m_log.Error("[ASSET DB]: Error storing item :" + e.Message + " sql "+sql);
|
m_log.Error("[ASSET DB]: Error storing item :" + e.Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Commented out since currently unused - this probably should be called in GetAsset()
|
// Commented out since currently unused - this probably should be called in GetAsset()
|
||||||
// private void UpdateAccessTime(AssetBase asset)
|
// private void UpdateAccessTime(AssetBase asset)
|
||||||
// {
|
// {
|
||||||
// using (AutoClosingSqlCommand cmd = m_database.Query("UPDATE assets SET access_time = :access_time WHERE id=:id"))
|
// using (AutoClosingSqlCommand cmd = m_database.Query("UPDATE assets SET access_time = @access_time WHERE id=@id"))
|
||||||
// {
|
// {
|
||||||
// int now = (int)((System.DateTime.Now.Ticks - m_ticksToEpoch) / 10000000);
|
// int now = (int)((System.DateTime.Now.Ticks - m_ticksToEpoch) / 10000000);
|
||||||
// cmd.Parameters.AddWithValue(":id", asset.FullID.ToString());
|
// cmd.Parameters.AddWithValue("@id", asset.FullID.ToString());
|
||||||
// cmd.Parameters.AddWithValue(":access_time", now);
|
// cmd.Parameters.AddWithValue("@access_time", now);
|
||||||
// try
|
// try
|
||||||
// {
|
// {
|
||||||
// cmd.ExecuteNonQuery();
|
// cmd.ExecuteNonQuery();
|
||||||
|
@ -232,38 +225,17 @@ namespace OpenSim.Data.PGSQL
|
||||||
// }
|
// }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Check if the assets exist in the database.
|
/// Check if asset exist in m_database
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="uuids">The assets' IDs</param>
|
/// <param name="uuid"></param>
|
||||||
/// <returns>For each asset: true if it exists, false otherwise</returns>
|
/// <returns>true if exist.</returns>
|
||||||
public override bool[] AssetsExist(UUID[] uuids)
|
override public bool ExistsAsset(UUID uuid)
|
||||||
{
|
{
|
||||||
if (uuids.Length == 0)
|
if (GetAsset(uuid) != null)
|
||||||
return new bool[0];
|
|
||||||
|
|
||||||
HashSet<UUID> exist = new HashSet<UUID>();
|
|
||||||
|
|
||||||
string ids = "'" + string.Join("','", uuids) + "'";
|
|
||||||
string sql = string.Format("SELECT id FROM assets WHERE id IN ({0})", ids);
|
|
||||||
|
|
||||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
|
||||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
|
||||||
{
|
{
|
||||||
conn.Open();
|
return true;
|
||||||
using (NpgsqlDataReader reader = cmd.ExecuteReader())
|
|
||||||
{
|
|
||||||
while (reader.Read())
|
|
||||||
{
|
|
||||||
UUID id = DBGuid.FromDB(reader["id"]);
|
|
||||||
exist.Add(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
bool[] results = new bool[uuids.Length];
|
|
||||||
for (int i = 0; i < uuids.Length; i++)
|
|
||||||
results[i] = exist.Contains(uuids[i]);
|
|
||||||
return results;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -277,19 +249,23 @@ namespace OpenSim.Data.PGSQL
|
||||||
public override List<AssetMetadata> FetchAssetMetadataSet(int start, int count)
|
public override List<AssetMetadata> FetchAssetMetadataSet(int start, int count)
|
||||||
{
|
{
|
||||||
List<AssetMetadata> retList = new List<AssetMetadata>(count);
|
List<AssetMetadata> retList = new List<AssetMetadata>(count);
|
||||||
string sql = @" SELECT id, name, description, " + "\"assetType\"" + @", temporary, creatorid
|
string sql = @"WITH OrderedAssets AS
|
||||||
FROM assets
|
(
|
||||||
order by id
|
SELECT id, name, description, assetType, temporary, creatorid,
|
||||||
limit :stop
|
RowNumber = ROW_NUMBER() OVER (ORDER BY id)
|
||||||
offset :start;";
|
FROM assets
|
||||||
|
)
|
||||||
|
SELECT *
|
||||||
|
FROM OrderedAssets
|
||||||
|
WHERE RowNumber BETWEEN @start AND @stop;";
|
||||||
|
|
||||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||||
{
|
{
|
||||||
cmd.Parameters.Add(m_database.CreateParameter("start", start));
|
cmd.Parameters.Add(m_database.CreateParameter("start", start));
|
||||||
cmd.Parameters.Add(m_database.CreateParameter("stop", start + count - 1));
|
cmd.Parameters.Add(m_database.CreateParameter("stop", start + count - 1));
|
||||||
conn.Open();
|
conn.Open();
|
||||||
using (NpgsqlDataReader reader = cmd.ExecuteReader())
|
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||||
{
|
{
|
||||||
while (reader.Read())
|
while (reader.Read())
|
||||||
{
|
{
|
|
@ -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.
|
||||||
*
|
*
|
||||||
|
@ -28,38 +28,32 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Data;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
|
using System.Data.SqlClient;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Data;
|
|
||||||
using Npgsql;
|
|
||||||
using NpgsqlTypes;
|
|
||||||
|
|
||||||
namespace OpenSim.Data.PGSQL
|
namespace OpenSim.Data.MSSQL
|
||||||
{
|
{
|
||||||
public class PGSQLAuthenticationData : IAuthenticationData
|
public class MSSQLAuthenticationData : IAuthenticationData
|
||||||
{
|
{
|
||||||
private string m_Realm;
|
private string m_Realm;
|
||||||
private List<string> m_ColumnNames = null;
|
private List<string> m_ColumnNames = null;
|
||||||
private int m_LastExpire = 0;
|
private int m_LastExpire = 0;
|
||||||
private string m_ConnectionString;
|
private string m_ConnectionString;
|
||||||
private PGSQLManager m_database;
|
private MSSQLManager m_database;
|
||||||
|
|
||||||
protected virtual Assembly Assembly
|
public MSSQLAuthenticationData(string connectionString, string realm)
|
||||||
{
|
|
||||||
get { return GetType().Assembly; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public PGSQLAuthenticationData(string connectionString, string realm)
|
|
||||||
{
|
{
|
||||||
m_Realm = realm;
|
m_Realm = realm;
|
||||||
m_ConnectionString = connectionString;
|
m_ConnectionString = connectionString;
|
||||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString))
|
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||||
{
|
{
|
||||||
conn.Open();
|
conn.Open();
|
||||||
Migration m = new Migration(conn, GetType().Assembly, "AuthStore");
|
Migration m = new Migration(conn, GetType().Assembly, "AuthStore");
|
||||||
m_database = new PGSQLManager(m_ConnectionString);
|
m_database = new MSSQLManager(m_ConnectionString);
|
||||||
m.Update();
|
m.Update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -69,14 +63,14 @@ namespace OpenSim.Data.PGSQL
|
||||||
AuthenticationData ret = new AuthenticationData();
|
AuthenticationData ret = new AuthenticationData();
|
||||||
ret.Data = new Dictionary<string, object>();
|
ret.Data = new Dictionary<string, object>();
|
||||||
|
|
||||||
string sql = string.Format("select * from {0} where uuid = :principalID", m_Realm);
|
string sql = string.Format("select * from {0} where UUID = @principalID", m_Realm);
|
||||||
|
|
||||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString))
|
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||||
{
|
{
|
||||||
cmd.Parameters.Add(m_database.CreateParameter("principalID", principalID));
|
cmd.Parameters.Add(m_database.CreateParameter("@principalID", principalID));
|
||||||
conn.Open();
|
conn.Open();
|
||||||
using (NpgsqlDataReader result = cmd.ExecuteReader())
|
using (SqlDataReader result = cmd.ExecuteReader())
|
||||||
{
|
{
|
||||||
if (result.Read())
|
if (result.Read())
|
||||||
{
|
{
|
||||||
|
@ -93,7 +87,7 @@ namespace OpenSim.Data.PGSQL
|
||||||
|
|
||||||
foreach (string s in m_ColumnNames)
|
foreach (string s in m_ColumnNames)
|
||||||
{
|
{
|
||||||
if (s == "UUID"||s == "uuid")
|
if (s == "UUID")
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ret.Data[s] = result[s].ToString();
|
ret.Data[s] = result[s].ToString();
|
||||||
|
@ -109,31 +103,12 @@ namespace OpenSim.Data.PGSQL
|
||||||
{
|
{
|
||||||
if (data.Data.ContainsKey("UUID"))
|
if (data.Data.ContainsKey("UUID"))
|
||||||
data.Data.Remove("UUID");
|
data.Data.Remove("UUID");
|
||||||
if (data.Data.ContainsKey("uuid"))
|
|
||||||
data.Data.Remove("uuid");
|
|
||||||
|
|
||||||
/*
|
|
||||||
Dictionary<string, object> oAuth = new Dictionary<string, object>();
|
|
||||||
|
|
||||||
foreach (KeyValuePair<string, object> oDado in data.Data)
|
|
||||||
{
|
|
||||||
if (oDado.Key != oDado.Key.ToLower())
|
|
||||||
{
|
|
||||||
oAuth.Add(oDado.Key.ToLower(), oDado.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
foreach (KeyValuePair<string, object> oDado in data.Data)
|
|
||||||
{
|
|
||||||
if (!oAuth.ContainsKey(oDado.Key.ToLower())) {
|
|
||||||
oAuth.Add(oDado.Key.ToLower(), oDado.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
string[] fields = new List<string>(data.Data.Keys).ToArray();
|
string[] fields = new List<string>(data.Data.Keys).ToArray();
|
||||||
StringBuilder updateBuilder = new StringBuilder();
|
StringBuilder updateBuilder = new StringBuilder();
|
||||||
|
|
||||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString))
|
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||||
using (NpgsqlCommand cmd = new NpgsqlCommand())
|
using (SqlCommand cmd = new SqlCommand())
|
||||||
{
|
{
|
||||||
updateBuilder.AppendFormat("update {0} set ", m_Realm);
|
updateBuilder.AppendFormat("update {0} set ", m_Realm);
|
||||||
|
|
||||||
|
@ -142,28 +117,27 @@ namespace OpenSim.Data.PGSQL
|
||||||
{
|
{
|
||||||
if (!first)
|
if (!first)
|
||||||
updateBuilder.Append(", ");
|
updateBuilder.Append(", ");
|
||||||
updateBuilder.AppendFormat("\"{0}\" = :{0}",field);
|
updateBuilder.AppendFormat("{0} = @{0}",field);
|
||||||
|
|
||||||
first = false;
|
first = false;
|
||||||
|
cmd.Parameters.Add(m_database.CreateParameter("@" + field, data.Data[field]));
|
||||||
cmd.Parameters.Add(m_database.CreateParameter("" + field, data.Data[field]));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
updateBuilder.Append(" where uuid = :principalID");
|
updateBuilder.Append(" where UUID = @principalID");
|
||||||
|
|
||||||
cmd.CommandText = updateBuilder.ToString();
|
cmd.CommandText = updateBuilder.ToString();
|
||||||
cmd.Connection = conn;
|
cmd.Connection = conn;
|
||||||
cmd.Parameters.Add(m_database.CreateParameter("principalID", data.PrincipalID));
|
cmd.Parameters.Add(m_database.CreateParameter("@principalID", data.PrincipalID));
|
||||||
|
|
||||||
conn.Open();
|
conn.Open();
|
||||||
if (cmd.ExecuteNonQuery() < 1)
|
if (cmd.ExecuteNonQuery() < 1)
|
||||||
{
|
{
|
||||||
StringBuilder insertBuilder = new StringBuilder();
|
StringBuilder insertBuilder = new StringBuilder();
|
||||||
|
|
||||||
insertBuilder.AppendFormat("insert into {0} (uuid, \"", m_Realm);
|
insertBuilder.AppendFormat("insert into {0} (UUID, ", m_Realm);
|
||||||
insertBuilder.Append(String.Join("\", \"", fields));
|
insertBuilder.Append(String.Join(", ", fields));
|
||||||
insertBuilder.Append("\") values (:principalID, :");
|
insertBuilder.Append(") values (@principalID, @");
|
||||||
insertBuilder.Append(String.Join(", :", fields));
|
insertBuilder.Append(String.Join(", @", fields));
|
||||||
insertBuilder.Append(")");
|
insertBuilder.Append(")");
|
||||||
|
|
||||||
cmd.CommandText = insertBuilder.ToString();
|
cmd.CommandText = insertBuilder.ToString();
|
||||||
|
@ -179,11 +153,11 @@ namespace OpenSim.Data.PGSQL
|
||||||
|
|
||||||
public bool SetDataItem(UUID principalID, string item, string value)
|
public bool SetDataItem(UUID principalID, string item, string value)
|
||||||
{
|
{
|
||||||
string sql = string.Format("update {0} set {1} = :{1} where uuid = :UUID", m_Realm, item);
|
string sql = string.Format("update {0} set {1} = @{1} where UUID = @UUID", m_Realm, item);
|
||||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString))
|
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||||
{
|
{
|
||||||
cmd.Parameters.Add(m_database.CreateParameter("" + item, value));
|
cmd.Parameters.Add(m_database.CreateParameter("@" + item, value));
|
||||||
conn.Open();
|
conn.Open();
|
||||||
if (cmd.ExecuteNonQuery() > 0)
|
if (cmd.ExecuteNonQuery() > 0)
|
||||||
return true;
|
return true;
|
||||||
|
@ -195,14 +169,14 @@ namespace OpenSim.Data.PGSQL
|
||||||
{
|
{
|
||||||
if (System.Environment.TickCount - m_LastExpire > 30000)
|
if (System.Environment.TickCount - m_LastExpire > 30000)
|
||||||
DoExpire();
|
DoExpire();
|
||||||
|
|
||||||
string sql = "insert into tokens (uuid, token, validity) values (:principalID, :token, :lifetime)";
|
string sql = "insert into tokens (UUID, token, validity) values (@principalID, @token, @lifetime)";
|
||||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString))
|
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||||
{
|
{
|
||||||
cmd.Parameters.Add(m_database.CreateParameter("principalID", principalID));
|
cmd.Parameters.Add(m_database.CreateParameter("@principalID", principalID));
|
||||||
cmd.Parameters.Add(m_database.CreateParameter("token", token));
|
cmd.Parameters.Add(m_database.CreateParameter("@token", token));
|
||||||
cmd.Parameters.Add(m_database.CreateParameter("lifetime", DateTime.Now.AddMinutes(lifetime)));
|
cmd.Parameters.Add(m_database.CreateParameter("@lifetime", DateTime.Now.AddMinutes(lifetime)));
|
||||||
conn.Open();
|
conn.Open();
|
||||||
|
|
||||||
if (cmd.ExecuteNonQuery() > 0)
|
if (cmd.ExecuteNonQuery() > 0)
|
||||||
|
@ -219,14 +193,13 @@ namespace OpenSim.Data.PGSQL
|
||||||
DoExpire();
|
DoExpire();
|
||||||
|
|
||||||
DateTime validDate = DateTime.Now.AddMinutes(lifetime);
|
DateTime validDate = DateTime.Now.AddMinutes(lifetime);
|
||||||
string sql = "update tokens set validity = :validDate where uuid = :principalID and token = :token and validity > (CURRENT_DATE + CURRENT_TIME)";
|
string sql = "update tokens set validity = @validDate where UUID = @principalID and token = @token and validity > GetDate()";
|
||||||
|
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString))
|
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
|
||||||
{
|
{
|
||||||
cmd.Parameters.Add(m_database.CreateParameter("principalID", principalID));
|
cmd.Parameters.Add(m_database.CreateParameter("@principalID", principalID));
|
||||||
cmd.Parameters.Add(m_database.CreateParameter("token", token));
|
cmd.Parameters.Add(m_database.CreateParameter("@token", token));
|
||||||
cmd.Parameters.Add(m_database.CreateParameter("validDate", validDate));
|
cmd.Parameters.Add(m_database.CreateParameter("@validDate", validDate));
|
||||||
conn.Open();
|
conn.Open();
|
||||||
|
|
||||||
if (cmd.ExecuteNonQuery() > 0)
|
if (cmd.ExecuteNonQuery() > 0)
|
||||||
|
@ -240,12 +213,12 @@ namespace OpenSim.Data.PGSQL
|
||||||
private void DoExpire()
|
private void DoExpire()
|
||||||
{
|
{
|
||||||
DateTime currentDateTime = DateTime.Now;
|
DateTime currentDateTime = DateTime.Now;
|
||||||
string sql = "delete from tokens where validity < :currentDateTime";
|
string sql = "delete from tokens where validity < @currentDateTime";
|
||||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString))
|
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||||
{
|
{
|
||||||
conn.Open();
|
conn.Open();
|
||||||
cmd.Parameters.Add(m_database.CreateParameter("currentDateTime", currentDateTime));
|
cmd.Parameters.Add(m_database.CreateParameter("@currentDateTime", currentDateTime));
|
||||||
cmd.ExecuteNonQuery();
|
cmd.ExecuteNonQuery();
|
||||||
}
|
}
|
||||||
m_LastExpire = System.Environment.TickCount;
|
m_LastExpire = System.Environment.TickCount;
|
|
@ -27,39 +27,38 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Data;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using log4net;
|
using log4net;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
using Npgsql;
|
using System.Data.SqlClient;
|
||||||
using NpgsqlTypes;
|
|
||||||
|
|
||||||
|
namespace OpenSim.Data.MSSQL
|
||||||
namespace OpenSim.Data.PGSQL
|
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A PGSQL Interface for Avatar Storage
|
/// A MSSQL Interface for Avatar Storage
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class PGSQLAvatarData : PGSQLGenericTableHandler<AvatarBaseData>,
|
public class MSSQLAvatarData : MSSQLGenericTableHandler<AvatarBaseData>,
|
||||||
IAvatarData
|
IAvatarData
|
||||||
{
|
{
|
||||||
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
public PGSQLAvatarData(string connectionString, string realm) :
|
public MSSQLAvatarData(string connectionString, string realm) :
|
||||||
base(connectionString, realm, "Avatar")
|
base(connectionString, realm, "Avatar")
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Delete(UUID principalID, string name)
|
public bool Delete(UUID principalID, string name)
|
||||||
{
|
{
|
||||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString))
|
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||||
using (NpgsqlCommand cmd = new NpgsqlCommand())
|
using (SqlCommand cmd = new SqlCommand())
|
||||||
{
|
{
|
||||||
|
|
||||||
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.Add(m_database.CreateParameter("PrincipalID", principalID));
|
cmd.Parameters.Add(m_database.CreateParameter("@PrincipalID", principalID.ToString()));
|
||||||
cmd.Parameters.Add(m_database.CreateParameter("Name", name));
|
cmd.Parameters.Add(m_database.CreateParameter("@Name", name));
|
||||||
cmd.Connection = conn;
|
cmd.Connection = conn;
|
||||||
conn.Open();
|
conn.Open();
|
||||||
if (cmd.ExecuteNonQuery() > 0)
|
if (cmd.ExecuteNonQuery() > 0)
|
|
@ -27,44 +27,38 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Data;
|
||||||
|
using System.Data.SqlClient;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using log4net;
|
using log4net;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
using OpenSim.Region.Framework.Interfaces;
|
||||||
using System.Data;
|
|
||||||
using Npgsql;
|
|
||||||
using NpgsqlTypes;
|
|
||||||
|
|
||||||
namespace OpenSim.Data.PGSQL
|
namespace OpenSim.Data.MSSQL
|
||||||
{
|
{
|
||||||
public class PGSQLEstateStore : IEstateDataStore
|
public class MSSQLEstateStore : IEstateDataStore
|
||||||
{
|
{
|
||||||
private const string _migrationStore = "EstateStore";
|
private const string _migrationStore = "EstateStore";
|
||||||
|
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
private PGSQLManager _Database;
|
private MSSQLManager _Database;
|
||||||
private string m_connectionString;
|
private string m_connectionString;
|
||||||
private FieldInfo[] _Fields;
|
private FieldInfo[] _Fields;
|
||||||
private Dictionary<string, FieldInfo> _FieldMap = new Dictionary<string, FieldInfo>();
|
private Dictionary<string, FieldInfo> _FieldMap = new Dictionary<string, FieldInfo>();
|
||||||
|
|
||||||
#region Public methods
|
#region Public methods
|
||||||
|
|
||||||
public PGSQLEstateStore()
|
public MSSQLEstateStore()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public PGSQLEstateStore(string connectionString)
|
public MSSQLEstateStore(string connectionString)
|
||||||
{
|
{
|
||||||
Initialise(connectionString);
|
Initialise(connectionString);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual Assembly Assembly
|
|
||||||
{
|
|
||||||
get { return GetType().Assembly; }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initialises the estatedata class.
|
/// Initialises the estatedata class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -74,11 +68,11 @@ namespace OpenSim.Data.PGSQL
|
||||||
if (!string.IsNullOrEmpty(connectionString))
|
if (!string.IsNullOrEmpty(connectionString))
|
||||||
{
|
{
|
||||||
m_connectionString = connectionString;
|
m_connectionString = connectionString;
|
||||||
_Database = new PGSQLManager(connectionString);
|
_Database = new MSSQLManager(connectionString);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Migration settings
|
//Migration settings
|
||||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||||
{
|
{
|
||||||
conn.Open();
|
conn.Open();
|
||||||
Migration m = new Migration(conn, GetType().Assembly, "EstateStore");
|
Migration m = new Migration(conn, GetType().Assembly, "EstateStore");
|
||||||
|
@ -107,17 +101,15 @@ namespace OpenSim.Data.PGSQL
|
||||||
{
|
{
|
||||||
EstateSettings es = new EstateSettings();
|
EstateSettings es = new EstateSettings();
|
||||||
|
|
||||||
string sql = "select estate_settings.\"" + String.Join("\",estate_settings.\"", FieldList) +
|
string sql = "select estate_settings." + String.Join(",estate_settings.", FieldList) + " from estate_map left join estate_settings on estate_map.EstateID = estate_settings.EstateID where estate_settings.EstateID is not null and RegionID = @RegionID";
|
||||||
"\" from estate_map left join estate_settings on estate_map.\"EstateID\" = estate_settings.\"EstateID\" " +
|
|
||||||
" where estate_settings.\"EstateID\" is not null and \"RegionID\" = :RegionID";
|
|
||||||
|
|
||||||
bool insertEstate = false;
|
bool insertEstate = false;
|
||||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||||
{
|
{
|
||||||
cmd.Parameters.Add(_Database.CreateParameter("RegionID", regionID));
|
cmd.Parameters.Add(_Database.CreateParameter("@RegionID", regionID));
|
||||||
conn.Open();
|
conn.Open();
|
||||||
using (NpgsqlDataReader reader = cmd.ExecuteReader())
|
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||||
{
|
{
|
||||||
if (reader.Read())
|
if (reader.Read())
|
||||||
{
|
{
|
||||||
|
@ -127,15 +119,11 @@ namespace OpenSim.Data.PGSQL
|
||||||
object v = reader[name];
|
object v = reader[name];
|
||||||
if (f.FieldType == typeof(bool))
|
if (f.FieldType == typeof(bool))
|
||||||
{
|
{
|
||||||
f.SetValue(es, v);
|
f.SetValue(es, Convert.ToInt32(v) != 0);
|
||||||
}
|
}
|
||||||
else if (f.FieldType == typeof(UUID))
|
else if (f.FieldType == typeof(UUID))
|
||||||
{
|
{
|
||||||
UUID estUUID = UUID.Zero;
|
f.SetValue(es, new UUID((Guid)v)); // uuid);
|
||||||
|
|
||||||
UUID.TryParse(v.ToString(), out estUUID);
|
|
||||||
|
|
||||||
f.SetValue(es, estUUID);
|
|
||||||
}
|
}
|
||||||
else if (f.FieldType == typeof(string))
|
else if (f.FieldType == typeof(string))
|
||||||
{
|
{
|
||||||
|
@ -199,37 +187,25 @@ namespace OpenSim.Data.PGSQL
|
||||||
|
|
||||||
names.Remove("EstateID");
|
names.Remove("EstateID");
|
||||||
|
|
||||||
string sql = string.Format("insert into estate_settings (\"{0}\") values ( :{1} )", String.Join("\",\"", names.ToArray()), String.Join(", :", names.ToArray()));
|
string sql = string.Format("insert into estate_settings ({0}) values ( @{1})", String.Join(",", names.ToArray()), String.Join(", @", names.ToArray()));
|
||||||
|
|
||||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
//_Log.Debug("[DB ESTATE]: SQL: " + sql);
|
||||||
using (NpgsqlCommand insertCommand = new NpgsqlCommand(sql, conn))
|
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||||
|
using (SqlCommand insertCommand = new SqlCommand(sql, conn))
|
||||||
{
|
{
|
||||||
insertCommand.CommandText = sql;
|
insertCommand.CommandText = sql + " SET @ID = SCOPE_IDENTITY()";
|
||||||
|
|
||||||
foreach (string name in names)
|
foreach (string name in names)
|
||||||
{
|
{
|
||||||
insertCommand.Parameters.Add(_Database.CreateParameter("" + name, _FieldMap[name].GetValue(es)));
|
insertCommand.Parameters.Add(_Database.CreateParameter("@" + name, _FieldMap[name].GetValue(es)));
|
||||||
}
|
}
|
||||||
//NpgsqlParameter idParameter = new NpgsqlParameter("ID", SqlDbType.Int);
|
SqlParameter idParameter = new SqlParameter("@ID", SqlDbType.Int);
|
||||||
//idParameter.Direction = ParameterDirection.Output;
|
idParameter.Direction = ParameterDirection.Output;
|
||||||
//insertCommand.Parameters.Add(idParameter);
|
insertCommand.Parameters.Add(idParameter);
|
||||||
conn.Open();
|
conn.Open();
|
||||||
|
insertCommand.ExecuteNonQuery();
|
||||||
|
|
||||||
es.EstateID = 100;
|
es.EstateID = Convert.ToUInt32(idParameter.Value);
|
||||||
|
|
||||||
if (insertCommand.ExecuteNonQuery() > 0)
|
|
||||||
{
|
|
||||||
insertCommand.CommandText = "Select cast(lastval() as int) as ID ;";
|
|
||||||
|
|
||||||
using (NpgsqlDataReader result = insertCommand.ExecuteReader())
|
|
||||||
{
|
|
||||||
if (result.Read())
|
|
||||||
{
|
|
||||||
es.EstateID = (uint)result.GetInt32(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO check if this is needed??
|
//TODO check if this is needed??
|
||||||
|
@ -249,20 +225,20 @@ namespace OpenSim.Data.PGSQL
|
||||||
string sql = string.Format("UPDATE estate_settings SET ");
|
string sql = string.Format("UPDATE estate_settings SET ");
|
||||||
foreach (string name in names)
|
foreach (string name in names)
|
||||||
{
|
{
|
||||||
sql += "\"" + name + "\" = :" + name + ", ";
|
sql += name + " = @" + name + ", ";
|
||||||
}
|
}
|
||||||
sql = sql.Remove(sql.LastIndexOf(","));
|
sql = sql.Remove(sql.LastIndexOf(","));
|
||||||
sql += " WHERE \"EstateID\" = :EstateID";
|
sql += " WHERE EstateID = @EstateID";
|
||||||
|
|
||||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||||
{
|
{
|
||||||
foreach (string name in names)
|
foreach (string name in names)
|
||||||
{
|
{
|
||||||
cmd.Parameters.Add(_Database.CreateParameter("" + name, _FieldMap[name].GetValue(es)));
|
cmd.Parameters.Add(_Database.CreateParameter("@" + name, _FieldMap[name].GetValue(es)));
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.Parameters.Add(_Database.CreateParameter("EstateID", es.EstateID));
|
cmd.Parameters.Add(_Database.CreateParameter("@EstateID", es.EstateID));
|
||||||
conn.Open();
|
conn.Open();
|
||||||
cmd.ExecuteNonQuery();
|
cmd.ExecuteNonQuery();
|
||||||
}
|
}
|
||||||
|
@ -286,24 +262,22 @@ namespace OpenSim.Data.PGSQL
|
||||||
{
|
{
|
||||||
es.ClearBans();
|
es.ClearBans();
|
||||||
|
|
||||||
string sql = "select * from estateban where \"EstateID\" = :EstateID";
|
string sql = "select bannedUUID from estateban where EstateID = @EstateID";
|
||||||
|
|
||||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||||
{
|
{
|
||||||
NpgsqlParameter idParameter = new NpgsqlParameter("EstateID", DbType.Int32);
|
SqlParameter idParameter = new SqlParameter("@EstateID", SqlDbType.Int);
|
||||||
idParameter.Value = es.EstateID;
|
idParameter.Value = es.EstateID;
|
||||||
cmd.Parameters.Add(idParameter);
|
cmd.Parameters.Add(idParameter);
|
||||||
conn.Open();
|
conn.Open();
|
||||||
using (NpgsqlDataReader reader = cmd.ExecuteReader())
|
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||||
{
|
{
|
||||||
while (reader.Read())
|
while (reader.Read())
|
||||||
{
|
{
|
||||||
EstateBan eb = new EstateBan();
|
EstateBan eb = new EstateBan();
|
||||||
|
|
||||||
eb.BannedUserID = new UUID((Guid)reader["bannedUUID"]); //uuid;
|
eb.BannedUserID = new UUID((Guid)reader["bannedUUID"]); //uuid;
|
||||||
eb.BanningUserID = new UUID((Guid)reader["banningUUID"]); //uuid;
|
|
||||||
eb.BanTime = Convert.ToInt32(reader["banTime"]);
|
|
||||||
eb.BannedHostAddress = "0.0.0.0";
|
eb.BannedHostAddress = "0.0.0.0";
|
||||||
eb.BannedHostIPMask = "0.0.0.0";
|
eb.BannedHostIPMask = "0.0.0.0";
|
||||||
es.AddBan(eb);
|
es.AddBan(eb);
|
||||||
|
@ -316,14 +290,14 @@ namespace OpenSim.Data.PGSQL
|
||||||
{
|
{
|
||||||
List<UUID> uuids = new List<UUID>();
|
List<UUID> uuids = new List<UUID>();
|
||||||
|
|
||||||
string sql = string.Format("select uuid from {0} where \"EstateID\" = :EstateID", table);
|
string sql = string.Format("select uuid from {0} where EstateID = @EstateID", table);
|
||||||
|
|
||||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||||
{
|
{
|
||||||
cmd.Parameters.Add(_Database.CreateParameter("EstateID", estateID));
|
cmd.Parameters.Add(_Database.CreateParameter("@EstateID", estateID));
|
||||||
conn.Open();
|
conn.Open();
|
||||||
using (NpgsqlDataReader reader = cmd.ExecuteReader())
|
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||||
{
|
{
|
||||||
while (reader.Read())
|
while (reader.Read())
|
||||||
{
|
{
|
||||||
|
@ -338,25 +312,21 @@ namespace OpenSim.Data.PGSQL
|
||||||
private void SaveBanList(EstateSettings es)
|
private void SaveBanList(EstateSettings es)
|
||||||
{
|
{
|
||||||
//Delete first
|
//Delete first
|
||||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||||
{
|
{
|
||||||
conn.Open();
|
conn.Open();
|
||||||
using (NpgsqlCommand cmd = conn.CreateCommand())
|
using (SqlCommand cmd = conn.CreateCommand())
|
||||||
{
|
{
|
||||||
cmd.CommandText = "delete from estateban where \"EstateID\" = :EstateID";
|
cmd.CommandText = "delete from estateban where EstateID = @EstateID";
|
||||||
cmd.Parameters.AddWithValue("EstateID", (int)es.EstateID);
|
cmd.Parameters.AddWithValue("@EstateID", (int)es.EstateID);
|
||||||
cmd.ExecuteNonQuery();
|
cmd.ExecuteNonQuery();
|
||||||
|
|
||||||
//Insert after
|
//Insert after
|
||||||
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, '','','' )";
|
||||||
cmd.Parameters.AddWithValue("bannedUUID", Guid.Empty);
|
cmd.Parameters.AddWithValue("@bannedUUID", Guid.Empty);
|
||||||
foreach (EstateBan b in es.EstateBans)
|
foreach (EstateBan b in es.EstateBans)
|
||||||
{
|
{
|
||||||
cmd.Parameters["EstateID"].Value = b.EstateID;
|
cmd.Parameters["@bannedUUID"].Value = b.BannedUserID.Guid;
|
||||||
cmd.Parameters["bannedUUID"].Value = b.BannedUserID.Guid;
|
|
||||||
cmd.Parameters["banningUUID"].Value = b.BanningUserID.Guid;
|
|
||||||
cmd.Parameters["banTime"].Value = b.BanTime;
|
|
||||||
|
|
||||||
cmd.ExecuteNonQuery();
|
cmd.ExecuteNonQuery();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -365,20 +335,20 @@ namespace OpenSim.Data.PGSQL
|
||||||
|
|
||||||
private void SaveUUIDList(uint estateID, string table, UUID[] data)
|
private void SaveUUIDList(uint estateID, string table, UUID[] data)
|
||||||
{
|
{
|
||||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||||
{
|
{
|
||||||
conn.Open();
|
conn.Open();
|
||||||
using (NpgsqlCommand cmd = conn.CreateCommand())
|
using (SqlCommand cmd = conn.CreateCommand())
|
||||||
{
|
{
|
||||||
cmd.Parameters.AddWithValue("EstateID", (int)estateID);
|
cmd.Parameters.AddWithValue("@EstateID", (int)estateID);
|
||||||
cmd.CommandText = string.Format("delete from {0} where \"EstateID\" = :EstateID", table);
|
cmd.CommandText = string.Format("delete from {0} where EstateID = @EstateID", table);
|
||||||
cmd.ExecuteNonQuery();
|
cmd.ExecuteNonQuery();
|
||||||
|
|
||||||
cmd.CommandText = string.Format("insert into {0} (\"EstateID\", uuid) values ( :EstateID, :uuid )", table);
|
cmd.CommandText = string.Format("insert into {0} (EstateID, uuid) values ( @EstateID, @uuid )", table);
|
||||||
cmd.Parameters.AddWithValue("uuid", Guid.Empty);
|
cmd.Parameters.AddWithValue("@uuid", Guid.Empty);
|
||||||
foreach (UUID uuid in data)
|
foreach (UUID uuid in data)
|
||||||
{
|
{
|
||||||
cmd.Parameters["uuid"].Value = uuid.Guid; //.ToString(); //TODO check if this works
|
cmd.Parameters["@uuid"].Value = uuid.Guid; //.ToString(); //TODO check if this works
|
||||||
cmd.ExecuteNonQuery();
|
cmd.ExecuteNonQuery();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -388,14 +358,14 @@ namespace OpenSim.Data.PGSQL
|
||||||
public EstateSettings LoadEstateSettings(int estateID)
|
public EstateSettings LoadEstateSettings(int estateID)
|
||||||
{
|
{
|
||||||
EstateSettings es = new EstateSettings();
|
EstateSettings es = new EstateSettings();
|
||||||
string sql = "select estate_settings.\"" + String.Join("\",estate_settings.\"", FieldList) + "\" from estate_settings where \"EstateID\" = :EstateID";
|
string sql = "select estate_settings." + String.Join(",estate_settings.", FieldList) + " from estate_settings where EstateID = @EstateID";
|
||||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||||
{
|
{
|
||||||
conn.Open();
|
conn.Open();
|
||||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||||
{
|
{
|
||||||
cmd.Parameters.AddWithValue("EstateID", (int)estateID);
|
cmd.Parameters.AddWithValue("@EstateID", (int)estateID);
|
||||||
using (NpgsqlDataReader reader = cmd.ExecuteReader())
|
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||||
{
|
{
|
||||||
if (reader.Read())
|
if (reader.Read())
|
||||||
{
|
{
|
||||||
|
@ -458,13 +428,13 @@ namespace OpenSim.Data.PGSQL
|
||||||
public List<int> GetEstates(string search)
|
public List<int> GetEstates(string search)
|
||||||
{
|
{
|
||||||
List<int> result = new List<int>();
|
List<int> result = new List<int>();
|
||||||
string sql = "select \"EstateID\" from estate_settings where lower(\"EstateName\") = lower(:EstateName)";
|
string sql = "select estateID from estate_settings where EstateName = @EstateName";
|
||||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||||
{
|
{
|
||||||
conn.Open();
|
conn.Open();
|
||||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||||
{
|
{
|
||||||
cmd.Parameters.AddWithValue("EstateName", search);
|
cmd.Parameters.AddWithValue("@EstateName", search);
|
||||||
|
|
||||||
using (IDataReader reader = cmd.ExecuteReader())
|
using (IDataReader reader = cmd.ExecuteReader())
|
||||||
{
|
{
|
||||||
|
@ -483,11 +453,11 @@ namespace OpenSim.Data.PGSQL
|
||||||
public List<int> GetEstatesAll()
|
public List<int> GetEstatesAll()
|
||||||
{
|
{
|
||||||
List<int> result = new List<int>();
|
List<int> result = new List<int>();
|
||||||
string sql = "select \"EstateID\" from estate_settings";
|
string sql = "select estateID from estate_settings";
|
||||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||||
{
|
{
|
||||||
conn.Open();
|
conn.Open();
|
||||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||||
{
|
{
|
||||||
using (IDataReader reader = cmd.ExecuteReader())
|
using (IDataReader reader = cmd.ExecuteReader())
|
||||||
{
|
{
|
||||||
|
@ -506,13 +476,13 @@ namespace OpenSim.Data.PGSQL
|
||||||
public List<int> GetEstatesByOwner(UUID ownerID)
|
public List<int> GetEstatesByOwner(UUID ownerID)
|
||||||
{
|
{
|
||||||
List<int> result = new List<int>();
|
List<int> result = new List<int>();
|
||||||
string sql = "select \"EstateID\" from estate_settings where \"EstateOwner\" = :EstateOwner";
|
string sql = "select estateID from estate_settings where EstateOwner = @EstateOwner";
|
||||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||||
{
|
{
|
||||||
conn.Open();
|
conn.Open();
|
||||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||||
{
|
{
|
||||||
cmd.Parameters.AddWithValue("EstateOwner", ownerID);
|
cmd.Parameters.AddWithValue("@EstateOwner", ownerID);
|
||||||
|
|
||||||
using (IDataReader reader = cmd.ExecuteReader())
|
using (IDataReader reader = cmd.ExecuteReader())
|
||||||
{
|
{
|
||||||
|
@ -530,29 +500,28 @@ namespace OpenSim.Data.PGSQL
|
||||||
|
|
||||||
public bool LinkRegion(UUID regionID, int estateID)
|
public bool LinkRegion(UUID regionID, int estateID)
|
||||||
{
|
{
|
||||||
string deleteSQL = "delete from estate_map where \"RegionID\" = :RegionID";
|
string deleteSQL = "delete from estate_map where RegionID = @RegionID";
|
||||||
string insertSQL = "insert into estate_map values (:RegionID, :EstateID)";
|
string insertSQL = "insert into estate_map values (@RegionID, @EstateID)";
|
||||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||||
{
|
{
|
||||||
conn.Open();
|
conn.Open();
|
||||||
|
SqlTransaction transaction = conn.BeginTransaction();
|
||||||
NpgsqlTransaction transaction = conn.BeginTransaction();
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using (NpgsqlCommand cmd = new NpgsqlCommand(deleteSQL, conn))
|
using (SqlCommand cmd = new SqlCommand(deleteSQL, conn))
|
||||||
{
|
{
|
||||||
cmd.Transaction = transaction;
|
cmd.Transaction = transaction;
|
||||||
cmd.Parameters.AddWithValue("RegionID", regionID.Guid);
|
cmd.Parameters.AddWithValue("@RegionID", regionID.Guid);
|
||||||
|
|
||||||
cmd.ExecuteNonQuery();
|
cmd.ExecuteNonQuery();
|
||||||
}
|
}
|
||||||
|
|
||||||
using (NpgsqlCommand cmd = new NpgsqlCommand(insertSQL, conn))
|
using (SqlCommand cmd = new SqlCommand(insertSQL, conn))
|
||||||
{
|
{
|
||||||
cmd.Transaction = transaction;
|
cmd.Transaction = transaction;
|
||||||
cmd.Parameters.AddWithValue("RegionID", regionID.Guid);
|
cmd.Parameters.AddWithValue("@RegionID", regionID.Guid);
|
||||||
cmd.Parameters.AddWithValue("EstateID", estateID);
|
cmd.Parameters.AddWithValue("@EstateID", estateID);
|
||||||
|
|
||||||
int ret = cmd.ExecuteNonQuery();
|
int ret = cmd.ExecuteNonQuery();
|
||||||
|
|
||||||
|
@ -576,13 +545,13 @@ namespace OpenSim.Data.PGSQL
|
||||||
public List<UUID> GetRegions(int estateID)
|
public List<UUID> GetRegions(int estateID)
|
||||||
{
|
{
|
||||||
List<UUID> result = new List<UUID>();
|
List<UUID> result = new List<UUID>();
|
||||||
string sql = "select \"RegionID\" from estate_map where \"EstateID\" = :EstateID";
|
string sql = "select RegionID from estate_map where EstateID = @EstateID";
|
||||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||||
{
|
{
|
||||||
conn.Open();
|
conn.Open();
|
||||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||||
{
|
{
|
||||||
cmd.Parameters.AddWithValue("EstateID", estateID);
|
cmd.Parameters.AddWithValue("@EstateID", estateID);
|
||||||
|
|
||||||
using (IDataReader reader = cmd.ExecuteReader())
|
using (IDataReader reader = cmd.ExecuteReader())
|
||||||
{
|
{
|
||||||
|
@ -600,7 +569,7 @@ namespace OpenSim.Data.PGSQL
|
||||||
|
|
||||||
public bool DeleteEstate(int estateID)
|
public bool DeleteEstate(int estateID)
|
||||||
{
|
{
|
||||||
// TODO: Implementation!
|
// TODO: Implementation!
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
|
@ -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.
|
||||||
*
|
*
|
||||||
|
@ -31,18 +31,18 @@ using System.Collections.Generic;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
|
using System.Data.SqlClient;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Npgsql;
|
|
||||||
|
|
||||||
namespace OpenSim.Data.PGSQL
|
namespace OpenSim.Data.MSSQL
|
||||||
{
|
{
|
||||||
public class PGSQLFriendsData : PGSQLGenericTableHandler<FriendsData>, IFriendsData
|
public class MSSQLFriendsData : MSSQLGenericTableHandler<FriendsData>, IFriendsData
|
||||||
{
|
{
|
||||||
public PGSQLFriendsData(string connectionString, string realm)
|
public MSSQLFriendsData(string connectionString, string realm)
|
||||||
: base(connectionString, realm, "FriendsStore")
|
: base(connectionString, realm, "FriendsStore")
|
||||||
{
|
{
|
||||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString))
|
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||||
{
|
{
|
||||||
conn.Open();
|
conn.Open();
|
||||||
Migration m = new Migration(conn, GetType().Assembly, "FriendsStore");
|
Migration m = new Migration(conn, GetType().Assembly, "FriendsStore");
|
||||||
|
@ -50,27 +50,19 @@ namespace OpenSim.Data.PGSQL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public override bool Delete(string principalID, string friend)
|
|
||||||
{
|
|
||||||
UUID princUUID = UUID.Zero;
|
|
||||||
|
|
||||||
bool ret = UUID.TryParse(principalID, out princUUID);
|
|
||||||
|
|
||||||
if (ret)
|
|
||||||
return Delete(princUUID, friend);
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Delete(UUID principalID, string friend)
|
public bool Delete(UUID principalID, string friend)
|
||||||
{
|
{
|
||||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString))
|
return Delete(principalID.ToString(), friend);
|
||||||
using (NpgsqlCommand cmd = new NpgsqlCommand())
|
}
|
||||||
|
|
||||||
|
public bool Delete(string principalID, string friend)
|
||||||
|
{
|
||||||
|
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||||
|
using (SqlCommand cmd = new SqlCommand())
|
||||||
{
|
{
|
||||||
cmd.CommandText = String.Format("delete from {0} where \"PrincipalID\" = :PrincipalID and \"Friend\" = :Friend", m_Realm);
|
cmd.CommandText = String.Format("delete from {0} where PrincipalID = @PrincipalID and Friend = @Friend", m_Realm);
|
||||||
cmd.Parameters.Add(m_database.CreateParameter("PrincipalID", principalID.ToString()));
|
cmd.Parameters.Add(m_database.CreateParameter("@PrincipalID", principalID.ToString()));
|
||||||
cmd.Parameters.Add(m_database.CreateParameter("Friend", friend));
|
cmd.Parameters.Add(m_database.CreateParameter("@Friend", friend));
|
||||||
cmd.Connection = conn;
|
cmd.Connection = conn;
|
||||||
conn.Open();
|
conn.Open();
|
||||||
cmd.ExecuteNonQuery();
|
cmd.ExecuteNonQuery();
|
||||||
|
@ -79,28 +71,19 @@ namespace OpenSim.Data.PGSQL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public FriendsData[] GetFriends(string principalID)
|
|
||||||
{
|
|
||||||
UUID princUUID = UUID.Zero;
|
|
||||||
|
|
||||||
bool ret = UUID.TryParse(principalID, out princUUID);
|
|
||||||
|
|
||||||
if (ret)
|
|
||||||
return GetFriends(princUUID);
|
|
||||||
else
|
|
||||||
return new FriendsData[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
public FriendsData[] GetFriends(UUID principalID)
|
public FriendsData[] GetFriends(UUID principalID)
|
||||||
{
|
{
|
||||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString))
|
return GetFriends(principalID.ToString());
|
||||||
using (NpgsqlCommand cmd = new NpgsqlCommand())
|
}
|
||||||
|
|
||||||
|
public FriendsData[] GetFriends(string principalID)
|
||||||
|
{
|
||||||
|
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||||
|
using (SqlCommand cmd = new SqlCommand())
|
||||||
{
|
{
|
||||||
|
|
||||||
cmd.CommandText = String.Format("select a.*,case when b.\"Flags\" is null then '-1' else b.\"Flags\" end as \"TheirFlags\" from {0} as a " +
|
cmd.CommandText = String.Format("select a.*,case when b.Flags is null then -1 else b.Flags end as TheirFlags from {0} as a left join {0} as b on a.PrincipalID = b.Friend and a.Friend = b.PrincipalID where a.PrincipalID = @PrincipalID", m_Realm);
|
||||||
" left join {0} as b on a.\"PrincipalID\" = b.\"Friend\" and a.\"Friend\" = b.\"PrincipalID\" " +
|
cmd.Parameters.Add(m_database.CreateParameter("@PrincipalID", principalID.ToString()));
|
||||||
" where a.\"PrincipalID\" = :PrincipalID", m_Realm);
|
|
||||||
cmd.Parameters.Add(m_database.CreateParameter("PrincipalID", principalID.ToString()));
|
|
||||||
cmd.Connection = conn;
|
cmd.Connection = conn;
|
||||||
conn.Open();
|
conn.Open();
|
||||||
return DoQuery(cmd);
|
return DoQuery(cmd);
|
||||||
|
@ -109,8 +92,8 @@ namespace OpenSim.Data.PGSQL
|
||||||
|
|
||||||
public FriendsData[] GetFriends(Guid principalID)
|
public FriendsData[] GetFriends(Guid principalID)
|
||||||
{
|
{
|
||||||
return GetFriends(principalID);
|
return GetFriends(principalID.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -30,46 +30,38 @@ using System.Collections.Generic;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using log4net;
|
using log4net;
|
||||||
|
using System.Data.SqlClient;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
using OpenSim.Region.Framework.Interfaces;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Npgsql;
|
|
||||||
|
|
||||||
namespace OpenSim.Data.PGSQL
|
namespace OpenSim.Data.MSSQL
|
||||||
{
|
{
|
||||||
public class PGSQLGenericTableHandler<T> : PGSqlFramework where T : class, new()
|
public class MSSQLGenericTableHandler<T> where T : class, new()
|
||||||
{
|
{
|
||||||
private static readonly ILog m_log =
|
// private static readonly ILog m_log =
|
||||||
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
protected string m_ConnectionString;
|
protected string m_ConnectionString;
|
||||||
protected PGSQLManager m_database; //used for parameter type translation
|
protected MSSQLManager m_database; //used for parameter type translation
|
||||||
protected Dictionary<string, FieldInfo> m_Fields =
|
protected Dictionary<string, FieldInfo> m_Fields =
|
||||||
new Dictionary<string, FieldInfo>();
|
new Dictionary<string, FieldInfo>();
|
||||||
|
|
||||||
protected Dictionary<string, string> m_FieldTypes = new Dictionary<string, string>();
|
|
||||||
|
|
||||||
protected List<string> m_ColumnNames = null;
|
protected List<string> m_ColumnNames = null;
|
||||||
protected string m_Realm;
|
protected string m_Realm;
|
||||||
protected FieldInfo m_DataField = null;
|
protected FieldInfo m_DataField = null;
|
||||||
|
|
||||||
protected virtual Assembly Assembly
|
public MSSQLGenericTableHandler(string connectionString,
|
||||||
{
|
|
||||||
get { return GetType().Assembly; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public PGSQLGenericTableHandler(string connectionString,
|
|
||||||
string realm, string storeName)
|
string realm, string storeName)
|
||||||
: base(connectionString)
|
|
||||||
{
|
{
|
||||||
m_Realm = realm;
|
m_Realm = realm;
|
||||||
|
|
||||||
m_ConnectionString = connectionString;
|
m_ConnectionString = connectionString;
|
||||||
|
|
||||||
if (storeName != String.Empty)
|
if (storeName != String.Empty)
|
||||||
{
|
{
|
||||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString))
|
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||||
{
|
{
|
||||||
conn.Open();
|
conn.Open();
|
||||||
Migration m = new Migration(conn, GetType().Assembly, storeName);
|
Migration m = new Migration(conn, GetType().Assembly, storeName);
|
||||||
|
@ -77,15 +69,13 @@ namespace OpenSim.Data.PGSQL
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
m_database = new PGSQLManager(m_ConnectionString);
|
m_database = new MSSQLManager(m_ConnectionString);
|
||||||
|
|
||||||
Type t = typeof(T);
|
Type t = typeof(T);
|
||||||
FieldInfo[] fields = t.GetFields(BindingFlags.Public |
|
FieldInfo[] fields = t.GetFields(BindingFlags.Public |
|
||||||
BindingFlags.Instance |
|
BindingFlags.Instance |
|
||||||
BindingFlags.DeclaredOnly);
|
BindingFlags.DeclaredOnly);
|
||||||
|
|
||||||
LoadFieldTypes();
|
|
||||||
|
|
||||||
if (fields.Length == 0)
|
if (fields.Length == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -99,31 +89,7 @@ namespace OpenSim.Data.PGSQL
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LoadFieldTypes()
|
private void CheckColumnNames(SqlDataReader reader)
|
||||||
{
|
|
||||||
m_FieldTypes = new Dictionary<string, string>();
|
|
||||||
|
|
||||||
string query = string.Format(@"select column_name,data_type
|
|
||||||
from INFORMATION_SCHEMA.COLUMNS
|
|
||||||
where table_name = lower('{0}');
|
|
||||||
|
|
||||||
", m_Realm);
|
|
||||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString))
|
|
||||||
using (NpgsqlCommand cmd = new NpgsqlCommand(query, conn))
|
|
||||||
{
|
|
||||||
conn.Open();
|
|
||||||
using (NpgsqlDataReader rdr = cmd.ExecuteReader())
|
|
||||||
{
|
|
||||||
while (rdr.Read())
|
|
||||||
{
|
|
||||||
// query produces 0 to many rows of single column, so always add the first item in each row
|
|
||||||
m_FieldTypes.Add((string)rdr[0], (string)rdr[1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CheckColumnNames(NpgsqlDataReader reader)
|
|
||||||
{
|
{
|
||||||
if (m_ColumnNames != null)
|
if (m_ColumnNames != null)
|
||||||
return;
|
return;
|
||||||
|
@ -131,7 +97,6 @@ namespace OpenSim.Data.PGSQL
|
||||||
m_ColumnNames = new List<string>();
|
m_ColumnNames = new List<string>();
|
||||||
|
|
||||||
DataTable schemaTable = reader.GetSchemaTable();
|
DataTable schemaTable = reader.GetSchemaTable();
|
||||||
|
|
||||||
foreach (DataRow row in schemaTable.Rows)
|
foreach (DataRow row in schemaTable.Rows)
|
||||||
{
|
{
|
||||||
if (row["ColumnName"] != null &&
|
if (row["ColumnName"] != null &&
|
||||||
|
@ -141,32 +106,21 @@ namespace OpenSim.Data.PGSQL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO GET CONSTRAINTS FROM POSTGRESQL
|
|
||||||
private List<string> GetConstraints()
|
private List<string> GetConstraints()
|
||||||
{
|
{
|
||||||
List<string> constraints = new List<string>();
|
List<string> constraints = new List<string>();
|
||||||
string query = string.Format(@"select
|
string query = string.Format(@"SELECT
|
||||||
a.attname as column_name
|
COL_NAME(ic.object_id,ic.column_id) AS column_name
|
||||||
from
|
FROM sys.indexes AS i
|
||||||
pg_class t,
|
INNER JOIN sys.index_columns AS ic
|
||||||
pg_class i,
|
ON i.object_id = ic.object_id AND i.index_id = ic.index_id
|
||||||
pg_index ix,
|
WHERE i.is_primary_key = 1
|
||||||
pg_attribute a
|
AND i.object_id = OBJECT_ID('{0}');", m_Realm);
|
||||||
where
|
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||||
t.oid = ix.indrelid
|
using (SqlCommand cmd = new SqlCommand(query, conn))
|
||||||
and i.oid = ix.indexrelid
|
|
||||||
and a.attrelid = t.oid
|
|
||||||
and a.attnum = ANY(ix.indkey)
|
|
||||||
and t.relkind = 'r'
|
|
||||||
and ix.indisunique = true
|
|
||||||
and t.relname = lower('{0}')
|
|
||||||
;", m_Realm);
|
|
||||||
|
|
||||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString))
|
|
||||||
using (NpgsqlCommand cmd = new NpgsqlCommand(query, conn))
|
|
||||||
{
|
{
|
||||||
conn.Open();
|
conn.Open();
|
||||||
using (NpgsqlDataReader rdr = cmd.ExecuteReader())
|
using (SqlDataReader rdr = cmd.ExecuteReader())
|
||||||
{
|
{
|
||||||
while (rdr.Read())
|
while (rdr.Read())
|
||||||
{
|
{
|
||||||
|
@ -180,54 +134,7 @@ namespace OpenSim.Data.PGSQL
|
||||||
|
|
||||||
public virtual T[] Get(string field, string key)
|
public virtual T[] Get(string field, string key)
|
||||||
{
|
{
|
||||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString))
|
return Get(new string[] { field }, new string[] { key });
|
||||||
using (NpgsqlCommand cmd = new NpgsqlCommand())
|
|
||||||
{
|
|
||||||
if ( m_FieldTypes.ContainsKey(field) )
|
|
||||||
cmd.Parameters.Add(m_database.CreateParameter(field, key, m_FieldTypes[field]));
|
|
||||||
else
|
|
||||||
cmd.Parameters.Add(m_database.CreateParameter(field, key));
|
|
||||||
|
|
||||||
string query = String.Format("SELECT * FROM {0} WHERE \"{1}\" = :{1}", m_Realm, field, field);
|
|
||||||
|
|
||||||
cmd.Connection = conn;
|
|
||||||
cmd.CommandText = query;
|
|
||||||
conn.Open();
|
|
||||||
return DoQuery(cmd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual T[] Get(string field, string[] keys)
|
|
||||||
{
|
|
||||||
|
|
||||||
int flen = keys.Length;
|
|
||||||
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 (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString))
|
|
||||||
using (NpgsqlCommand cmd = new NpgsqlCommand())
|
|
||||||
{
|
|
||||||
|
|
||||||
for (int i = 0 ; i < flen ; i++)
|
|
||||||
{
|
|
||||||
sb.Append(keys[i]);
|
|
||||||
if(i < flast)
|
|
||||||
sb.Append("','");
|
|
||||||
else
|
|
||||||
sb.Append("')");
|
|
||||||
}
|
|
||||||
|
|
||||||
string query = sb.ToString();
|
|
||||||
|
|
||||||
cmd.Connection = conn;
|
|
||||||
cmd.CommandText = query;
|
|
||||||
conn.Open();
|
|
||||||
return DoQuery(cmd);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual T[] Get(string[] fields, string[] keys)
|
public virtual T[] Get(string[] fields, string[] keys)
|
||||||
|
@ -237,18 +144,14 @@ namespace OpenSim.Data.PGSQL
|
||||||
|
|
||||||
List<string> terms = new List<string>();
|
List<string> terms = new List<string>();
|
||||||
|
|
||||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString))
|
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||||
using (NpgsqlCommand cmd = new NpgsqlCommand())
|
using (SqlCommand cmd = new SqlCommand())
|
||||||
{
|
{
|
||||||
|
|
||||||
for (int i = 0; i < fields.Length; i++)
|
for (int i = 0; i < fields.Length; i++)
|
||||||
{
|
{
|
||||||
if ( m_FieldTypes.ContainsKey(fields[i]) )
|
cmd.Parameters.Add(m_database.CreateParameter(fields[i], keys[i]));
|
||||||
cmd.Parameters.Add(m_database.CreateParameter(fields[i], keys[i], m_FieldTypes[fields[i]]));
|
terms.Add("[" + fields[i] + "] = @" + fields[i]);
|
||||||
else
|
|
||||||
cmd.Parameters.Add(m_database.CreateParameter(fields[i], keys[i]));
|
|
||||||
|
|
||||||
terms.Add(" \"" + fields[i] + "\" = :" + fields[i]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
string where = String.Join(" AND ", terms.ToArray());
|
string where = String.Join(" AND ", terms.ToArray());
|
||||||
|
@ -263,23 +166,15 @@ namespace OpenSim.Data.PGSQL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected T[] DoQuery(NpgsqlCommand cmd)
|
protected T[] DoQuery(SqlCommand cmd)
|
||||||
{
|
{
|
||||||
List<T> result = new List<T>();
|
List<T> result = new List<T>();
|
||||||
if (cmd.Connection == null)
|
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||||
{
|
|
||||||
cmd.Connection = new NpgsqlConnection(m_connectionString);
|
|
||||||
}
|
|
||||||
if (cmd.Connection.State == ConnectionState.Closed)
|
|
||||||
{
|
|
||||||
cmd.Connection.Open();
|
|
||||||
}
|
|
||||||
using (NpgsqlDataReader reader = cmd.ExecuteReader())
|
|
||||||
{
|
{
|
||||||
if (reader == null)
|
if (reader == null)
|
||||||
return new T[0];
|
return new T[0];
|
||||||
|
|
||||||
CheckColumnNames(reader);
|
CheckColumnNames(reader);
|
||||||
|
|
||||||
while (reader.Read())
|
while (reader.Read())
|
||||||
{
|
{
|
||||||
|
@ -318,7 +213,6 @@ namespace OpenSim.Data.PGSQL
|
||||||
foreach (string col in m_ColumnNames)
|
foreach (string col in m_ColumnNames)
|
||||||
{
|
{
|
||||||
data[col] = reader[col].ToString();
|
data[col] = reader[col].ToString();
|
||||||
|
|
||||||
if (data[col] == null)
|
if (data[col] == null)
|
||||||
data[col] = String.Empty;
|
data[col] = String.Empty;
|
||||||
}
|
}
|
||||||
|
@ -334,34 +228,16 @@ namespace OpenSim.Data.PGSQL
|
||||||
|
|
||||||
public virtual T[] Get(string where)
|
public virtual T[] Get(string where)
|
||||||
{
|
{
|
||||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString))
|
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||||
using (NpgsqlCommand cmd = new NpgsqlCommand())
|
using (SqlCommand cmd = new SqlCommand())
|
||||||
{
|
{
|
||||||
|
|
||||||
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.Connection = conn;
|
cmd.Connection = conn;
|
||||||
cmd.CommandText = query;
|
cmd.CommandText = query;
|
||||||
//m_log.WarnFormat("[PGSQLGenericTable]: SELECT {0} WHERE {1}", m_Realm, where);
|
|
||||||
|
|
||||||
conn.Open();
|
//m_log.WarnFormat("[MSSQLGenericTable]: SELECT {0} WHERE {1}", m_Realm, where);
|
||||||
return DoQuery(cmd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual T[] Get(string where, NpgsqlParameter parameter)
|
|
||||||
{
|
|
||||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString))
|
|
||||||
using (NpgsqlCommand cmd = new NpgsqlCommand())
|
|
||||||
{
|
|
||||||
|
|
||||||
string query = String.Format("SELECT * FROM {0} WHERE {1}",
|
|
||||||
m_Realm, where);
|
|
||||||
cmd.Connection = conn;
|
|
||||||
cmd.CommandText = query;
|
|
||||||
//m_log.WarnFormat("[PGSQLGenericTable]: SELECT {0} WHERE {1}", m_Realm, where);
|
|
||||||
|
|
||||||
cmd.Parameters.Add(parameter);
|
|
||||||
|
|
||||||
conn.Open();
|
conn.Open();
|
||||||
return DoQuery(cmd);
|
return DoQuery(cmd);
|
||||||
|
@ -373,8 +249,8 @@ namespace OpenSim.Data.PGSQL
|
||||||
List<string> constraintFields = GetConstraints();
|
List<string> constraintFields = GetConstraints();
|
||||||
List<KeyValuePair<string, string>> constraints = new List<KeyValuePair<string, string>>();
|
List<KeyValuePair<string, string>> constraints = new List<KeyValuePair<string, string>>();
|
||||||
|
|
||||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString))
|
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||||
using (NpgsqlCommand cmd = new NpgsqlCommand())
|
using (SqlCommand cmd = new SqlCommand())
|
||||||
{
|
{
|
||||||
|
|
||||||
StringBuilder query = new StringBuilder();
|
StringBuilder query = new StringBuilder();
|
||||||
|
@ -384,24 +260,21 @@ namespace OpenSim.Data.PGSQL
|
||||||
foreach (FieldInfo fi in m_Fields.Values)
|
foreach (FieldInfo fi in m_Fields.Values)
|
||||||
{
|
{
|
||||||
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(
|
||||||
"[PGSQL GENERIC TABLE HANDLER]: Trying to store field {0} for {1} which is unexpectedly null",
|
"[MSSQL GENERIC TABLE HANDLER]: Trying to store field {0} for {1} which is unexpectedly null",
|
||||||
fi.Name, row));
|
fi.Name, row));
|
||||||
|
|
||||||
if (constraintFields.Count > 0 && constraintFields.Contains(fi.Name))
|
if (constraintFields.Count > 0 && constraintFields.Contains(fi.Name))
|
||||||
{
|
{
|
||||||
constraints.Add(new KeyValuePair<string, string>(fi.Name, fi.GetValue(row).ToString() ));
|
constraints.Add(new KeyValuePair<string, string>(fi.Name, fi.GetValue(row).ToString()));
|
||||||
}
|
}
|
||||||
if (m_FieldTypes.ContainsKey(fi.Name))
|
cmd.Parameters.Add(m_database.CreateParameter(fi.Name, fi.GetValue(row).ToString()));
|
||||||
cmd.Parameters.Add(m_database.CreateParameter(fi.Name, fi.GetValue(row), m_FieldTypes[fi.Name]));
|
|
||||||
else
|
|
||||||
cmd.Parameters.Add(m_database.CreateParameter(fi.Name, fi.GetValue(row)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_DataField != null)
|
if (m_DataField != null)
|
||||||
|
@ -416,12 +289,8 @@ namespace OpenSim.Data.PGSQL
|
||||||
constraints.Add(new KeyValuePair<string, string>(kvp.Key, kvp.Key));
|
constraints.Add(new KeyValuePair<string, string>(kvp.Key, kvp.Key));
|
||||||
}
|
}
|
||||||
names.Add(kvp.Key);
|
names.Add(kvp.Key);
|
||||||
values.Add(":" + kvp.Key);
|
values.Add("@" + kvp.Key);
|
||||||
|
cmd.Parameters.Add(m_database.CreateParameter("@" + kvp.Key, kvp.Value));
|
||||||
if (m_FieldTypes.ContainsKey(kvp.Key))
|
|
||||||
cmd.Parameters.Add(m_database.CreateParameter("" + kvp.Key, kvp.Value, m_FieldTypes[kvp.Key]));
|
|
||||||
else
|
|
||||||
cmd.Parameters.Add(m_database.CreateParameter("" + kvp.Key, kvp.Value));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -430,27 +299,27 @@ namespace OpenSim.Data.PGSQL
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (i = 0; i < names.Count - 1; i++)
|
for (i = 0; i < names.Count - 1; i++)
|
||||||
{
|
{
|
||||||
query.AppendFormat("\"{0}\" = {1}, ", names[i], values[i]);
|
query.AppendFormat("[{0}] = {1}, ", names[i], values[i]);
|
||||||
}
|
}
|
||||||
query.AppendFormat("\"{0}\" = {1} ", names[i], values[i]);
|
query.AppendFormat("[{0}] = {1} ", names[i], values[i]);
|
||||||
if (constraints.Count > 0)
|
if (constraints.Count > 0)
|
||||||
{
|
{
|
||||||
List<string> terms = new List<string>();
|
List<string> terms = new List<string>();
|
||||||
for (int j = 0; j < constraints.Count; j++)
|
for (int j = 0; j < constraints.Count; j++)
|
||||||
{
|
{
|
||||||
terms.Add(String.Format(" \"{0}\" = :{0}", constraints[j].Key));
|
terms.Add(" [" + constraints[j].Key + "] = @" + constraints[j].Key);
|
||||||
}
|
}
|
||||||
string where = String.Join(" AND ", terms.ToArray());
|
string where = String.Join(" AND ", terms.ToArray());
|
||||||
query.AppendFormat(" WHERE {0} ", where);
|
query.AppendFormat(" WHERE {0} ", where);
|
||||||
|
|
||||||
}
|
}
|
||||||
cmd.Connection = conn;
|
cmd.Connection = conn;
|
||||||
cmd.CommandText = query.ToString();
|
cmd.CommandText = query.ToString();
|
||||||
|
|
||||||
conn.Open();
|
conn.Open();
|
||||||
if (cmd.ExecuteNonQuery() > 0)
|
if (cmd.ExecuteNonQuery() > 0)
|
||||||
{
|
{
|
||||||
//m_log.WarnFormat("[PGSQLGenericTable]: Updating {0}", m_Realm);
|
//m_log.WarnFormat("[MSSQLGenericTable]: Updating {0}", m_Realm);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -458,14 +327,12 @@ namespace OpenSim.Data.PGSQL
|
||||||
// assume record has not yet been inserted
|
// assume record has not yet been inserted
|
||||||
|
|
||||||
query = new StringBuilder();
|
query = new StringBuilder();
|
||||||
query.AppendFormat("INSERT INTO {0} (\"", m_Realm);
|
query.AppendFormat("INSERT INTO {0} ([", m_Realm);
|
||||||
query.Append(String.Join("\",\"", names.ToArray()));
|
query.Append(String.Join("],[", names.ToArray()));
|
||||||
query.Append("\") values (" + String.Join(",", values.ToArray()) + ")");
|
query.Append("]) values (" + String.Join(",", values.ToArray()) + ")");
|
||||||
cmd.Connection = conn;
|
cmd.Connection = conn;
|
||||||
cmd.CommandText = query.ToString();
|
cmd.CommandText = query.ToString();
|
||||||
|
//m_log.WarnFormat("[MSSQLGenericTable]: Inserting into {0}", m_Realm);
|
||||||
// m_log.WarnFormat("[PGSQLGenericTable]: Inserting into {0} sql {1}", m_Realm, cmd.CommandText);
|
|
||||||
|
|
||||||
if (conn.State != ConnectionState.Open)
|
if (conn.State != ConnectionState.Open)
|
||||||
conn.Open();
|
conn.Open();
|
||||||
if (cmd.ExecuteNonQuery() > 0)
|
if (cmd.ExecuteNonQuery() > 0)
|
||||||
|
@ -488,17 +355,13 @@ namespace OpenSim.Data.PGSQL
|
||||||
|
|
||||||
List<string> terms = new List<string>();
|
List<string> terms = new List<string>();
|
||||||
|
|
||||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_ConnectionString))
|
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||||
using (NpgsqlCommand cmd = new NpgsqlCommand())
|
using (SqlCommand cmd = new SqlCommand())
|
||||||
{
|
{
|
||||||
for (int i = 0; i < fields.Length; i++)
|
for (int i = 0; i < fields.Length; i++)
|
||||||
{
|
{
|
||||||
if (m_FieldTypes.ContainsKey(fields[i]))
|
cmd.Parameters.Add(m_database.CreateParameter(fields[i], keys[i]));
|
||||||
cmd.Parameters.Add(m_database.CreateParameter(fields[i], keys[i], m_FieldTypes[fields[i]]));
|
terms.Add("[" + fields[i] + "] = @" + fields[i]);
|
||||||
else
|
|
||||||
cmd.Parameters.Add(m_database.CreateParameter(fields[i], keys[i]));
|
|
||||||
|
|
||||||
terms.Add(" \"" + fields[i] + "\" = :" + fields[i]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
string where = String.Join(" AND ", terms.ToArray());
|
string where = String.Join(" AND ", terms.ToArray());
|
||||||
|
@ -511,69 +374,11 @@ namespace OpenSim.Data.PGSQL
|
||||||
|
|
||||||
if (cmd.ExecuteNonQuery() > 0)
|
if (cmd.ExecuteNonQuery() > 0)
|
||||||
{
|
{
|
||||||
//m_log.Warn("[PGSQLGenericTable]: " + deleteCommand);
|
//m_log.Warn("[MSSQLGenericTable]: " + deleteCommand);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public long GetCount(string field, string key)
|
|
||||||
{
|
|
||||||
return GetCount(new string[] { field }, new string[] { key });
|
|
||||||
}
|
|
||||||
|
|
||||||
public long GetCount(string[] fields, string[] keys)
|
|
||||||
{
|
|
||||||
if (fields.Length != keys.Length)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
List<string> terms = new List<string>();
|
|
||||||
|
|
||||||
using (NpgsqlCommand cmd = new NpgsqlCommand())
|
|
||||||
{
|
|
||||||
for (int i = 0; i < fields.Length; i++)
|
|
||||||
{
|
|
||||||
cmd.Parameters.AddWithValue(fields[i], keys[i]);
|
|
||||||
terms.Add("\"" + fields[i] + "\" = :" + fields[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
string where = String.Join(" and ", terms.ToArray());
|
|
||||||
|
|
||||||
string query = String.Format("select count(*) from {0} where {1}",
|
|
||||||
m_Realm, where);
|
|
||||||
|
|
||||||
cmd.CommandText = query;
|
|
||||||
|
|
||||||
Object result = DoQueryScalar(cmd);
|
|
||||||
|
|
||||||
return Convert.ToInt64(result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public long GetCount(string where)
|
|
||||||
{
|
|
||||||
using (NpgsqlCommand cmd = new NpgsqlCommand())
|
|
||||||
{
|
|
||||||
string query = String.Format("select count(*) from {0} where {1}",
|
|
||||||
m_Realm, where);
|
|
||||||
|
|
||||||
cmd.CommandText = query;
|
|
||||||
|
|
||||||
object result = DoQueryScalar(cmd);
|
|
||||||
|
|
||||||
return Convert.ToInt64(result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public object DoQueryScalar(NpgsqlCommand cmd)
|
|
||||||
{
|
|
||||||
using (NpgsqlConnection dbcon = new NpgsqlConnection(m_ConnectionString))
|
|
||||||
{
|
|
||||||
dbcon.Open();
|
|
||||||
cmd.Connection = dbcon;
|
|
||||||
|
|
||||||
return cmd.ExecuteScalar();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -33,18 +33,19 @@ using System.Threading;
|
||||||
using log4net;
|
using log4net;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
|
using System.Data.SqlClient;
|
||||||
|
|
||||||
namespace OpenSim.Data.PGSQL
|
namespace OpenSim.Data.MSSQL
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A PGSQL Interface for Avatar Storage
|
/// A MSSQL Interface for Avatar Storage
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class PGSQLGridUserData : PGSQLGenericTableHandler<GridUserData>,
|
public class MSSQLGridUserData : MSSQLGenericTableHandler<GridUserData>,
|
||||||
IGridUserData
|
IGridUserData
|
||||||
{
|
{
|
||||||
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
public PGSQLGridUserData(string connectionString, string realm) :
|
public MSSQLGridUserData(string connectionString, string realm) :
|
||||||
base(connectionString, realm, "GridUserStore")
|
base(connectionString, realm, "GridUserStore")
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -61,7 +62,7 @@ namespace OpenSim.Data.PGSQL
|
||||||
|
|
||||||
public GridUserData[] GetAll(string userID)
|
public GridUserData[] GetAll(string userID)
|
||||||
{
|
{
|
||||||
return base.Get(String.Format("\"UserID\" LIKE '{0}%'", userID));
|
return base.Get(String.Format("UserID LIKE '{0}%'", userID));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -28,18 +28,18 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
|
using System.Data.SqlClient;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using log4net;
|
using log4net;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
using Npgsql;
|
|
||||||
|
|
||||||
namespace OpenSim.Data.PGSQL
|
namespace OpenSim.Data.MSSQL
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A PGSQL interface for the inventory server
|
/// A MSSQL interface for the inventory server
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class PGSQLInventoryData : IInventoryDataPlugin
|
public class MSSQLInventoryData : IInventoryDataPlugin
|
||||||
{
|
{
|
||||||
private const string _migrationStore = "InventoryStore";
|
private const string _migrationStore = "InventoryStore";
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ namespace OpenSim.Data.PGSQL
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The database manager
|
/// The database manager
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private PGSQLManager database;
|
private MSSQLManager database;
|
||||||
private string m_connectionString;
|
private string m_connectionString;
|
||||||
|
|
||||||
#region IPlugin members
|
#region IPlugin members
|
||||||
|
@ -56,20 +56,20 @@ namespace OpenSim.Data.PGSQL
|
||||||
[Obsolete("Cannot be default-initialized!")]
|
[Obsolete("Cannot be default-initialized!")]
|
||||||
public void Initialise()
|
public void Initialise()
|
||||||
{
|
{
|
||||||
m_log.Info("[PGSQLInventoryData]: " + Name + " cannot be default-initialized!");
|
m_log.Info("[MSSQLInventoryData]: " + Name + " cannot be default-initialized!");
|
||||||
throw new PluginNotInitialisedException(Name);
|
throw new PluginNotInitialisedException(Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Loads and initialises the PGSQL inventory storage interface
|
/// Loads and initialises the MSSQL inventory storage interface
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="connectionString">connect string</param>
|
/// <param name="connectionString">connect string</param>
|
||||||
/// <remarks>use PGSQL_connection.ini</remarks>
|
/// <remarks>use mssql_connection.ini</remarks>
|
||||||
public void Initialise(string connectionString)
|
public void Initialise(string connectionString)
|
||||||
{
|
{
|
||||||
m_connectionString = connectionString;
|
m_connectionString = connectionString;
|
||||||
database = new PGSQLManager(connectionString);
|
database = new MSSQLManager(connectionString);
|
||||||
|
|
||||||
//New migrations check of store
|
//New migrations check of store
|
||||||
database.CheckMigration(_migrationStore);
|
database.CheckMigration(_migrationStore);
|
||||||
}
|
}
|
||||||
|
@ -80,7 +80,7 @@ namespace OpenSim.Data.PGSQL
|
||||||
/// <returns>A string containing the name of the DB provider</returns>
|
/// <returns>A string containing the name of the DB provider</returns>
|
||||||
public string Name
|
public string Name
|
||||||
{
|
{
|
||||||
get { return "PGSQL Inventory Data Interface"; }
|
get { return "MSSQL Inventory Data Interface"; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -158,13 +158,13 @@ namespace OpenSim.Data.PGSQL
|
||||||
/// <returns>A folder class</returns>
|
/// <returns>A folder class</returns>
|
||||||
public InventoryFolderBase getInventoryFolder(UUID folderID)
|
public InventoryFolderBase getInventoryFolder(UUID folderID)
|
||||||
{
|
{
|
||||||
string sql = "SELECT * FROM inventoryfolders WHERE \"folderID\" = :folderID";
|
string sql = "SELECT * FROM inventoryfolders WHERE folderID = @folderID";
|
||||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||||
{
|
{
|
||||||
cmd.Parameters.Add(database.CreateParameter("folderID", folderID));
|
cmd.Parameters.Add(database.CreateParameter("folderID", folderID));
|
||||||
conn.Open();
|
conn.Open();
|
||||||
using (NpgsqlDataReader reader = cmd.ExecuteReader())
|
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||||
{
|
{
|
||||||
if (reader.Read())
|
if (reader.Read())
|
||||||
{
|
{
|
||||||
|
@ -190,8 +190,8 @@ namespace OpenSim.Data.PGSQL
|
||||||
/* NOTE: the implementation below is very inefficient (makes a separate request to get subfolders for
|
/* NOTE: the implementation below is very inefficient (makes a separate request to get subfolders for
|
||||||
* every found folder, recursively). Inventory code for other DBs has been already rewritten to get ALL
|
* every found folder, recursively). Inventory code for other DBs has been already rewritten to get ALL
|
||||||
* inventory for a specific user at once.
|
* inventory for a specific user at once.
|
||||||
*
|
*
|
||||||
* Meanwhile, one little thing is corrected: getFolderHierarchy(UUID.Zero) doesn't make sense and should never
|
* Meanwhile, one little thing is corrected: getFolderHierarchy(UUID.Zero) doesn't make sense and should never
|
||||||
* be used, so check for that and return an empty list.
|
* be used, so check for that and return an empty list.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -200,11 +200,11 @@ namespace OpenSim.Data.PGSQL
|
||||||
if (parentID == UUID.Zero)
|
if (parentID == UUID.Zero)
|
||||||
return folders;
|
return folders;
|
||||||
|
|
||||||
string sql = "SELECT * FROM inventoryfolders WHERE \"parentFolderID\" = :parentID";
|
string sql = "SELECT * FROM inventoryfolders WHERE parentFolderID = @parentID";
|
||||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||||
{
|
{
|
||||||
cmd.Parameters.Add(database.CreateParameter("parentID", parentID));
|
cmd.Parameters.Add(database.CreateParameter("@parentID", parentID));
|
||||||
conn.Open();
|
conn.Open();
|
||||||
folders.AddRange(getInventoryFolders(cmd));
|
folders.AddRange(getInventoryFolders(cmd));
|
||||||
|
|
||||||
|
@ -228,8 +228,8 @@ namespace OpenSim.Data.PGSQL
|
||||||
/// <param name="folder">Folder to create</param>
|
/// <param name="folder">Folder to create</param>
|
||||||
public void addInventoryFolder(InventoryFolderBase folder)
|
public void addInventoryFolder(InventoryFolderBase folder)
|
||||||
{
|
{
|
||||||
string sql = "INSERT INTO inventoryfolders (\"folderID\", \"agentID\", \"parentFolderID\", \"folderName\", type, version) " +
|
string sql = @"INSERT INTO inventoryfolders ([folderID], [agentID], [parentFolderID], [folderName], [type], [version])
|
||||||
" VALUES (:folderID, :agentID, :parentFolderID, :folderName, :type, :version);";
|
VALUES (@folderID, @agentID, @parentFolderID, @folderName, @type, @version);";
|
||||||
|
|
||||||
string folderName = folder.Name;
|
string folderName = folder.Name;
|
||||||
if (folderName.Length > 64)
|
if (folderName.Length > 64)
|
||||||
|
@ -237,8 +237,8 @@ namespace OpenSim.Data.PGSQL
|
||||||
folderName = folderName.Substring(0, 64);
|
folderName = folderName.Substring(0, 64);
|
||||||
m_log.Warn("[INVENTORY DB]: Name field truncated from " + folder.Name.Length.ToString() + " to " + folderName.Length + " characters on add");
|
m_log.Warn("[INVENTORY DB]: Name field truncated from " + folder.Name.Length.ToString() + " to " + folderName.Length + " characters on add");
|
||||||
}
|
}
|
||||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||||
{
|
{
|
||||||
cmd.Parameters.Add(database.CreateParameter("folderID", folder.ID));
|
cmd.Parameters.Add(database.CreateParameter("folderID", folder.ID));
|
||||||
cmd.Parameters.Add(database.CreateParameter("agentID", folder.Owner));
|
cmd.Parameters.Add(database.CreateParameter("agentID", folder.Owner));
|
||||||
|
@ -264,12 +264,12 @@ namespace OpenSim.Data.PGSQL
|
||||||
/// <param name="folder">Folder to update</param>
|
/// <param name="folder">Folder to update</param>
|
||||||
public void updateInventoryFolder(InventoryFolderBase folder)
|
public void updateInventoryFolder(InventoryFolderBase folder)
|
||||||
{
|
{
|
||||||
string sql = @"UPDATE inventoryfolders SET ""agentID"" = :agentID,
|
string sql = @"UPDATE inventoryfolders SET agentID = @agentID,
|
||||||
""parentFolderID"" = :parentFolderID,
|
parentFolderID = @parentFolderID,
|
||||||
""folderName"" = :folderName,
|
folderName = @folderName,
|
||||||
type = :type,
|
type = @type,
|
||||||
version = :version
|
version = @version
|
||||||
WHERE folderID = :folderID";
|
WHERE folderID = @folderID";
|
||||||
|
|
||||||
string folderName = folder.Name;
|
string folderName = folder.Name;
|
||||||
if (folderName.Length > 64)
|
if (folderName.Length > 64)
|
||||||
|
@ -277,8 +277,8 @@ namespace OpenSim.Data.PGSQL
|
||||||
folderName = folderName.Substring(0, 64);
|
folderName = folderName.Substring(0, 64);
|
||||||
m_log.Warn("[INVENTORY DB]: Name field truncated from " + folder.Name.Length.ToString() + " to " + folderName.Length + " characters on update");
|
m_log.Warn("[INVENTORY DB]: Name field truncated from " + folder.Name.Length.ToString() + " to " + folderName.Length + " characters on update");
|
||||||
}
|
}
|
||||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||||
{
|
{
|
||||||
cmd.Parameters.Add(database.CreateParameter("folderID", folder.ID));
|
cmd.Parameters.Add(database.CreateParameter("folderID", folder.ID));
|
||||||
cmd.Parameters.Add(database.CreateParameter("agentID", folder.Owner));
|
cmd.Parameters.Add(database.CreateParameter("agentID", folder.Owner));
|
||||||
|
@ -304,9 +304,9 @@ namespace OpenSim.Data.PGSQL
|
||||||
/// <param name="folder">Folder to update</param>
|
/// <param name="folder">Folder to update</param>
|
||||||
public void moveInventoryFolder(InventoryFolderBase folder)
|
public void moveInventoryFolder(InventoryFolderBase folder)
|
||||||
{
|
{
|
||||||
string sql = @"UPDATE inventoryfolders SET ""parentFolderID"" = :parentFolderID WHERE ""folderID"" = :folderID";
|
string sql = @"UPDATE inventoryfolders SET parentFolderID = @parentFolderID WHERE folderID = @folderID";
|
||||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||||
{
|
{
|
||||||
cmd.Parameters.Add(database.CreateParameter("parentFolderID", folder.ParentID));
|
cmd.Parameters.Add(database.CreateParameter("parentFolderID", folder.ParentID));
|
||||||
cmd.Parameters.Add(database.CreateParameter("folderID", folder.ID));
|
cmd.Parameters.Add(database.CreateParameter("folderID", folder.ID));
|
||||||
|
@ -328,16 +328,16 @@ namespace OpenSim.Data.PGSQL
|
||||||
/// <param name="folderID">Id of folder to delete</param>
|
/// <param name="folderID">Id of folder to delete</param>
|
||||||
public void deleteInventoryFolder(UUID folderID)
|
public void deleteInventoryFolder(UUID folderID)
|
||||||
{
|
{
|
||||||
string sql = @"SELECT * FROM inventoryfolders WHERE ""parentFolderID"" = :parentID";
|
string sql = "SELECT * FROM inventoryfolders WHERE parentFolderID = @parentID";
|
||||||
|
|
||||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||||
{
|
{
|
||||||
List<InventoryFolderBase> subFolders;
|
List<InventoryFolderBase> subFolders;
|
||||||
cmd.Parameters.Add(database.CreateParameter("parentID", UUID.Zero));
|
cmd.Parameters.Add(database.CreateParameter("@parentID", UUID.Zero));
|
||||||
conn.Open();
|
conn.Open();
|
||||||
subFolders = getFolderHierarchy(folderID, cmd);
|
subFolders = getFolderHierarchy(folderID, cmd);
|
||||||
|
|
||||||
|
|
||||||
//Delete all sub-folders
|
//Delete all sub-folders
|
||||||
foreach (InventoryFolderBase f in subFolders)
|
foreach (InventoryFolderBase f in subFolders)
|
||||||
|
@ -363,15 +363,15 @@ namespace OpenSim.Data.PGSQL
|
||||||
/// <returns>A list containing inventory items</returns>
|
/// <returns>A list containing inventory items</returns>
|
||||||
public List<InventoryItemBase> getInventoryInFolder(UUID folderID)
|
public List<InventoryItemBase> getInventoryInFolder(UUID folderID)
|
||||||
{
|
{
|
||||||
string sql = @"SELECT * FROM inventoryitems WHERE ""parentFolderID"" = :parentFolderID";
|
string sql = "SELECT * FROM inventoryitems WHERE parentFolderID = @parentFolderID";
|
||||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||||
{
|
{
|
||||||
cmd.Parameters.Add(database.CreateParameter("parentFolderID", folderID));
|
cmd.Parameters.Add(database.CreateParameter("parentFolderID", folderID));
|
||||||
conn.Open();
|
conn.Open();
|
||||||
List<InventoryItemBase> items = new List<InventoryItemBase>();
|
List<InventoryItemBase> items = new List<InventoryItemBase>();
|
||||||
|
|
||||||
using (NpgsqlDataReader reader = cmd.ExecuteReader())
|
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||||
{
|
{
|
||||||
while (reader.Read())
|
while (reader.Read())
|
||||||
{
|
{
|
||||||
|
@ -389,13 +389,13 @@ namespace OpenSim.Data.PGSQL
|
||||||
/// <returns>An inventory item</returns>
|
/// <returns>An inventory item</returns>
|
||||||
public InventoryItemBase getInventoryItem(UUID itemID)
|
public InventoryItemBase getInventoryItem(UUID itemID)
|
||||||
{
|
{
|
||||||
string sql = @"SELECT * FROM inventoryitems WHERE ""inventoryID"" = :inventoryID";
|
string sql = "SELECT * FROM inventoryitems WHERE inventoryID = @inventoryID";
|
||||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||||
{
|
{
|
||||||
cmd.Parameters.Add(database.CreateParameter("inventoryID", itemID));
|
cmd.Parameters.Add(database.CreateParameter("inventoryID", itemID));
|
||||||
conn.Open();
|
conn.Open();
|
||||||
using (NpgsqlDataReader reader = cmd.ExecuteReader())
|
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||||
{
|
{
|
||||||
if (reader.Read())
|
if (reader.Read())
|
||||||
{
|
{
|
||||||
|
@ -403,7 +403,7 @@ namespace OpenSim.Data.PGSQL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_log.InfoFormat("[INVENTORY DB]: Found no inventory item with ID : {0}", itemID);
|
m_log.InfoFormat("[INVENTORY DB]: Found no inventory item with ID : {0}", itemID);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -420,24 +420,24 @@ namespace OpenSim.Data.PGSQL
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
string sql = @"INSERT INTO inventoryitems
|
string sql = @"INSERT INTO inventoryitems
|
||||||
(""inventoryID"", ""assetID"", ""assetType"", ""parentFolderID"", ""avatarID"", ""inventoryName"",
|
([inventoryID], [assetID], [assetType], [parentFolderID], [avatarID], [inventoryName],
|
||||||
""inventoryDescription"", ""inventoryNextPermissions"", ""inventoryCurrentPermissions"",
|
[inventoryDescription], [inventoryNextPermissions], [inventoryCurrentPermissions],
|
||||||
""invType"", ""creatorID"", ""inventoryBasePermissions"", ""inventoryEveryOnePermissions"", ""inventoryGroupPermissions"",
|
[invType], [creatorID], [inventoryBasePermissions], [inventoryEveryOnePermissions], [inventoryGroupPermissions],
|
||||||
""salePrice"", ""SaleType"", ""creationDate"", ""groupID"", ""groupOwned"", flags)
|
[salePrice], [saleType], [creationDate], [groupID], [groupOwned], [flags])
|
||||||
VALUES
|
VALUES
|
||||||
(:inventoryID, :assetID, :assetType, :parentFolderID, :avatarID, :inventoryName, :inventoryDescription,
|
(@inventoryID, @assetID, @assetType, @parentFolderID, @avatarID, @inventoryName, @inventoryDescription,
|
||||||
:inventoryNextPermissions, :inventoryCurrentPermissions, :invType, :creatorID,
|
@inventoryNextPermissions, @inventoryCurrentPermissions, @invType, @creatorID,
|
||||||
:inventoryBasePermissions, :inventoryEveryOnePermissions, :inventoryGroupPermissions, :SalePrice, :SaleType,
|
@inventoryBasePermissions, @inventoryEveryOnePermissions, @inventoryGroupPermissions, @salePrice, @saleType,
|
||||||
:creationDate, :groupID, :groupOwned, :flags)";
|
@creationDate, @groupID, @groupOwned, @flags)";
|
||||||
|
|
||||||
string itemName = item.Name;
|
string itemName = item.Name;
|
||||||
if (item.Name.Length > 64)
|
if (item.Name.Length > 64)
|
||||||
{
|
{
|
||||||
itemName = item.Name.Substring(0, 64);
|
itemName = item.Name.Substring(0, 64);
|
||||||
m_log.Warn("[INVENTORY DB]: Name field truncated from " + item.Name.Length.ToString() + " to " + itemName.Length.ToString() + " characters");
|
m_log.Warn("[INVENTORY DB]: Name field truncated from " + item.Name.Length.ToString() + " to " + itemName.Length.ToString() + " characters");
|
||||||
}
|
}
|
||||||
|
|
||||||
string itemDesc = item.Description;
|
string itemDesc = item.Description;
|
||||||
if (item.Description.Length > 128)
|
if (item.Description.Length > 128)
|
||||||
{
|
{
|
||||||
|
@ -445,8 +445,8 @@ namespace OpenSim.Data.PGSQL
|
||||||
m_log.Warn("[INVENTORY DB]: Description field truncated from " + item.Description.Length.ToString() + " to " + itemDesc.Length.ToString() + " characters");
|
m_log.Warn("[INVENTORY DB]: Description field truncated from " + item.Description.Length.ToString() + " to " + itemDesc.Length.ToString() + " characters");
|
||||||
}
|
}
|
||||||
|
|
||||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||||
using (NpgsqlCommand command = new NpgsqlCommand(sql, conn))
|
using (SqlCommand command = new SqlCommand(sql, conn))
|
||||||
{
|
{
|
||||||
command.Parameters.Add(database.CreateParameter("inventoryID", item.ID));
|
command.Parameters.Add(database.CreateParameter("inventoryID", item.ID));
|
||||||
command.Parameters.Add(database.CreateParameter("assetID", item.AssetID));
|
command.Parameters.Add(database.CreateParameter("assetID", item.AssetID));
|
||||||
|
@ -462,8 +462,8 @@ namespace OpenSim.Data.PGSQL
|
||||||
command.Parameters.Add(database.CreateParameter("inventoryBasePermissions", item.BasePermissions));
|
command.Parameters.Add(database.CreateParameter("inventoryBasePermissions", item.BasePermissions));
|
||||||
command.Parameters.Add(database.CreateParameter("inventoryEveryOnePermissions", item.EveryOnePermissions));
|
command.Parameters.Add(database.CreateParameter("inventoryEveryOnePermissions", item.EveryOnePermissions));
|
||||||
command.Parameters.Add(database.CreateParameter("inventoryGroupPermissions", item.GroupPermissions));
|
command.Parameters.Add(database.CreateParameter("inventoryGroupPermissions", item.GroupPermissions));
|
||||||
command.Parameters.Add(database.CreateParameter("SalePrice", item.SalePrice));
|
command.Parameters.Add(database.CreateParameter("salePrice", item.SalePrice));
|
||||||
command.Parameters.Add(database.CreateParameter("SaleType", item.SaleType));
|
command.Parameters.Add(database.CreateParameter("saleType", item.SaleType));
|
||||||
command.Parameters.Add(database.CreateParameter("creationDate", item.CreationDate));
|
command.Parameters.Add(database.CreateParameter("creationDate", item.CreationDate));
|
||||||
command.Parameters.Add(database.CreateParameter("groupID", item.GroupID));
|
command.Parameters.Add(database.CreateParameter("groupID", item.GroupID));
|
||||||
command.Parameters.Add(database.CreateParameter("groupOwned", item.GroupOwned));
|
command.Parameters.Add(database.CreateParameter("groupOwned", item.GroupOwned));
|
||||||
|
@ -479,9 +479,9 @@ namespace OpenSim.Data.PGSQL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sql = @"UPDATE inventoryfolders SET version = version + 1 WHERE ""folderID"" = @folderID";
|
sql = "UPDATE inventoryfolders SET version = version + 1 WHERE folderID = @folderID";
|
||||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||||
using (NpgsqlCommand command = new NpgsqlCommand(sql, conn))
|
using (SqlCommand command = new SqlCommand(sql, conn))
|
||||||
{
|
{
|
||||||
command.Parameters.Add(database.CreateParameter("folderID", item.Folder.ToString()));
|
command.Parameters.Add(database.CreateParameter("folderID", item.Folder.ToString()));
|
||||||
conn.Open();
|
conn.Open();
|
||||||
|
@ -502,26 +502,26 @@ namespace OpenSim.Data.PGSQL
|
||||||
/// <param name="item">Inventory item to update</param>
|
/// <param name="item">Inventory item to update</param>
|
||||||
public void updateInventoryItem(InventoryItemBase item)
|
public void updateInventoryItem(InventoryItemBase item)
|
||||||
{
|
{
|
||||||
string sql = @"UPDATE inventoryitems SET ""assetID"" = :assetID,
|
string sql = @"UPDATE inventoryitems SET assetID = @assetID,
|
||||||
""assetType"" = :assetType,
|
assetType = @assetType,
|
||||||
""parentFolderID"" = :parentFolderID,
|
parentFolderID = @parentFolderID,
|
||||||
""avatarID"" = :avatarID,
|
avatarID = @avatarID,
|
||||||
""inventoryName"" = :inventoryName,
|
inventoryName = @inventoryName,
|
||||||
""inventoryDescription"" = :inventoryDescription,
|
inventoryDescription = @inventoryDescription,
|
||||||
""inventoryNextPermissions"" = :inventoryNextPermissions,
|
inventoryNextPermissions = @inventoryNextPermissions,
|
||||||
""inventoryCurrentPermissions"" = :inventoryCurrentPermissions,
|
inventoryCurrentPermissions = @inventoryCurrentPermissions,
|
||||||
""invType"" = :invType,
|
invType = @invType,
|
||||||
""creatorID"" = :creatorID,
|
creatorID = @creatorID,
|
||||||
""inventoryBasePermissions"" = :inventoryBasePermissions,
|
inventoryBasePermissions = @inventoryBasePermissions,
|
||||||
""inventoryEveryOnePermissions"" = :inventoryEveryOnePermissions,
|
inventoryEveryOnePermissions = @inventoryEveryOnePermissions,
|
||||||
""inventoryGroupPermissions"" = :inventoryGroupPermissions,
|
inventoryGroupPermissions = @inventoryGroupPermissions,
|
||||||
""salePrice"" = :SalePrice,
|
salePrice = @salePrice,
|
||||||
""saleType"" = :SaleType,
|
saleType = @saleType,
|
||||||
""creationDate"" = :creationDate,
|
creationDate = @creationDate,
|
||||||
""groupID"" = :groupID,
|
groupID = @groupID,
|
||||||
""groupOwned"" = :groupOwned,
|
groupOwned = @groupOwned,
|
||||||
flags = :flags
|
flags = @flags
|
||||||
WHERE ""inventoryID"" = :inventoryID";
|
WHERE inventoryID = @inventoryID";
|
||||||
|
|
||||||
string itemName = item.Name;
|
string itemName = item.Name;
|
||||||
if (item.Name.Length > 64)
|
if (item.Name.Length > 64)
|
||||||
|
@ -529,7 +529,7 @@ namespace OpenSim.Data.PGSQL
|
||||||
itemName = item.Name.Substring(0, 64);
|
itemName = item.Name.Substring(0, 64);
|
||||||
m_log.Warn("[INVENTORY DB]: Name field truncated from " + item.Name.Length.ToString() + " to " + itemName.Length.ToString() + " characters on update");
|
m_log.Warn("[INVENTORY DB]: Name field truncated from " + item.Name.Length.ToString() + " to " + itemName.Length.ToString() + " characters on update");
|
||||||
}
|
}
|
||||||
|
|
||||||
string itemDesc = item.Description;
|
string itemDesc = item.Description;
|
||||||
if (item.Description.Length > 128)
|
if (item.Description.Length > 128)
|
||||||
{
|
{
|
||||||
|
@ -537,8 +537,8 @@ namespace OpenSim.Data.PGSQL
|
||||||
m_log.Warn("[INVENTORY DB]: Description field truncated from " + item.Description.Length.ToString() + " to " + itemDesc.Length.ToString() + " characters on update");
|
m_log.Warn("[INVENTORY DB]: Description field truncated from " + item.Description.Length.ToString() + " to " + itemDesc.Length.ToString() + " characters on update");
|
||||||
}
|
}
|
||||||
|
|
||||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||||
using (NpgsqlCommand command = new NpgsqlCommand(sql, conn))
|
using (SqlCommand command = new SqlCommand(sql, conn))
|
||||||
{
|
{
|
||||||
command.Parameters.Add(database.CreateParameter("inventoryID", item.ID));
|
command.Parameters.Add(database.CreateParameter("inventoryID", item.ID));
|
||||||
command.Parameters.Add(database.CreateParameter("assetID", item.AssetID));
|
command.Parameters.Add(database.CreateParameter("assetID", item.AssetID));
|
||||||
|
@ -554,8 +554,8 @@ namespace OpenSim.Data.PGSQL
|
||||||
command.Parameters.Add(database.CreateParameter("inventoryBasePermissions", item.BasePermissions));
|
command.Parameters.Add(database.CreateParameter("inventoryBasePermissions", item.BasePermissions));
|
||||||
command.Parameters.Add(database.CreateParameter("inventoryEveryOnePermissions", item.EveryOnePermissions));
|
command.Parameters.Add(database.CreateParameter("inventoryEveryOnePermissions", item.EveryOnePermissions));
|
||||||
command.Parameters.Add(database.CreateParameter("inventoryGroupPermissions", item.GroupPermissions));
|
command.Parameters.Add(database.CreateParameter("inventoryGroupPermissions", item.GroupPermissions));
|
||||||
command.Parameters.Add(database.CreateParameter("SalePrice", item.SalePrice));
|
command.Parameters.Add(database.CreateParameter("salePrice", item.SalePrice));
|
||||||
command.Parameters.Add(database.CreateParameter("SaleType", item.SaleType));
|
command.Parameters.Add(database.CreateParameter("saleType", item.SaleType));
|
||||||
command.Parameters.Add(database.CreateParameter("creationDate", item.CreationDate));
|
command.Parameters.Add(database.CreateParameter("creationDate", item.CreationDate));
|
||||||
command.Parameters.Add(database.CreateParameter("groupID", item.GroupID));
|
command.Parameters.Add(database.CreateParameter("groupID", item.GroupID));
|
||||||
command.Parameters.Add(database.CreateParameter("groupOwned", item.GroupOwned));
|
command.Parameters.Add(database.CreateParameter("groupOwned", item.GroupOwned));
|
||||||
|
@ -580,9 +580,9 @@ namespace OpenSim.Data.PGSQL
|
||||||
/// <param name="itemID">the item UUID</param>
|
/// <param name="itemID">the item UUID</param>
|
||||||
public void deleteInventoryItem(UUID itemID)
|
public void deleteInventoryItem(UUID itemID)
|
||||||
{
|
{
|
||||||
string sql = @"DELETE FROM inventoryitems WHERE ""inventoryID""=:inventoryID";
|
string sql = "DELETE FROM inventoryitems WHERE inventoryID=@inventoryID";
|
||||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||||
{
|
{
|
||||||
cmd.Parameters.Add(database.CreateParameter("inventoryID", itemID));
|
cmd.Parameters.Add(database.CreateParameter("inventoryID", itemID));
|
||||||
try
|
try
|
||||||
|
@ -616,14 +616,14 @@ namespace OpenSim.Data.PGSQL
|
||||||
/// </returns>
|
/// </returns>
|
||||||
public List<InventoryItemBase> fetchActiveGestures(UUID avatarID)
|
public List<InventoryItemBase> fetchActiveGestures(UUID avatarID)
|
||||||
{
|
{
|
||||||
string sql = @"SELECT * FROM inventoryitems WHERE ""avatarID"" = :uuid AND ""assetType"" = :assetType and flags = 1";
|
string sql = "SELECT * FROM inventoryitems WHERE avatarId = @uuid AND assetType = @assetType and flags = 1";
|
||||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, conn))
|
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||||
{
|
{
|
||||||
cmd.Parameters.Add(database.CreateParameter("uuid", avatarID));
|
cmd.Parameters.Add(database.CreateParameter("uuid", avatarID));
|
||||||
cmd.Parameters.Add(database.CreateParameter("assetType", (int)AssetType.Gesture));
|
cmd.Parameters.Add(database.CreateParameter("assetType", (int)AssetType.Gesture));
|
||||||
conn.Open();
|
conn.Open();
|
||||||
using (NpgsqlDataReader reader = cmd.ExecuteReader())
|
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||||
{
|
{
|
||||||
List<InventoryItemBase> gestureList = new List<InventoryItemBase>();
|
List<InventoryItemBase> gestureList = new List<InventoryItemBase>();
|
||||||
while (reader.Read())
|
while (reader.Read())
|
||||||
|
@ -644,9 +644,9 @@ namespace OpenSim.Data.PGSQL
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="folderID">the item ID</param>
|
/// <param name="folderID">the item ID</param>
|
||||||
/// <param name="connection">connection to the database</param>
|
/// <param name="connection">connection to the database</param>
|
||||||
private void DeleteItemsInFolder(UUID folderID, NpgsqlConnection connection)
|
private void DeleteItemsInFolder(UUID folderID, SqlConnection connection)
|
||||||
{
|
{
|
||||||
using (NpgsqlCommand command = new NpgsqlCommand(@"DELETE FROM inventoryitems WHERE ""folderID""=:folderID", connection))
|
using (SqlCommand command = new SqlCommand("DELETE FROM inventoryitems WHERE folderID=@folderID", connection))
|
||||||
{
|
{
|
||||||
command.Parameters.Add(database.CreateParameter("folderID", folderID));
|
command.Parameters.Add(database.CreateParameter("folderID", folderID));
|
||||||
|
|
||||||
|
@ -667,9 +667,9 @@ namespace OpenSim.Data.PGSQL
|
||||||
/// <param name="parentID">parent ID.</param>
|
/// <param name="parentID">parent ID.</param>
|
||||||
/// <param name="command">SQL command/connection to database</param>
|
/// <param name="command">SQL command/connection to database</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private static List<InventoryFolderBase> getFolderHierarchy(UUID parentID, NpgsqlCommand command)
|
private static List<InventoryFolderBase> getFolderHierarchy(UUID parentID, SqlCommand command)
|
||||||
{
|
{
|
||||||
command.Parameters["parentID"].Value = parentID.Guid; //.ToString();
|
command.Parameters["@parentID"].Value = parentID.Guid; //.ToString();
|
||||||
|
|
||||||
List<InventoryFolderBase> folders = getInventoryFolders(command);
|
List<InventoryFolderBase> folders = getInventoryFolders(command);
|
||||||
|
|
||||||
|
@ -698,9 +698,9 @@ namespace OpenSim.Data.PGSQL
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private List<InventoryFolderBase> getInventoryFolders(UUID parentID, UUID user)
|
private List<InventoryFolderBase> getInventoryFolders(UUID parentID, UUID user)
|
||||||
{
|
{
|
||||||
string sql = @"SELECT * FROM inventoryfolders WHERE ""parentFolderID"" = :parentID AND ""agentID"" = :uuid";
|
string sql = "SELECT * FROM inventoryfolders WHERE parentFolderID = @parentID AND agentID LIKE @uuid";
|
||||||
using (NpgsqlConnection conn = new NpgsqlConnection(m_connectionString))
|
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||||
using (NpgsqlCommand command = new NpgsqlCommand(sql, conn))
|
using (SqlCommand command = new SqlCommand(sql, conn))
|
||||||
{
|
{
|
||||||
if (user == UUID.Zero)
|
if (user == UUID.Zero)
|
||||||
{
|
{
|
||||||
|
@ -721,9 +721,9 @@ namespace OpenSim.Data.PGSQL
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="command">SQLcommand.</param>
|
/// <param name="command">SQLcommand.</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private static List<InventoryFolderBase> getInventoryFolders(NpgsqlCommand command)
|
private static List<InventoryFolderBase> getInventoryFolders(SqlCommand command)
|
||||||
{
|
{
|
||||||
using (NpgsqlDataReader reader = command.ExecuteReader())
|
using (SqlDataReader reader = command.ExecuteReader())
|
||||||
{
|
{
|
||||||
|
|
||||||
List<InventoryFolderBase> items = new List<InventoryFolderBase>();
|
List<InventoryFolderBase> items = new List<InventoryFolderBase>();
|
||||||
|
@ -738,9 +738,9 @@ namespace OpenSim.Data.PGSQL
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Reads a list of inventory folders returned by a query.
|
/// Reads a list of inventory folders returned by a query.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="reader">A PGSQL Data Reader</param>
|
/// <param name="reader">A MSSQL Data Reader</param>
|
||||||
/// <returns>A List containing inventory folders</returns>
|
/// <returns>A List containing inventory folders</returns>
|
||||||
protected static InventoryFolderBase readInventoryFolder(NpgsqlDataReader reader)
|
protected static InventoryFolderBase readInventoryFolder(SqlDataReader reader)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -796,7 +796,7 @@ namespace OpenSim.Data.PGSQL
|
||||||
|
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
catch (NpgsqlException e)
|
catch (SqlException e)
|
||||||
{
|
{
|
||||||
m_log.Error("[INVENTORY DB]: Error reading inventory item :" + e.Message);
|
m_log.Error("[INVENTORY DB]: Error reading inventory item :" + e.Message);
|
||||||
}
|
}
|
||||||
|
@ -809,18 +809,18 @@ namespace OpenSim.Data.PGSQL
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="folderID">the folder UUID</param>
|
/// <param name="folderID">the folder UUID</param>
|
||||||
/// <param name="connection">connection to database</param>
|
/// <param name="connection">connection to database</param>
|
||||||
private void DeleteOneFolder(UUID folderID, NpgsqlConnection connection)
|
private void DeleteOneFolder(UUID folderID, SqlConnection connection)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using (NpgsqlCommand command = new NpgsqlCommand(@"DELETE FROM inventoryfolders WHERE ""folderID""=:folderID and type=-1", connection))
|
using (SqlCommand command = new SqlCommand("DELETE FROM inventoryfolders WHERE folderID=@folderID and type=-1", connection))
|
||||||
{
|
{
|
||||||
command.Parameters.Add(database.CreateParameter("folderID", folderID));
|
command.Parameters.Add(database.CreateParameter("folderID", folderID));
|
||||||
|
|
||||||
command.ExecuteNonQuery();
|
command.ExecuteNonQuery();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (NpgsqlException e)
|
catch (SqlException e)
|
||||||
{
|
{
|
||||||
m_log.Error("[INVENTORY DB]: Error deleting folder :" + e.Message);
|
m_log.Error("[INVENTORY DB]: Error deleting folder :" + e.Message);
|
||||||
}
|
}
|
|
@ -28,20 +28,18 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
|
using System.Data.SqlClient;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using OpenSim.Framework;
|
|
||||||
using log4net;
|
using log4net;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
using Npgsql;
|
|
||||||
using NpgsqlTypes;
|
|
||||||
|
|
||||||
namespace OpenSim.Data.PGSQL
|
namespace OpenSim.Data.MSSQL
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A management class for the MS SQL Storage Engine
|
/// A management class for the MS SQL Storage Engine
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class PGSQLManager
|
public class MSSQLManager
|
||||||
{
|
{
|
||||||
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
@ -54,37 +52,9 @@ namespace OpenSim.Data.PGSQL
|
||||||
/// Initialize the manager and set the connectionstring
|
/// Initialize the manager and set the connectionstring
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="connection"></param>
|
/// <param name="connection"></param>
|
||||||
public PGSQLManager(string connection)
|
public MSSQLManager(string connection)
|
||||||
{
|
{
|
||||||
connectionString = connection;
|
connectionString = connection;
|
||||||
InitializeMonoSecurity();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void InitializeMonoSecurity()
|
|
||||||
{
|
|
||||||
if (!Util.IsPlatformMono)
|
|
||||||
{
|
|
||||||
if (AppDomain.CurrentDomain.GetData("MonoSecurityPostgresAdded") == null)
|
|
||||||
{
|
|
||||||
AppDomain.CurrentDomain.SetData("MonoSecurityPostgresAdded", "true");
|
|
||||||
|
|
||||||
AppDomain currentDomain = AppDomain.CurrentDomain;
|
|
||||||
currentDomain.AssemblyResolve += new ResolveEventHandler(ResolveEventHandlerMonoSec);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private System.Reflection.Assembly ResolveEventHandlerMonoSec(object sender, ResolveEventArgs args)
|
|
||||||
{
|
|
||||||
Assembly MyAssembly = null;
|
|
||||||
|
|
||||||
if (args.Name.Substring(0, args.Name.IndexOf(",")) == "Mono.Security")
|
|
||||||
{
|
|
||||||
MyAssembly = Assembly.LoadFrom("lib/NET/Mono.Security.dll");
|
|
||||||
}
|
|
||||||
|
|
||||||
//Return the loaded assembly.
|
|
||||||
return MyAssembly;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -92,97 +62,54 @@ namespace OpenSim.Data.PGSQL
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="type"></param>
|
/// <param name="type"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
internal NpgsqlDbType DbtypeFromType(Type type)
|
internal SqlDbType DbtypeFromType(Type type)
|
||||||
{
|
{
|
||||||
if (type == typeof(string))
|
if (type == typeof(string))
|
||||||
{
|
{
|
||||||
return NpgsqlDbType.Varchar;
|
return SqlDbType.VarChar;
|
||||||
}
|
}
|
||||||
if (type == typeof(double))
|
if (type == typeof(double))
|
||||||
{
|
{
|
||||||
return NpgsqlDbType.Double;
|
return SqlDbType.Float;
|
||||||
}
|
}
|
||||||
if (type == typeof(Single))
|
if (type == typeof(Single))
|
||||||
{
|
{
|
||||||
return NpgsqlDbType.Double;
|
return SqlDbType.Float;
|
||||||
}
|
}
|
||||||
if (type == typeof(int))
|
if (type == typeof(int))
|
||||||
{
|
{
|
||||||
return NpgsqlDbType.Integer;
|
return SqlDbType.Int;
|
||||||
}
|
}
|
||||||
if (type == typeof(bool))
|
if (type == typeof(bool))
|
||||||
{
|
{
|
||||||
return NpgsqlDbType.Boolean;
|
return SqlDbType.Bit;
|
||||||
}
|
}
|
||||||
if (type == typeof(UUID))
|
if (type == typeof(UUID))
|
||||||
{
|
{
|
||||||
return NpgsqlDbType.Uuid;
|
return SqlDbType.UniqueIdentifier;
|
||||||
}
|
|
||||||
if (type == typeof(byte))
|
|
||||||
{
|
|
||||||
return NpgsqlDbType.Smallint;
|
|
||||||
}
|
}
|
||||||
if (type == typeof(sbyte))
|
if (type == typeof(sbyte))
|
||||||
{
|
{
|
||||||
return NpgsqlDbType.Integer;
|
return SqlDbType.Int;
|
||||||
}
|
}
|
||||||
if (type == typeof(Byte[]))
|
if (type == typeof(Byte[]))
|
||||||
{
|
{
|
||||||
return NpgsqlDbType.Bytea;
|
return SqlDbType.Image;
|
||||||
}
|
}
|
||||||
if (type == typeof(uint) || type == typeof(ushort))
|
if (type == typeof(uint) || type == typeof(ushort))
|
||||||
{
|
{
|
||||||
return NpgsqlDbType.Integer;
|
return SqlDbType.Int;
|
||||||
}
|
}
|
||||||
if (type == typeof(ulong))
|
if (type == typeof(ulong))
|
||||||
{
|
{
|
||||||
return NpgsqlDbType.Bigint;
|
return SqlDbType.BigInt;
|
||||||
}
|
}
|
||||||
if (type == typeof(DateTime))
|
if (type == typeof(DateTime))
|
||||||
{
|
{
|
||||||
return NpgsqlDbType.Timestamp;
|
return SqlDbType.DateTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NpgsqlDbType.Varchar;
|
return SqlDbType.VarChar;
|
||||||
}
|
|
||||||
|
|
||||||
internal NpgsqlDbType DbtypeFromString(Type type, string PGFieldType)
|
|
||||||
{
|
|
||||||
if (PGFieldType == "")
|
|
||||||
{
|
|
||||||
return DbtypeFromType(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (PGFieldType == "character varying")
|
|
||||||
{
|
|
||||||
return NpgsqlDbType.Varchar;
|
|
||||||
}
|
|
||||||
if (PGFieldType == "double precision")
|
|
||||||
{
|
|
||||||
return NpgsqlDbType.Double;
|
|
||||||
}
|
|
||||||
if (PGFieldType == "integer")
|
|
||||||
{
|
|
||||||
return NpgsqlDbType.Integer;
|
|
||||||
}
|
|
||||||
if (PGFieldType == "smallint")
|
|
||||||
{
|
|
||||||
return NpgsqlDbType.Smallint;
|
|
||||||
}
|
|
||||||
if (PGFieldType == "boolean")
|
|
||||||
{
|
|
||||||
return NpgsqlDbType.Boolean;
|
|
||||||
}
|
|
||||||
if (PGFieldType == "uuid")
|
|
||||||
{
|
|
||||||
return NpgsqlDbType.Uuid;
|
|
||||||
}
|
|
||||||
if (PGFieldType == "bytea")
|
|
||||||
{
|
|
||||||
return NpgsqlDbType.Bytea;
|
|
||||||
}
|
|
||||||
|
|
||||||
return DbtypeFromType(type);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -204,7 +131,7 @@ namespace OpenSim.Data.PGSQL
|
||||||
}
|
}
|
||||||
if (valueType == typeof(bool))
|
if (valueType == typeof(bool))
|
||||||
{
|
{
|
||||||
return (bool)value;
|
return (bool)value ? 1 : 0;
|
||||||
}
|
}
|
||||||
if (valueType == typeof(Byte[]))
|
if (valueType == typeof(Byte[]))
|
||||||
{
|
{
|
||||||
|
@ -217,52 +144,13 @@ namespace OpenSim.Data.PGSQL
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Create value for parameter based on PGSQL Schema
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="value"></param>
|
|
||||||
/// <param name="PGFieldType"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
internal static object CreateParameterValue(object value, string PGFieldType)
|
|
||||||
{
|
|
||||||
if (PGFieldType == "uuid")
|
|
||||||
{
|
|
||||||
UUID uidout;
|
|
||||||
UUID.TryParse(value.ToString(), out uidout);
|
|
||||||
return uidout;
|
|
||||||
}
|
|
||||||
if (PGFieldType == "integer")
|
|
||||||
{
|
|
||||||
int intout;
|
|
||||||
int.TryParse(value.ToString(), out intout);
|
|
||||||
return intout;
|
|
||||||
}
|
|
||||||
if (PGFieldType == "boolean")
|
|
||||||
{
|
|
||||||
return (value.ToString() == "true");
|
|
||||||
}
|
|
||||||
if (PGFieldType == "timestamp with time zone")
|
|
||||||
{
|
|
||||||
return (DateTime)value;
|
|
||||||
}
|
|
||||||
if (PGFieldType == "timestamp without time zone")
|
|
||||||
{
|
|
||||||
return (DateTime)value;
|
|
||||||
}
|
|
||||||
if (PGFieldType == "double precision")
|
|
||||||
{
|
|
||||||
return Convert.ToDouble(value);
|
|
||||||
}
|
|
||||||
return CreateParameterValue(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create a parameter for a command
|
/// Create a parameter for a command
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="parameterName">Name of the parameter.</param>
|
/// <param name="parameterName">Name of the parameter.</param>
|
||||||
/// <param name="parameterObject">parameter object.</param>
|
/// <param name="parameterObject">parameter object.</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
internal NpgsqlParameter CreateParameter(string parameterName, object parameterObject)
|
internal SqlParameter CreateParameter(string parameterName, object parameterObject)
|
||||||
{
|
{
|
||||||
return CreateParameter(parameterName, parameterObject, false);
|
return CreateParameter(parameterName, parameterObject, false);
|
||||||
}
|
}
|
||||||
|
@ -274,15 +162,15 @@ namespace OpenSim.Data.PGSQL
|
||||||
/// <param name="parameterObject">parameter object.</param>
|
/// <param name="parameterObject">parameter object.</param>
|
||||||
/// <param name="parameterOut">if set to <c>true</c> parameter is a output parameter</param>
|
/// <param name="parameterOut">if set to <c>true</c> parameter is a output parameter</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
internal NpgsqlParameter CreateParameter(string parameterName, object parameterObject, bool parameterOut)
|
internal SqlParameter CreateParameter(string parameterName, object parameterObject, bool parameterOut)
|
||||||
{
|
{
|
||||||
//Tweak so we dont always have to add : sign
|
//Tweak so we dont always have to add @ sign
|
||||||
if (parameterName.StartsWith(":")) parameterName = parameterName.Replace(":","");
|
if (!parameterName.StartsWith("@")) parameterName = "@" + parameterName;
|
||||||
|
|
||||||
//HACK if object is null, it is turned into a string, there are no nullable type till now
|
//HACK if object is null, it is turned into a string, there are no nullable type till now
|
||||||
if (parameterObject == null) parameterObject = "";
|
if (parameterObject == null) parameterObject = "";
|
||||||
|
|
||||||
NpgsqlParameter parameter = new NpgsqlParameter(parameterName, DbtypeFromType(parameterObject.GetType()));
|
SqlParameter parameter = new SqlParameter(parameterName, DbtypeFromType(parameterObject.GetType()));
|
||||||
|
|
||||||
if (parameterOut)
|
if (parameterOut)
|
||||||
{
|
{
|
||||||
|
@ -297,40 +185,17 @@ namespace OpenSim.Data.PGSQL
|
||||||
return parameter;
|
return parameter;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Create a parameter with PGSQL schema type
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="parameterName"></param>
|
|
||||||
/// <param name="parameterObject"></param>
|
|
||||||
/// <param name="PGFieldType"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
internal NpgsqlParameter CreateParameter(string parameterName, object parameterObject, string PGFieldType)
|
|
||||||
{
|
|
||||||
//Tweak so we dont always have to add : sign
|
|
||||||
if (parameterName.StartsWith(":")) parameterName = parameterName.Replace(":", "");
|
|
||||||
|
|
||||||
//HACK if object is null, it is turned into a string, there are no nullable type till now
|
|
||||||
if (parameterObject == null) parameterObject = "";
|
|
||||||
|
|
||||||
NpgsqlParameter parameter = new NpgsqlParameter(parameterName, DbtypeFromString(parameterObject.GetType(), PGFieldType));
|
|
||||||
|
|
||||||
parameter.Direction = ParameterDirection.Input;
|
|
||||||
parameter.Value = CreateParameterValue(parameterObject, PGFieldType);
|
|
||||||
|
|
||||||
return parameter;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Checks if we need to do some migrations to the database
|
/// Checks if we need to do some migrations to the database
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="migrationStore">migrationStore.</param>
|
/// <param name="migrationStore">migrationStore.</param>
|
||||||
public void CheckMigration(string migrationStore)
|
public void CheckMigration(string migrationStore)
|
||||||
{
|
{
|
||||||
using (NpgsqlConnection connection = new NpgsqlConnection(connectionString))
|
using (SqlConnection connection = new SqlConnection(connectionString))
|
||||||
{
|
{
|
||||||
connection.Open();
|
connection.Open();
|
||||||
Assembly assem = GetType().Assembly;
|
Assembly assem = GetType().Assembly;
|
||||||
PGSQLMigration migration = new PGSQLMigration(connection, assem, migrationStore);
|
MSSQLMigration migration = new MSSQLMigration(connection, assem, migrationStore);
|
||||||
|
|
||||||
migration.Update();
|
migration.Update();
|
||||||
}
|
}
|
|
@ -25,22 +25,22 @@
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using Npgsql;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using System.Data.Common;
|
using System.Data.Common;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using System.Data.SqlClient;
|
||||||
|
|
||||||
namespace OpenSim.Data.PGSQL
|
namespace OpenSim.Data.MSSQL
|
||||||
{
|
{
|
||||||
public class PGSQLMigration : Migration
|
public class MSSQLMigration : Migration
|
||||||
{
|
{
|
||||||
public PGSQLMigration(NpgsqlConnection conn, Assembly assem, string type)
|
public MSSQLMigration(DbConnection conn, Assembly assem, string type)
|
||||||
: base(conn, assem, type)
|
: base(conn, assem, type)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public PGSQLMigration(NpgsqlConnection conn, Assembly assem, string subtype, string type)
|
public MSSQLMigration(DbConnection conn, Assembly assem, string subtype, string type)
|
||||||
: base(conn, assem, subtype, type)
|
: base(conn, assem, subtype, type)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -48,15 +48,12 @@ namespace OpenSim.Data.PGSQL
|
||||||
protected override int FindVersion(DbConnection conn, string type)
|
protected override int FindVersion(DbConnection conn, string type)
|
||||||
{
|
{
|
||||||
int version = 0;
|
int version = 0;
|
||||||
NpgsqlConnection lcConn = (NpgsqlConnection)conn;
|
using (DbCommand cmd = conn.CreateCommand())
|
||||||
|
|
||||||
using (NpgsqlCommand cmd = lcConn.CreateCommand())
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
cmd.CommandText = "select version from migrations where name = '" + type + "' " +
|
cmd.CommandText = "select top 1 version from migrations where name = '" + type + "' order by version desc"; //Must be
|
||||||
" order by version desc limit 1"; //Must be
|
using (IDataReader reader = cmd.ExecuteReader())
|
||||||
using (NpgsqlDataReader reader = cmd.ExecuteReader())
|
|
||||||
{
|
{
|
||||||
if (reader.Read())
|
if (reader.Read())
|
||||||
{
|
{
|
||||||
|
@ -76,7 +73,7 @@ namespace OpenSim.Data.PGSQL
|
||||||
|
|
||||||
protected override void ExecuteScript(DbConnection conn, string[] script)
|
protected override void ExecuteScript(DbConnection conn, string[] script)
|
||||||
{
|
{
|
||||||
if (!(conn is NpgsqlConnection))
|
if (!(conn is SqlConnection))
|
||||||
{
|
{
|
||||||
base.ExecuteScript(conn, script);
|
base.ExecuteScript(conn, script);
|
||||||
return;
|
return;
|
||||||
|
@ -86,7 +83,7 @@ namespace OpenSim.Data.PGSQL
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using (NpgsqlCommand cmd = new NpgsqlCommand(sql, (NpgsqlConnection)conn))
|
using (SqlCommand cmd = new SqlCommand(sql, (SqlConnection)conn))
|
||||||
{
|
{
|
||||||
cmd.ExecuteNonQuery();
|
cmd.ExecuteNonQuery();
|
||||||
}
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue