Compare commits
6 Commits
master
...
ThreadPool
Author | SHA1 | Date |
---|---|---|
Teravus Ovares | ce1bbc0ae4 | |
Teravus Ovares | 882566a32f | |
Teravus Ovares | e803d2f3f6 | |
Teravus Ovares | 2ceee79905 | |
Teravus Ovares | b25c60e62f | |
Teravus Ovares | 14a8700be0 |
|
@ -1,116 +0,0 @@
|
||||||
.project
|
|
||||||
.settings
|
|
||||||
.gitignore
|
|
||||||
*.csproj
|
|
||||||
*.csproj.user
|
|
||||||
*.build
|
|
||||||
*.mdb
|
|
||||||
*.mdp
|
|
||||||
*.mds
|
|
||||||
*.pdb
|
|
||||||
*.pidb
|
|
||||||
*.dll.build
|
|
||||||
*.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
|
|
||||||
*/*/obj
|
|
||||||
*/*/*/obj
|
|
||||||
*/*/*/*/obj
|
|
||||||
*/*/*/*/*/obj
|
|
||||||
*/*/*/*/*/*/obj
|
|
||||||
*/*/*/*/*/*/*/obj
|
|
||||||
*/*/bin
|
|
||||||
*/*/*/bin
|
|
||||||
*/*/*/*/bin
|
|
||||||
*/*/*/*/*/bin
|
|
||||||
*/*/*/*/*/*/bin
|
|
||||||
*/*/*/*/*/*/*/bin
|
|
||||||
.vs/
|
|
||||||
addon-modules/
|
|
||||||
bin/Debug/*.dll
|
|
||||||
bin/*.dll.mdb
|
|
||||||
bin/*.db
|
|
||||||
bin/*.db-journal
|
|
||||||
bin/addin-db-*
|
|
||||||
bin/*.dll
|
|
||||||
bin/OpenSim.vshost.exe.config
|
|
||||||
bin/OpenSim.32BitLaunch.vshost.exe.config
|
|
||||||
bin/OpenSim.32BitLaunch.log
|
|
||||||
UpgradeLog.XML
|
|
||||||
_UpgradeReport_Files/
|
|
||||||
bin/ScriptEngines/*-*-*-*-*
|
|
||||||
bin/ScriptEngines/*.dll
|
|
||||||
bin/ScriptEngines/*/*.dll
|
|
||||||
bin/ScriptEngines/*/*.state
|
|
||||||
bin/*.maddin
|
|
||||||
bin/*.exe
|
|
||||||
bin/*.ini
|
|
||||||
bin/j2kDecodeCache
|
|
||||||
bin/Physics*
|
|
||||||
bin/Terrain*
|
|
||||||
bin/Regions/*
|
|
||||||
bin/UserAssets
|
|
||||||
bin/assetcache
|
|
||||||
bin/maptiles
|
|
||||||
bin/bakes
|
|
||||||
bin/estate_settings.xml
|
|
||||||
bin/config-include/CenomeCache.ini
|
|
||||||
bin/config-include/FlotsamCache.ini
|
|
||||||
bin/config-include/GridCommon.ini
|
|
||||||
bin/config-include/StandaloneCommon.ini
|
|
||||||
bin/OpenSim.Grid.AssetInventoryServer.log
|
|
||||||
bin/OpenSim.Grid.AssetServer.log
|
|
||||||
bin/OpenSim.Grid.GridServer.log
|
|
||||||
bin/OpenSim.Grid.InventoryServer.log
|
|
||||||
bin/OpenSim.Grid.MessagingServer.log
|
|
||||||
bin/OpenSim.Grid.UserServer.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/crashes/
|
|
||||||
Examples/*.dll
|
|
||||||
OpenSim.build
|
|
||||||
OpenSim.sln
|
|
||||||
OpenSim.userprefs
|
|
||||||
Prebuild/Prebuild.build
|
|
||||||
Prebuild/Prebuild.sln
|
|
||||||
TestResult.xml
|
|
||||||
cov/*
|
|
||||||
OpenSim/OpenSim.userprefs
|
|
||||||
OpenSim/OpenSim.usertasks
|
|
||||||
TAGS
|
|
||||||
*~
|
|
||||||
Makefile.local
|
|
||||||
bin/.version
|
|
||||||
compile.bat
|
|
||||||
OpenSim/Data/Tests/test-results/
|
|
||||||
OpenSim/Framework/Serialization/Tests/test-results/
|
|
||||||
OpenSim/Framework/Servers/Tests/test-results/
|
|
||||||
OpenSim/Framework/Tests/test-results/
|
|
||||||
OpenSim/Region/ClientStack/Linden/Caps/test-results/
|
|
||||||
OpenSim/Region/ClientStack/Linden/UDP/Tests/test-results/
|
|
||||||
OpenSim/Region/CoreModules/test-results/
|
|
||||||
OpenSim/Region/Framework/test-results/
|
|
||||||
OpenSim/Region/OptionalModules/test-results/
|
|
||||||
OpenSim/Region/Physics/BulletDotNETPlugin/
|
|
||||||
OpenSim/Region/Physics/Manager/test-results/
|
|
||||||
OpenSim/Region/Physics/OdePlugin/Tests/test-results/
|
|
||||||
OpenSim/Region/ScriptEngine/test-results/
|
|
||||||
OpenSim/Tests/Common/test-results/
|
|
||||||
OpenSim/Tests/test-results/
|
|
||||||
test-results/
|
|
||||||
doc/html
|
|
||||||
doc/doxygen.error.log
|
|
||||||
|
|
||||||
*.patch
|
|
23
.hgignore
23
.hgignore
|
@ -1,23 +0,0 @@
|
||||||
^tailor.state.old$
|
|
||||||
^tailor.state.journal$
|
|
||||||
\.csproj$
|
|
||||||
\.csproj\.user$
|
|
||||||
\.mdp$
|
|
||||||
\.mds$
|
|
||||||
\.dll\.build$
|
|
||||||
^bin/Debug/.+\.dll$
|
|
||||||
^bin/.+\.db$
|
|
||||||
^bin/OpenSim\.ini$
|
|
||||||
^bin/OpenSim\.log$
|
|
||||||
^bin/estate_settings\.xml$
|
|
||||||
^bin/Regions
|
|
||||||
bin/.+\.dll.mdb$
|
|
||||||
bin/addin-db-
|
|
||||||
bin/.+\.dll$
|
|
||||||
bin/.+\.maddin$
|
|
||||||
Examples/.+\.dll$
|
|
||||||
^bin/.+\.exe
|
|
||||||
^(OpenSim|Prebuild)/.+\.(exe|exe\.build|exe\.mdb)$
|
|
||||||
^OpenSim\.(build|sln)$
|
|
||||||
^Prebuild/Prebuild\.(build|sln)$
|
|
||||||
.+~$
|
|
|
@ -1,289 +1,41 @@
|
||||||
<!-- -*- xml -*- -->
|
<property name="projectdir" value="opensim-0.4" />
|
||||||
<!-- please leave the top comment for us emacs folks -->
|
|
||||||
<property name="nunitcmd" value="nunit-console" />
|
|
||||||
|
|
||||||
<!-- This target produces a source distribution of OpenSimulator -->
|
<target name="distdir">
|
||||||
<!-- TODO: A few parameters still need to be tweaked after running this - need to do this automatically with sed or similar -->
|
<delete dir="${projectdir}" />
|
||||||
<target name="distsrc">
|
<copy todir="${projectdir}">
|
||||||
<copy file="bin/OpenSim.ini.example" tofile="bin/OpenSim.ini"/>
|
<fileset basedir=".">
|
||||||
<copy file="bin/config-include/StandaloneCommon.ini.example" tofile="bin/config-include/StandaloneCommon.ini"/>
|
<include name="ThirdPartyLicenses/**" />
|
||||||
<copy file="bin/config-include/FlotsamCache.ini.example" tofile="bin/config-include/FlotsamCache.ini"/>
|
<include name="CONTRIBUTORS.txt" />
|
||||||
<!-- delete files generated by runprebuild.sh which had to be run in order to generate the build file for this target-->
|
<include name="README" />
|
||||||
<delete>
|
<include name="OpenSim/**/*.cs" />
|
||||||
<fileset basedir="OpenSim">
|
<include name="**/*.build" />
|
||||||
<include name="**/*.build"/>
|
<include name="**/*.csproj" />
|
||||||
<include name="**/*.csproj*"/>
|
<include name="**/*.csproj.user" />
|
||||||
<include name="**/*.dll.build"/>
|
<include name="**/*.sln" />
|
||||||
<include name="**/*.pidb"/>
|
<include name="bin/*.dll" />
|
||||||
<exclude name="Tools/OpenSim.32BitLaunch/**"/>
|
<include name="bin/*.so" />
|
||||||
<exclude name="Tools/Robust.32BitLaunch/**"/>
|
<include name="bin/*.config" />
|
||||||
<exclude name="Tools/LaunchSLClient/**"/>
|
<include name="bin/assets/**" />
|
||||||
|
<include name="bin/data/**" />
|
||||||
|
<include name="bin/OpenSim*xml" />
|
||||||
|
<!-- the next is to exclude built libs -->
|
||||||
|
<exclude name="bin/OpenSim.*dll" />
|
||||||
|
<include name="bin/OpenSim.ini" />
|
||||||
|
<include name="bin/defaultstripe.png" />
|
||||||
|
</fileset>
|
||||||
|
</copy>
|
||||||
|
<touch file="${projectdir}/bin/startup_commands.txt" />
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="dist" depends="distdir">
|
||||||
|
<zip zipfile="${projectdir}.zip">
|
||||||
|
<fileset basedir=".">
|
||||||
|
<include name="${projectdir}/**" />
|
||||||
</fileset>
|
</fileset>
|
||||||
</delete>
|
</zip>
|
||||||
<delete>
|
<tar destfile="${projectdir}.tar.gz" compression="GZip">
|
||||||
<fileset>
|
<fileset basedir=".">
|
||||||
<include name="OpenSim.build"/>
|
<include name="${projectdir}/**" />
|
||||||
<include name="OpenSim.sln"/>
|
|
||||||
</fileset>
|
</fileset>
|
||||||
</delete>
|
</tar>
|
||||||
</target>
|
|
||||||
|
|
||||||
<property name="distbindir" value="distbin" />
|
|
||||||
<!-- This target produces a binary directory called distbin/ in OpenSim/bin which contains everything needed for binary distribution -->
|
|
||||||
<!-- For safety/laziness sake, we're going to take the approach of deleting known extraneous files here rather than
|
|
||||||
trying to copy across only the essential ones -->
|
|
||||||
<target name="distbin">
|
|
||||||
<delete dir="${distbindir}"/>
|
|
||||||
<copy todir="${distbindir}">
|
|
||||||
<fileset>
|
|
||||||
<include name="**"/>
|
|
||||||
</fileset>
|
|
||||||
</copy>
|
|
||||||
<delete dir="${distbindir}/OpenSim"/>
|
|
||||||
<delete dir="${distbindir}/Prebuild"/>
|
|
||||||
<delete dir="${distbindir}/%temp%"/>
|
|
||||||
<delete dir="${distbindir}/.nant"/>
|
|
||||||
<delete dir="${distbindir}/ThirdParty"/>
|
|
||||||
<delete>
|
|
||||||
<fileset basedir="${distbindir}">
|
|
||||||
<include name="compile.bat"/>
|
|
||||||
<include name="BUILDING.md"/>
|
|
||||||
<include name="Makefile"/>
|
|
||||||
<include name="nant-color"/>
|
|
||||||
<include name="OpenSim.*"/>
|
|
||||||
<include name="prebuild.xml"/>
|
|
||||||
<include name="runprebuild*"/>
|
|
||||||
<include name="TESTING.txt"/>
|
|
||||||
<include name="TestResult.xml"/>
|
|
||||||
<include name="bin/OpenSim.Server.ini"/>
|
|
||||||
<include name="bin/Regions/Regions.ini"/>
|
|
||||||
<include name="bin/*.db"/>
|
|
||||||
<include name="**/.git/**"/>
|
|
||||||
<include name=".gitignore"/>
|
|
||||||
<include name=".hgignore"/>
|
|
||||||
</fileset>
|
|
||||||
</delete>
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="test" depends="build, find-nunit">
|
|
||||||
<setenv name="MONO_THREADS_PER_CPU" value="100" />
|
|
||||||
|
|
||||||
<!-- Unit Test Assembly -->
|
|
||||||
<!-- if you want to add more unit tests it's important that you add
|
|
||||||
the assembly here as an exec, and you add the fail clause later.
|
|
||||||
This lets all the unit tests run and tells you if they fail at the
|
|
||||||
end, instead of stopping short -->
|
|
||||||
<exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.tests">
|
|
||||||
<arg value="./bin/OpenSim.Tests.dll" />
|
|
||||||
</exec>
|
|
||||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.tests)==0}" />
|
|
||||||
|
|
||||||
<exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.framework.tests">
|
|
||||||
<arg value="./bin/OpenSim.Framework.Tests.dll" />
|
|
||||||
</exec>
|
|
||||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.framework.tests)==0}" />
|
|
||||||
|
|
||||||
<exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.framework.servers.tests">
|
|
||||||
<arg value="./bin/OpenSim.Framework.Servers.Tests.dll" />
|
|
||||||
</exec>
|
|
||||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.framework.servers.tests)==0}" />
|
|
||||||
|
|
||||||
<exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.framework.serialization.tests">
|
|
||||||
<arg value="./bin/OpenSim.Framework.Serialization.Tests.dll" />
|
|
||||||
</exec>
|
|
||||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.framework.serialization.tests)==0}" />
|
|
||||||
|
|
||||||
<exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.region.clientstack.lindencaps.tests">
|
|
||||||
<arg value="./bin/OpenSim.Region.ClientStack.LindenCaps.Tests.dll" />
|
|
||||||
</exec>
|
|
||||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.clientstack.lindencaps.tests)==0}" />
|
|
||||||
|
|
||||||
<exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.region.clientstack.lindenudp.tests">
|
|
||||||
<arg value="./bin/OpenSim.Region.ClientStack.LindenUDP.Tests.dll" />
|
|
||||||
</exec>
|
|
||||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.clientstack.lindenudp.tests)==0}" />
|
|
||||||
|
|
||||||
<exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.region.scriptengine.tests">
|
|
||||||
<arg value="./bin/OpenSim.Region.ScriptEngine.Tests.dll" />
|
|
||||||
</exec>
|
|
||||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.scriptengine.tests)==0}" />
|
|
||||||
|
|
||||||
<exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.region.coremodules.tests">
|
|
||||||
<arg value="./bin/OpenSim.Region.CoreModules.Tests.dll" />
|
|
||||||
</exec>
|
|
||||||
<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">
|
|
||||||
<arg value="./bin/OpenSim.Region.OptionalModules.Tests.dll" />
|
|
||||||
</exec>
|
|
||||||
<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">
|
|
||||||
<arg value="./bin/OpenSim.Region.Framework.Tests.dll" />
|
|
||||||
</exec>
|
|
||||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.framework.tests)==0}" />
|
|
||||||
|
|
||||||
<exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.data.tests">
|
|
||||||
<arg value="./bin/OpenSim.Data.Tests.dll" />
|
|
||||||
</exec>
|
|
||||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.data.tests)==0}" />
|
|
||||||
|
|
||||||
<exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.capabilities.handlers.tests">
|
|
||||||
<arg value="./bin/OpenSim.Capabilities.Handlers.Tests.dll" />
|
|
||||||
</exec>
|
|
||||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.capabilities.handlers.tests)==0}" />
|
|
||||||
|
|
||||||
<exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.server.handlers.tests">
|
|
||||||
<arg value="./bin/OpenSim.Server.Handlers.Tests.dll" />
|
|
||||||
</exec>
|
|
||||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.server.handlers.tests)==0}" />
|
|
||||||
|
|
||||||
<exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.services.inventoryservice.tests">
|
|
||||||
<arg value="./bin/OpenSim.Services.InventoryService.Tests.dll" />
|
|
||||||
</exec>
|
|
||||||
<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">
|
|
||||||
<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 name="test-stress" depends="build, find-nunit">
|
|
||||||
<setenv name="MONO_THREADS_PER_CPU" value="100" />
|
|
||||||
|
|
||||||
<exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.tests.stress">
|
|
||||||
<arg value="./bin/OpenSim.Tests.Stress.dll" />
|
|
||||||
</exec>
|
|
||||||
|
|
||||||
<fail message="Failures reported in stress tests." unless="${int::parse(testresult.opensim.tests.stress)==0}" />
|
|
||||||
<delete dir="%temp%"/>
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="test-perf" depends="build, find-nunit">
|
|
||||||
<setenv name="MONO_THREADS_PER_CPU" value="100" />
|
|
||||||
|
|
||||||
<exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.tests.performance">
|
|
||||||
<arg value="./bin/OpenSim.Tests.Performance.dll" />
|
|
||||||
</exec>
|
|
||||||
|
|
||||||
<fail message="Failures reported in performance tests." unless="${int::parse(testresult.opensim.tests.performance)==0}" />
|
|
||||||
<delete dir="%temp%"/>
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="find-nunit">
|
|
||||||
<exec program="which" failonerror="false"
|
|
||||||
resultproperty="hasnunit2">
|
|
||||||
<arg value="nunit-console2" />
|
|
||||||
</exec>
|
|
||||||
|
|
||||||
<property name="nunitcmd" value="nunit-console2"
|
|
||||||
if="${int::parse(hasnunit2)==0}" />
|
|
||||||
<property name="nunitcmd" value="nunit-console"
|
|
||||||
if="${int::parse(hasnunit2)==1}" />
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<!-- this is used for panda test execution -->
|
|
||||||
<!-- work in progress -->
|
|
||||||
|
|
||||||
<target name="test-xml" depends="build, find-nunit">
|
|
||||||
<mkdir dir="test-results" failonerror="false" />
|
|
||||||
<!-- Unit Test Assembly -->
|
|
||||||
<exec program="${nunitcmd}" failonerror="false" resultproperty="testresult.opensim.tests">
|
|
||||||
<arg value="./bin/OpenSim.Tests.dll" />
|
|
||||||
<arg value="-xml=test-results/OpenSim.Tests.dll-Results.xml" />
|
|
||||||
</exec>
|
|
||||||
|
|
||||||
<exec program="${nunitcmd}" failonerror="false" resultproperty="testresult.opensim.framework.tests">
|
|
||||||
<arg value="./bin/OpenSim.Framework.Tests.dll" />
|
|
||||||
<arg value="-xml=test-results/OpenSim.Framework.Tests.dll-Results.xml" />
|
|
||||||
</exec>
|
|
||||||
|
|
||||||
<exec program="${nunitcmd}" failonerror="false" resultproperty="testresult.opensim.framework.serialization.tests">
|
|
||||||
<arg value="./bin/OpenSim.Framework.Serialization.Tests.dll" />
|
|
||||||
<arg value="-xml=test-results/OpenSim.Framework.Serialization.Tests.dll-Results.xml" />
|
|
||||||
</exec>
|
|
||||||
|
|
||||||
<exec program="${nunitcmd}" failonerror="false" resultproperty="testresult.opensim.framework.servers.tests">
|
|
||||||
<arg value="./bin/OpenSim.Framework.Servers.Tests.dll" />
|
|
||||||
<arg value="-xml=test-results/OpenSim.Framework.Servers.Tests.dll-Results.xml" />
|
|
||||||
</exec>
|
|
||||||
|
|
||||||
<exec program="${nunitcmd}" failonerror="false" resultproperty="testresult.opensim.region.clientstack.lindencaps.tests">
|
|
||||||
<arg value="./bin/OpenSim.Region.ClientStack.LindenCaps.Tests.dll" />
|
|
||||||
<arg value="-xml=test-results/OpenSim.Region.ClientStack.LindenCaps.Tests.dll-Results.xml" />
|
|
||||||
</exec>
|
|
||||||
|
|
||||||
<exec program="${nunitcmd}" failonerror="false" resultproperty="testresult.opensim.region.clientstack.lindenudp.tests">
|
|
||||||
<arg value="./bin/OpenSim.Region.ClientStack.LindenUDP.Tests.dll" />
|
|
||||||
<arg value="-xml=test-results/OpenSim.Region.ClientStack.LindenUDP.Tests.dll-Results.xml" />
|
|
||||||
</exec>
|
|
||||||
|
|
||||||
<exec program="${nunitcmd}" failonerror="false" resultproperty="testresult.opensim.region.scriptengine.tests">
|
|
||||||
<arg value="./bin/OpenSim.Region.ScriptEngine.Tests.dll" />
|
|
||||||
<arg value="-xml=test-results/OpenSim.Region.ScriptEngine.Tests.dll-Results.xml" />
|
|
||||||
</exec>
|
|
||||||
|
|
||||||
<exec program="${nunitcmd}" failonerror="false" resultproperty="testresult.opensim.region.coremodules.tests">
|
|
||||||
<arg value="./bin/OpenSim.Region.CoreModules.Tests.dll" />
|
|
||||||
<arg value="-xml=test-results/OpenSim.Region.CoreModules.Tests.dll-Results.xml" />
|
|
||||||
</exec>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
<exec program="${nunitcmd}" failonerror="false" resultproperty="testresult.opensim.region.optionalmodules.tests">
|
|
||||||
<arg value="./bin/OpenSim.Region.OptionalModules.Tests.dll" />
|
|
||||||
<arg value="-xml=test-results/OpenSim.Region.OptionalModules.Tests.dll-Results.xml" />
|
|
||||||
</exec>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<exec program="${nunitcmd}" failonerror="false" resultproperty="testresult.opensim.region.framework.tests">
|
|
||||||
<arg value="./bin/OpenSim.Region.Framework.Tests.dll" />
|
|
||||||
<arg value="-xml=test-results/OpenSim.Region.Framework.Tests.dll-Results.xml" />
|
|
||||||
</exec>
|
|
||||||
|
|
||||||
<exec program="${nunitcmd}" failonerror="false" resultproperty="testresult.opensim.data.tests">
|
|
||||||
<arg value="./bin/OpenSim.Data.Tests.dll" />
|
|
||||||
<arg value="-xml=test-results/OpenSim.Data.Tests.dll-Results.xml" />
|
|
||||||
</exec>
|
|
||||||
|
|
||||||
<exec program="${nunitcmd}" failonerror="false" resultproperty="testresult.opensim.capabilities.handlers.tests">
|
|
||||||
<arg value="./bin/OpenSim.Capabilities.Handlers.Tests.dll" />
|
|
||||||
<arg value="-xml=test-results/OpenSim.Capabilities.Handlers.Tests.dll-Results.xml" />
|
|
||||||
</exec>
|
|
||||||
|
|
||||||
<exec program="${nunitcmd}" failonerror="false" resultproperty="testresult.opensim.server.handlers.tests">
|
|
||||||
<arg value="./bin/OpenSim.Server.Handlers.Tests.dll" />
|
|
||||||
<arg value="-xml=test-results/OpenSim.Server.Handlers.Tests.dll-Results.xml" />
|
|
||||||
</exec>
|
|
||||||
|
|
||||||
<exec program="${nunitcmd}" failonerror="false" resultproperty="testresult.opensim.services.inventoryservice.tests">
|
|
||||||
<arg value="./bin/OpenSim.Services.InventoryService.Tests.dll" />
|
|
||||||
<arg value="-xml=test-results/OpenSim.Services.InventoryService.Tests.dll-Results.xml" />
|
|
||||||
</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.framework.tests)==0}" />
|
|
||||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.framework.servers.tests)==0}" />
|
|
||||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.clientstack.lindenudp.tests)==0}" />
|
|
||||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.scriptengine.tests)==0}" />
|
|
||||||
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.coremodules.tests)==0}" />
|
|
||||||
<!-- <fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.optionalmodules.tests)==0}" /> -->
|
|
||||||
<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.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.tests.permissions)==0}" />
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="doxygen">
|
|
||||||
<exec program="doxygen" workingdir="doc" commandline="doxygen.conf" />
|
|
||||||
</target>
|
</target>
|
||||||
|
|
37
BUILDING.md
37
BUILDING.md
|
@ -1,37 +0,0 @@
|
||||||
# Building on Windows
|
|
||||||
|
|
||||||
Steps:
|
|
||||||
|
|
||||||
* runprebuild.bat
|
|
||||||
* Load OpenSim.sln into Visual Studio .NET and build the solution.
|
|
||||||
* chdir bin
|
|
||||||
* copy OpenSim.ini.example to OpenSim.ini and other appropriate files in bin/config-include
|
|
||||||
* run OpenSim.exe
|
|
||||||
|
|
||||||
# Building on Linux / Mac
|
|
||||||
|
|
||||||
Prereqs:
|
|
||||||
|
|
||||||
* Mono > 5.0
|
|
||||||
* 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.
|
|
||||||
|
|
||||||
From the distribution type:
|
|
||||||
|
|
||||||
* ./runprebuild.sh
|
|
||||||
* type msbuild or xbuild
|
|
||||||
* cd bin
|
|
||||||
* 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
|
|
||||||
* windows: execute opensim.exe or opensim32.exe for small regions
|
|
||||||
* linux: run ./opensim.sh
|
|
||||||
* msbuild (xbuild) option switches
|
|
||||||
* clean: msbuild /target:clean
|
|
||||||
* debug: (default) msbuild /property:Configuration=Debug
|
|
||||||
* release: msbuild /property:Configuration=Release
|
|
||||||
|
|
||||||
# References
|
|
||||||
|
|
||||||
Helpful resources:
|
|
||||||
* http://opensimulator.org/wiki/Build_Instructions
|
|
252
CONTRIBUTORS.txt
252
CONTRIBUTORS.txt
|
@ -1,252 +1,76 @@
|
||||||
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) =
|
Add your name in here if you have committed to OpenSim
|
||||||
These folks represent the current core team for OpenSim, and are the
|
|
||||||
people that make the day to day of OpenSim happen.
|
|
||||||
|
|
||||||
* Melanie Thielker
|
|
||||||
* Diva (Crista Lopes, University of California, Irvine)
|
|
||||||
* Robert Adams (MisterBlue)
|
|
||||||
* Kevin Cozens
|
|
||||||
* Leal Duarte (Ubit Umarov)
|
|
||||||
|
|
||||||
= Core Developers Following the White Rabbit =
|
OpenSim Developers
|
||||||
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
|
|
||||||
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)
|
||||||
|
* MingChen (DeepThink Pty Ltd)
|
||||||
= Past Open Sim Developers =
|
* lbsa71 (Tribal Media AB)
|
||||||
These folks are alumns of the OpenSim core group, but are now
|
* sdague (International Business Machines Corp.)
|
||||||
currently not active. Their great contributions helped get us to
|
|
||||||
where we are today.
|
|
||||||
|
|
||||||
* Gareth
|
|
||||||
* Andy-
|
* Andy-
|
||||||
|
* Gareth
|
||||||
* MorphW
|
* MorphW
|
||||||
* CW
|
* CW
|
||||||
* Babblefrog
|
* Babblefrog
|
||||||
|
* Tedd
|
||||||
|
* justincc (International Business Machines Corp.)
|
||||||
|
* Teravus (w3z)
|
||||||
|
* Johan Berntsson (3Di)
|
||||||
|
* Ckrinke (Charles Krinke)
|
||||||
* Danx0r
|
* Danx0r
|
||||||
* Dalien
|
* Dalien
|
||||||
* Darok
|
* Darok
|
||||||
|
* chi11ken (3Di)
|
||||||
|
* adjohn (3Di)
|
||||||
* Alondria
|
* Alondria
|
||||||
* Sean Dague / sdague (IBM)
|
|
||||||
* Tedd
|
|
||||||
* MingChen (DeepThink Pty Ltd)
|
|
||||||
* adjohn (Genkii)
|
|
||||||
* idb (Ian Brown)
|
|
||||||
* 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 =
|
|
||||||
These folks have contributed code patches or content to OpenSimulator to help make it
|
|
||||||
what it is today.
|
|
||||||
|
|
||||||
* A_Biondi
|
Patches
|
||||||
* aduffy70
|
|
||||||
* Ai Austin
|
|
||||||
* alex_carnell
|
|
||||||
* Alan Webb (IBM)
|
|
||||||
* Aleric
|
|
||||||
* Allen Kerensky
|
|
||||||
* BigFootAg
|
* BigFootAg
|
||||||
* Bill Blight
|
|
||||||
* BlueWall Slade
|
|
||||||
* bobshaffer2
|
|
||||||
* brianw/Sir_Ahzz
|
|
||||||
* CharlieO
|
* CharlieO
|
||||||
* ChrisDown
|
* jhurliman (LLSD Login)
|
||||||
* Chris Yeoh (IBM)
|
* kinoc
|
||||||
* cinderblocks
|
|
||||||
* controlbreak
|
|
||||||
* coyled
|
|
||||||
* ctrlaltdavid (David Rowe)
|
|
||||||
* Daedius
|
|
||||||
* daTwitch
|
* daTwitch
|
||||||
* Dev Random
|
|
||||||
* devalnor-#708
|
|
||||||
* dmiles (Daxtron Labs)
|
|
||||||
* Dong Jun Lan (IBM)
|
|
||||||
* DoranZemlja
|
|
||||||
* Drake Arconis
|
|
||||||
* dr0b3rts
|
|
||||||
* dslake
|
|
||||||
* eeyore
|
|
||||||
* FredoChaplin
|
|
||||||
* FreakyTech
|
|
||||||
* Garmin Kawaguichi
|
|
||||||
* Gavin Hird
|
|
||||||
* Gerhard
|
|
||||||
* Godfrey
|
|
||||||
* Greg C.
|
|
||||||
* Grumly57
|
|
||||||
* GuduleLapointe
|
|
||||||
* Ewe Loon
|
|
||||||
* Fernando Oliveira
|
|
||||||
* Fly-Man
|
|
||||||
* Flyte Xevious
|
|
||||||
* Freaky Tech
|
|
||||||
* Garmin Kawaguichi
|
|
||||||
* Geir Noklebye
|
|
||||||
* Glenn Martin (MOSES)
|
|
||||||
* Gryc Ueusp
|
|
||||||
* H-H-H (ginge264)
|
|
||||||
* Hiro Lecker
|
|
||||||
* Iain Oliver
|
|
||||||
* Imaze Rhiano
|
|
||||||
* Intimidated
|
|
||||||
* Jak Daniels
|
|
||||||
* Jeff Kelly
|
|
||||||
* Jeremy Bongio (IBM)
|
|
||||||
* jhurliman
|
|
||||||
* John R Sohn (XenReborn)
|
|
||||||
* jonc
|
|
||||||
* Jon Cundill
|
|
||||||
* Junta Kohime
|
|
||||||
* Kayne
|
|
||||||
* kinoc (Daxtron Labs)
|
|
||||||
* Kira
|
|
||||||
* Kitto Flora
|
|
||||||
* KittyLiu
|
|
||||||
* Kurt Taylor (IBM)
|
|
||||||
* Lani Global
|
|
||||||
* lickx
|
|
||||||
* lillith_xue
|
|
||||||
* lkalif
|
|
||||||
* LuciusSirnah
|
|
||||||
* lulurun
|
|
||||||
* M.Igarashi
|
|
||||||
* Magnuz Binder
|
|
||||||
* maimedleech
|
|
||||||
* Mana Janus
|
|
||||||
* Mandarinka Tasty
|
|
||||||
* MarcelEdward
|
|
||||||
* Matt Lehmann
|
|
||||||
* mewtwo0641
|
|
||||||
* Mic Bowman
|
|
||||||
* Michelle Argus
|
|
||||||
* Michael Cortez (The Flotsam Project, http://osflotsam.org/)
|
|
||||||
* Michael Heilmann (MOSES)
|
|
||||||
* Micheil Merlin
|
|
||||||
* Mike Osias (IBM)
|
|
||||||
* Mike Pitman (IBM)
|
|
||||||
* Mike Rieker (Dreamnation)
|
|
||||||
* mikemig
|
|
||||||
* mikkopa/_someone - RealXtend
|
* mikkopa/_someone - RealXtend
|
||||||
* Misterblue
|
|
||||||
* Mircea Kitsune
|
|
||||||
* mpallari
|
|
||||||
* MrMonkE
|
|
||||||
* Nebadon Izumi (Michael Cerquoni - http://OSgrid.org)
|
|
||||||
* Neil Canham
|
|
||||||
* nornalbion
|
|
||||||
* Omar Vera Ustariz (IBM)
|
|
||||||
* openlifegrid.com
|
* openlifegrid.com
|
||||||
* otakup0pe
|
* Dr Scofield (International Business Machines Corp.)
|
||||||
* Pixel Tomsen
|
* Daedius
|
||||||
* Quill Littlefeather
|
* alex_carnell
|
||||||
* ralphos
|
* webmage (International Business Machines Corp.)
|
||||||
* RemedyTomm
|
* jimbo2120 (International Business Machines Corp.)
|
||||||
* Revolution
|
* brianw/Sir_Ahzz
|
||||||
* Richard Alimi (IBM)
|
|
||||||
* Rick Alther (IBM)
|
|
||||||
* Rob Smart (IBM)
|
LSL Devs
|
||||||
* Robert Louden (MOSES)
|
|
||||||
* Roger Kirkman (zadark)
|
|
||||||
* rtomita
|
|
||||||
* Ruud Lathorp
|
|
||||||
* SachaMagne
|
|
||||||
* Salahzar Stenvaag
|
|
||||||
* satguru p srivastava
|
|
||||||
* sempuki
|
|
||||||
* Shy Robbiani
|
|
||||||
* SignpostMarv
|
|
||||||
* SpotOn3D
|
|
||||||
* Stefan_Boom / stoehr
|
|
||||||
* Steven Zielinski (MOSES)
|
|
||||||
* Stolen Ruby
|
|
||||||
* Strawberry Fride
|
|
||||||
* Talun
|
|
||||||
* TechplexEngineer (Blake Bourque)
|
|
||||||
* TBG Renfold
|
|
||||||
* Terry Ford
|
|
||||||
* tglion
|
|
||||||
* tlaukkan/Tommil (Tommi S. E. Laukkanen, Bubble Cloud)
|
|
||||||
* TomDataWorks
|
|
||||||
* TomTheDragon (muckwaddle)
|
|
||||||
* tyre
|
|
||||||
* uriesk
|
|
||||||
* Vegaslon <vegaslon@gmail.com>
|
|
||||||
* Vincent Sylvester
|
|
||||||
* VikingErik
|
|
||||||
* Vytek
|
|
||||||
* webmage (IBM)
|
|
||||||
* Xantor
|
|
||||||
* Y. Nitta
|
|
||||||
* YoshikoFazuku
|
|
||||||
* YZh
|
|
||||||
* Zackary Geers aka Kunnis Basiat
|
|
||||||
* Zha Ewry
|
|
||||||
* ziah
|
|
||||||
|
|
||||||
= LSL Devs =
|
|
||||||
* Alondria
|
* Alondria
|
||||||
* CharlieO
|
* CharlieO
|
||||||
* Tedd
|
* Tedd
|
||||||
* Melanie Thielker
|
|
||||||
|
|
||||||
= Testers =
|
|
||||||
* Ai Austin
|
Testers
|
||||||
* CharlieO (LSL)
|
|
||||||
* Ckrinke
|
* Ckrinke
|
||||||
|
* CharlieO (LSL)
|
||||||
* 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)
|
* DB4objects, Inc. (DB4o)
|
||||||
* SQLite (Public Domain)
|
* SQLite (Public Domain)
|
||||||
* XmlRpcCS (http://xmlrpccs.sf.net/)
|
* XmlRpcCS (http://xmlrpccs.sf.net/)
|
||||||
* MySQL, Inc. (MySQL Connector/NET)
|
* MySQL, Inc. (MySQL Connector/NET)
|
||||||
* NUnit (http://www.nunit.org)
|
|
||||||
* AGEIA Inc. (PhysX)
|
* AGEIA Inc. (PhysX)
|
||||||
* Russel L. Smith (ODE)
|
* Russel L. Smith (ODE)
|
||||||
* Erwin Coumans (Bullet)
|
* Prebuild ( http://sourceforge.net/projects/dnpb/ )
|
||||||
* Prebuild (http://sourceforge.net/projects/dnpb/)
|
* LibSecondLife ( http://www.libsecondlife.org/wiki/Main_Page )
|
||||||
* LibOpenMetaverse (http://lib.openmetaverse.org/)
|
|
||||||
* DotNetOpenMail v0.5.8b (http://dotnetopenmail.sourceforge.net)
|
|
||||||
* Prototype JavaScript Framework ajax (http://www.prototypejs.org/)
|
|
||||||
* C5 GENERIC COLLECTION LIBRARY FOR C#/CLI
|
|
||||||
* Nini (http://nini.sourceforge.net/)
|
|
||||||
* log4net (http://logging.apache.org/log4net/)
|
|
||||||
* GlynnTucker.Cache (http://gtcache.sourceforge.net/)
|
|
||||||
* NDesk.Options 0.2.1 (http://www.ndesk.org/Options)
|
|
||||||
* Json.NET 3.5 Release 6. The binary used is actually Newtonsoft.Json.Net20.dll for Mono 2.4 compatability (http://james.newtonking.com/projects/json-net.aspx)
|
|
||||||
* zlib.net for C# 1.0.4 (http://www.componentace.com/zlib_.NET.htm)
|
|
||||||
|
|
||||||
Some plugins are based on Cable Beach
|
|
||||||
Cable Beach is Copyright (c) 2008 Intel Corporation
|
|
||||||
see http://forge.opensimulator.org/gf/project/assetserver/
|
|
||||||
|
|
||||||
In addition, we would like to thank:
|
In addition, we would like to thank:
|
||||||
* The Mono Project
|
* The Mono Project
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
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.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
modification, are permitted provided that the following conditions are met:
|
modification, are permitted provided that the following conditions are met:
|
||||||
* Redistributions of source code must retain the above copyright
|
* Redistributions of source code must retain the above copyright
|
||||||
notice, this list of conditions and the following disclaimer.
|
notice, this list of conditions and the following disclaimer.
|
||||||
* Redistributions in binary form must reproduce the above copyright
|
* Redistributions in binary form must reproduce the above copyright
|
||||||
notice, this list of conditions and the following disclaimer in the
|
notice, this list of conditions and the following disclaimer in the
|
||||||
documentation and/or other materials provided with the distribution.
|
documentation and/or other materials provided with the distribution.
|
||||||
* Neither the name of the OpenSimulator Project nor the
|
* Neither the name of the OpenSim Project nor the
|
||||||
names of its contributors may be used to endorse or promote products
|
names of its contributors may be used to endorse or promote products
|
||||||
derived from this software without specific prior written permission.
|
derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
|
43
Makefile
43
Makefile
|
@ -1,43 +0,0 @@
|
||||||
# hey, emacs! this is a -*- makefile -*-
|
|
||||||
#
|
|
||||||
# OpenSim makefile
|
|
||||||
#
|
|
||||||
|
|
||||||
RUBY = $(strip $(shell which ruby 2>/dev/null))
|
|
||||||
ifeq ($(RUBY),)
|
|
||||||
NANT = nant
|
|
||||||
else
|
|
||||||
NANT = $(shell if test "$$EMACS" = "t" ; then echo "nant"; else echo "./nant-color"; fi)
|
|
||||||
endif
|
|
||||||
|
|
||||||
all: prebuild
|
|
||||||
# @export PATH=/usr/local/bin:$(PATH)
|
|
||||||
${NANT}
|
|
||||||
find OpenSim -name \*.mdb -exec cp {} bin \;
|
|
||||||
|
|
||||||
release: prebuild
|
|
||||||
${NANT} -D:project.config=Release
|
|
||||||
find OpenSim -name \*.mdb -exec cp {} bin \;
|
|
||||||
|
|
||||||
prebuild:
|
|
||||||
./runprebuild.sh
|
|
||||||
|
|
||||||
clean:
|
|
||||||
# @export PATH=/usr/local/bin:$(PATH)
|
|
||||||
-${NANT} clean
|
|
||||||
|
|
||||||
test: prebuild
|
|
||||||
${NANT} test
|
|
||||||
|
|
||||||
test-xml: prebuild
|
|
||||||
${NANT} test-xml
|
|
||||||
|
|
||||||
tags:
|
|
||||||
find OpenSim -name \*\.cs | xargs etags
|
|
||||||
|
|
||||||
cscope-tags:
|
|
||||||
find OpenSim -name \*\.cs -fprint cscope.files
|
|
||||||
cscope -b
|
|
||||||
|
|
||||||
include $(wildcard Makefile.local)
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,78 +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 OpenSim.Framework;
|
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
|
||||||
using OpenSim.Services.Interfaces;
|
|
||||||
|
|
||||||
namespace OpenSim.Groups
|
|
||||||
{
|
|
||||||
public class ForeignImporter
|
|
||||||
{
|
|
||||||
IUserManagement m_UserManagement;
|
|
||||||
public ForeignImporter(IUserManagement uman)
|
|
||||||
{
|
|
||||||
m_UserManagement = uman;
|
|
||||||
}
|
|
||||||
|
|
||||||
public GroupMembersData ConvertGroupMembersData(ExtendedGroupMembersData _m)
|
|
||||||
{
|
|
||||||
GroupMembersData m = new GroupMembersData();
|
|
||||||
m.AcceptNotices = _m.AcceptNotices;
|
|
||||||
m.AgentPowers = _m.AgentPowers;
|
|
||||||
m.Contribution = _m.Contribution;
|
|
||||||
m.IsOwner = _m.IsOwner;
|
|
||||||
m.ListInProfile = _m.ListInProfile;
|
|
||||||
m.OnlineStatus = _m.OnlineStatus;
|
|
||||||
m.Title = _m.Title;
|
|
||||||
|
|
||||||
string url = string.Empty, first = string.Empty, last = string.Empty, tmp = string.Empty;
|
|
||||||
Util.ParseUniversalUserIdentifier(_m.AgentID, out m.AgentID, out url, out first, out last, out tmp);
|
|
||||||
if (url != string.Empty)
|
|
||||||
m_UserManagement.AddUser(m.AgentID, first, last, url);
|
|
||||||
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
public GroupRoleMembersData ConvertGroupRoleMembersData(ExtendedGroupRoleMembersData _rm)
|
|
||||||
{
|
|
||||||
GroupRoleMembersData rm = new GroupRoleMembersData();
|
|
||||||
rm.RoleID = _rm.RoleID;
|
|
||||||
|
|
||||||
string url = string.Empty, first = string.Empty, last = string.Empty, tmp = string.Empty;
|
|
||||||
Util.ParseUniversalUserIdentifier(_rm.MemberID, out rm.MemberID, out url, out first, out last, out tmp);
|
|
||||||
if (url != string.Empty)
|
|
||||||
m_UserManagement.AddUser(rm.MemberID, first, last, url);
|
|
||||||
|
|
||||||
return rm;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,533 +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 OpenSim.Framework;
|
|
||||||
using OpenMetaverse;
|
|
||||||
|
|
||||||
namespace OpenSim.Groups
|
|
||||||
{
|
|
||||||
public class ExtendedGroupRecord : GroupRecord
|
|
||||||
{
|
|
||||||
public int MemberCount;
|
|
||||||
public int RoleCount;
|
|
||||||
public string ServiceLocation;
|
|
||||||
public string FounderUUI;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ExtendedGroupMembershipData : GroupMembershipData
|
|
||||||
{
|
|
||||||
public string AccessToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ExtendedGroupMembersData
|
|
||||||
{
|
|
||||||
// This is the only difference: this is a string
|
|
||||||
public string AgentID;
|
|
||||||
public int Contribution;
|
|
||||||
public string OnlineStatus;
|
|
||||||
public ulong AgentPowers;
|
|
||||||
public string Title;
|
|
||||||
public bool IsOwner;
|
|
||||||
public bool ListInProfile;
|
|
||||||
public bool AcceptNotices;
|
|
||||||
public string AccessToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ExtendedGroupRoleMembersData
|
|
||||||
{
|
|
||||||
public UUID RoleID;
|
|
||||||
// This is the only difference: this is a string
|
|
||||||
public string MemberID;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct ExtendedGroupNoticeData
|
|
||||||
{
|
|
||||||
public UUID NoticeID;
|
|
||||||
public uint Timestamp;
|
|
||||||
public string FromName;
|
|
||||||
public string Subject;
|
|
||||||
public bool HasAttachment;
|
|
||||||
public byte AttachmentType;
|
|
||||||
public string AttachmentName;
|
|
||||||
public UUID AttachmentItemID;
|
|
||||||
public string AttachmentOwnerID;
|
|
||||||
|
|
||||||
public GroupNoticeData ToGroupNoticeData()
|
|
||||||
{
|
|
||||||
GroupNoticeData n = new GroupNoticeData();
|
|
||||||
n.FromName = this.FromName;
|
|
||||||
n.AssetType = this.AttachmentType;
|
|
||||||
n.HasAttachment = this.HasAttachment;
|
|
||||||
n.NoticeID = this.NoticeID;
|
|
||||||
n.Subject = this.Subject;
|
|
||||||
n.Timestamp = this.Timestamp;
|
|
||||||
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class GroupsDataUtils
|
|
||||||
{
|
|
||||||
public static string Sanitize(string s)
|
|
||||||
{
|
|
||||||
return s == null ? string.Empty : s;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Dictionary<string, object> GroupRecord(ExtendedGroupRecord grec)
|
|
||||||
{
|
|
||||||
Dictionary<string, object> dict = new Dictionary<string, object>();
|
|
||||||
if (grec == null)
|
|
||||||
return dict;
|
|
||||||
|
|
||||||
dict["AllowPublish"] = grec.AllowPublish.ToString();
|
|
||||||
dict["Charter"] = Sanitize(grec.Charter);
|
|
||||||
dict["FounderID"] = grec.FounderID.ToString();
|
|
||||||
dict["FounderUUI"] = Sanitize(grec.FounderUUI);
|
|
||||||
dict["GroupID"] = grec.GroupID.ToString();
|
|
||||||
dict["GroupName"] = Sanitize(grec.GroupName);
|
|
||||||
dict["InsigniaID"] = grec.GroupPicture.ToString();
|
|
||||||
dict["MaturePublish"] = grec.MaturePublish.ToString();
|
|
||||||
dict["MembershipFee"] = grec.MembershipFee.ToString();
|
|
||||||
dict["OpenEnrollment"] = grec.OpenEnrollment.ToString();
|
|
||||||
dict["OwnerRoleID"] = grec.OwnerRoleID.ToString();
|
|
||||||
dict["ServiceLocation"] = Sanitize(grec.ServiceLocation);
|
|
||||||
dict["ShownInList"] = grec.ShowInList.ToString();
|
|
||||||
dict["MemberCount"] = grec.MemberCount.ToString();
|
|
||||||
dict["RoleCount"] = grec.RoleCount.ToString();
|
|
||||||
|
|
||||||
return dict;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ExtendedGroupRecord GroupRecord(Dictionary<string, object> dict)
|
|
||||||
{
|
|
||||||
if (dict == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
ExtendedGroupRecord grec = new ExtendedGroupRecord();
|
|
||||||
if (dict.ContainsKey("AllowPublish") && dict["AllowPublish"] != null)
|
|
||||||
grec.AllowPublish = bool.Parse(dict["AllowPublish"].ToString());
|
|
||||||
|
|
||||||
if (dict.ContainsKey("Charter") && dict["Charter"] != null)
|
|
||||||
grec.Charter = dict["Charter"].ToString();
|
|
||||||
else
|
|
||||||
grec.Charter = string.Empty;
|
|
||||||
|
|
||||||
if (dict.ContainsKey("FounderID") && dict["FounderID"] != null)
|
|
||||||
grec.FounderID = UUID.Parse(dict["FounderID"].ToString());
|
|
||||||
|
|
||||||
if (dict.ContainsKey("FounderUUI") && dict["FounderUUI"] != null)
|
|
||||||
grec.FounderUUI = dict["FounderUUI"].ToString();
|
|
||||||
else
|
|
||||||
grec.FounderUUI = string.Empty;
|
|
||||||
|
|
||||||
if (dict.ContainsKey("GroupID") && dict["GroupID"] != null)
|
|
||||||
grec.GroupID = UUID.Parse(dict["GroupID"].ToString());
|
|
||||||
|
|
||||||
if (dict.ContainsKey("GroupName") && dict["GroupName"] != null)
|
|
||||||
grec.GroupName = dict["GroupName"].ToString();
|
|
||||||
else
|
|
||||||
grec.GroupName = string.Empty;
|
|
||||||
|
|
||||||
if (dict.ContainsKey("InsigniaID") && dict["InsigniaID"] != null)
|
|
||||||
grec.GroupPicture = UUID.Parse(dict["InsigniaID"].ToString());
|
|
||||||
|
|
||||||
if (dict.ContainsKey("MaturePublish") && dict["MaturePublish"] != null)
|
|
||||||
grec.MaturePublish = bool.Parse(dict["MaturePublish"].ToString());
|
|
||||||
|
|
||||||
if (dict.ContainsKey("MembershipFee") && dict["MembershipFee"] != null)
|
|
||||||
grec.MembershipFee = Int32.Parse(dict["MembershipFee"].ToString());
|
|
||||||
|
|
||||||
if (dict.ContainsKey("OpenEnrollment") && dict["OpenEnrollment"] != null)
|
|
||||||
grec.OpenEnrollment = bool.Parse(dict["OpenEnrollment"].ToString());
|
|
||||||
|
|
||||||
if (dict.ContainsKey("OwnerRoleID") && dict["OwnerRoleID"] != null)
|
|
||||||
grec.OwnerRoleID = UUID.Parse(dict["OwnerRoleID"].ToString());
|
|
||||||
|
|
||||||
if (dict.ContainsKey("ServiceLocation") && dict["ServiceLocation"] != null)
|
|
||||||
grec.ServiceLocation = dict["ServiceLocation"].ToString();
|
|
||||||
else
|
|
||||||
grec.ServiceLocation = string.Empty;
|
|
||||||
|
|
||||||
if (dict.ContainsKey("ShownInList") && dict["ShownInList"] != null)
|
|
||||||
grec.ShowInList = bool.Parse(dict["ShownInList"].ToString());
|
|
||||||
|
|
||||||
if (dict.ContainsKey("MemberCount") && dict["MemberCount"] != null)
|
|
||||||
grec.MemberCount = Int32.Parse(dict["MemberCount"].ToString());
|
|
||||||
|
|
||||||
if (dict.ContainsKey("RoleCount") && dict["RoleCount"] != null)
|
|
||||||
grec.RoleCount = Int32.Parse(dict["RoleCount"].ToString());
|
|
||||||
|
|
||||||
return grec;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Dictionary<string, object> GroupMembershipData(ExtendedGroupMembershipData membership)
|
|
||||||
{
|
|
||||||
Dictionary<string, object> dict = new Dictionary<string, object>();
|
|
||||||
if (membership == null)
|
|
||||||
return dict;
|
|
||||||
|
|
||||||
dict["AcceptNotices"] = membership.AcceptNotices.ToString();
|
|
||||||
dict["AccessToken"] = Sanitize(membership.AccessToken);
|
|
||||||
dict["Active"] = membership.Active.ToString();
|
|
||||||
dict["ActiveRole"] = membership.ActiveRole.ToString();
|
|
||||||
dict["AllowPublish"] = membership.AllowPublish.ToString();
|
|
||||||
dict["Charter"] = Sanitize(membership.Charter);
|
|
||||||
dict["Contribution"] = membership.Contribution.ToString();
|
|
||||||
dict["FounderID"] = membership.FounderID.ToString();
|
|
||||||
dict["GroupID"] = membership.GroupID.ToString();
|
|
||||||
dict["GroupName"] = Sanitize(membership.GroupName);
|
|
||||||
dict["GroupPicture"] = membership.GroupPicture.ToString();
|
|
||||||
dict["GroupPowers"] = membership.GroupPowers.ToString();
|
|
||||||
dict["GroupTitle"] = Sanitize(membership.GroupTitle);
|
|
||||||
dict["ListInProfile"] = membership.ListInProfile.ToString();
|
|
||||||
dict["MaturePublish"] = membership.MaturePublish.ToString();
|
|
||||||
dict["MembershipFee"] = membership.MembershipFee.ToString();
|
|
||||||
dict["OpenEnrollment"] = membership.OpenEnrollment.ToString();
|
|
||||||
dict["ShowInList"] = membership.ShowInList.ToString();
|
|
||||||
|
|
||||||
return dict;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ExtendedGroupMembershipData GroupMembershipData(Dictionary<string, object> dict)
|
|
||||||
{
|
|
||||||
if (dict == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
ExtendedGroupMembershipData membership = new ExtendedGroupMembershipData();
|
|
||||||
|
|
||||||
if (dict.ContainsKey("AcceptNotices") && dict["AcceptNotices"] != null)
|
|
||||||
membership.AcceptNotices = bool.Parse(dict["AcceptNotices"].ToString());
|
|
||||||
|
|
||||||
if (dict.ContainsKey("AccessToken") && dict["AccessToken"] != null)
|
|
||||||
membership.AccessToken = dict["AccessToken"].ToString();
|
|
||||||
else
|
|
||||||
membership.AccessToken = string.Empty;
|
|
||||||
|
|
||||||
if (dict.ContainsKey("Active") && dict["Active"] != null)
|
|
||||||
membership.Active = bool.Parse(dict["Active"].ToString());
|
|
||||||
|
|
||||||
if (dict.ContainsKey("ActiveRole") && dict["ActiveRole"] != null)
|
|
||||||
membership.ActiveRole = UUID.Parse(dict["ActiveRole"].ToString());
|
|
||||||
|
|
||||||
if (dict.ContainsKey("AllowPublish") && dict["AllowPublish"] != null)
|
|
||||||
membership.AllowPublish = bool.Parse(dict["AllowPublish"].ToString());
|
|
||||||
|
|
||||||
if (dict.ContainsKey("Charter") && dict["Charter"] != null)
|
|
||||||
membership.Charter = dict["Charter"].ToString();
|
|
||||||
else
|
|
||||||
membership.Charter = string.Empty;
|
|
||||||
|
|
||||||
if (dict.ContainsKey("Contribution") && dict["Contribution"] != null)
|
|
||||||
membership.Contribution = Int32.Parse(dict["Contribution"].ToString());
|
|
||||||
|
|
||||||
if (dict.ContainsKey("FounderID") && dict["FounderID"] != null)
|
|
||||||
membership.FounderID = UUID.Parse(dict["FounderID"].ToString());
|
|
||||||
|
|
||||||
if (dict.ContainsKey("GroupID") && dict["GroupID"] != null)
|
|
||||||
membership.GroupID = UUID.Parse(dict["GroupID"].ToString());
|
|
||||||
|
|
||||||
if (dict.ContainsKey("GroupName") && dict["GroupName"] != null)
|
|
||||||
membership.GroupName = dict["GroupName"].ToString();
|
|
||||||
else
|
|
||||||
membership.GroupName = string.Empty;
|
|
||||||
|
|
||||||
if (dict.ContainsKey("GroupPicture") && dict["GroupPicture"] != null)
|
|
||||||
membership.GroupPicture = UUID.Parse(dict["GroupPicture"].ToString());
|
|
||||||
|
|
||||||
if (dict.ContainsKey("GroupPowers") && dict["GroupPowers"] != null)
|
|
||||||
membership.GroupPowers = UInt64.Parse(dict["GroupPowers"].ToString());
|
|
||||||
|
|
||||||
if (dict.ContainsKey("GroupTitle") && dict["GroupTitle"] != null)
|
|
||||||
membership.GroupTitle = dict["GroupTitle"].ToString();
|
|
||||||
else
|
|
||||||
membership.GroupTitle = string.Empty;
|
|
||||||
|
|
||||||
if (dict.ContainsKey("ListInProfile") && dict["ListInProfile"] != null)
|
|
||||||
membership.ListInProfile = bool.Parse(dict["ListInProfile"].ToString());
|
|
||||||
|
|
||||||
if (dict.ContainsKey("MaturePublish") && dict["MaturePublish"] != null)
|
|
||||||
membership.MaturePublish = bool.Parse(dict["MaturePublish"].ToString());
|
|
||||||
|
|
||||||
if (dict.ContainsKey("MembershipFee") && dict["MembershipFee"] != null)
|
|
||||||
membership.MembershipFee = Int32.Parse(dict["MembershipFee"].ToString());
|
|
||||||
|
|
||||||
if (dict.ContainsKey("OpenEnrollment") && dict["OpenEnrollment"] != null)
|
|
||||||
membership.OpenEnrollment = bool.Parse(dict["OpenEnrollment"].ToString());
|
|
||||||
|
|
||||||
if (dict.ContainsKey("ShowInList") && dict["ShowInList"] != null)
|
|
||||||
membership.ShowInList = bool.Parse(dict["ShowInList"].ToString());
|
|
||||||
|
|
||||||
return membership;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Dictionary<string, object> GroupMembersData(ExtendedGroupMembersData member)
|
|
||||||
{
|
|
||||||
Dictionary<string, object> dict = new Dictionary<string, object>();
|
|
||||||
|
|
||||||
dict["AcceptNotices"] = member.AcceptNotices.ToString();
|
|
||||||
dict["AccessToken"] = Sanitize(member.AccessToken);
|
|
||||||
dict["AgentID"] = Sanitize(member.AgentID);
|
|
||||||
dict["AgentPowers"] = member.AgentPowers.ToString();
|
|
||||||
dict["Contribution"] = member.Contribution.ToString();
|
|
||||||
dict["IsOwner"] = member.IsOwner.ToString();
|
|
||||||
dict["ListInProfile"] = member.ListInProfile.ToString();
|
|
||||||
dict["OnlineStatus"] = Sanitize(member.OnlineStatus);
|
|
||||||
dict["Title"] = Sanitize(member.Title);
|
|
||||||
|
|
||||||
return dict;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ExtendedGroupMembersData GroupMembersData(Dictionary<string, object> dict)
|
|
||||||
{
|
|
||||||
ExtendedGroupMembersData member = new ExtendedGroupMembersData();
|
|
||||||
|
|
||||||
if (dict == null)
|
|
||||||
return member;
|
|
||||||
|
|
||||||
if (dict.ContainsKey("AcceptNotices") && dict["AcceptNotices"] != null)
|
|
||||||
member.AcceptNotices = bool.Parse(dict["AcceptNotices"].ToString());
|
|
||||||
|
|
||||||
if (dict.ContainsKey("AccessToken") && dict["AccessToken"] != null)
|
|
||||||
member.AccessToken = Sanitize(dict["AccessToken"].ToString());
|
|
||||||
else
|
|
||||||
member.AccessToken = string.Empty;
|
|
||||||
|
|
||||||
if (dict.ContainsKey("AgentID") && dict["AgentID"] != null)
|
|
||||||
member.AgentID = Sanitize(dict["AgentID"].ToString());
|
|
||||||
else
|
|
||||||
member.AgentID = UUID.Zero.ToString();
|
|
||||||
|
|
||||||
if (dict.ContainsKey("AgentPowers") && dict["AgentPowers"] != null)
|
|
||||||
member.AgentPowers = UInt64.Parse(dict["AgentPowers"].ToString());
|
|
||||||
|
|
||||||
if (dict.ContainsKey("Contribution") && dict["Contribution"] != null)
|
|
||||||
member.Contribution = Int32.Parse(dict["Contribution"].ToString());
|
|
||||||
|
|
||||||
if (dict.ContainsKey("IsOwner") && dict["IsOwner"] != null)
|
|
||||||
member.IsOwner = bool.Parse(dict["IsOwner"].ToString());
|
|
||||||
|
|
||||||
if (dict.ContainsKey("ListInProfile") && dict["ListInProfile"] != null)
|
|
||||||
member.ListInProfile = bool.Parse(dict["ListInProfile"].ToString());
|
|
||||||
|
|
||||||
if (dict.ContainsKey("OnlineStatus") && dict["OnlineStatus"] != null)
|
|
||||||
member.OnlineStatus = Sanitize(dict["OnlineStatus"].ToString());
|
|
||||||
else
|
|
||||||
member.OnlineStatus = string.Empty;
|
|
||||||
|
|
||||||
if (dict.ContainsKey("Title") && dict["Title"] != null)
|
|
||||||
member.Title = Sanitize(dict["Title"].ToString());
|
|
||||||
else
|
|
||||||
member.Title = string.Empty;
|
|
||||||
|
|
||||||
return member;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Dictionary<string, object> GroupRolesData(GroupRolesData role)
|
|
||||||
{
|
|
||||||
Dictionary<string, object> dict = new Dictionary<string, object>();
|
|
||||||
|
|
||||||
dict["Description"] = Sanitize(role.Description);
|
|
||||||
dict["Members"] = role.Members.ToString();
|
|
||||||
dict["Name"] = Sanitize(role.Name);
|
|
||||||
dict["Powers"] = role.Powers.ToString();
|
|
||||||
dict["RoleID"] = role.RoleID.ToString();
|
|
||||||
dict["Title"] = Sanitize(role.Title);
|
|
||||||
|
|
||||||
return dict;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static GroupRolesData GroupRolesData(Dictionary<string, object> dict)
|
|
||||||
{
|
|
||||||
GroupRolesData role = new GroupRolesData();
|
|
||||||
|
|
||||||
if (dict == null)
|
|
||||||
return role;
|
|
||||||
|
|
||||||
if (dict.ContainsKey("Description") && dict["Description"] != null)
|
|
||||||
role.Description = Sanitize(dict["Description"].ToString());
|
|
||||||
else
|
|
||||||
role.Description = string.Empty;
|
|
||||||
|
|
||||||
if (dict.ContainsKey("Members") && dict["Members"] != null)
|
|
||||||
role.Members = Int32.Parse(dict["Members"].ToString());
|
|
||||||
|
|
||||||
if (dict.ContainsKey("Name") && dict["Name"] != null)
|
|
||||||
role.Name = Sanitize(dict["Name"].ToString());
|
|
||||||
else
|
|
||||||
role.Name = string.Empty;
|
|
||||||
|
|
||||||
if (dict.ContainsKey("Powers") && dict["Powers"] != null)
|
|
||||||
role.Powers = UInt64.Parse(dict["Powers"].ToString());
|
|
||||||
|
|
||||||
if (dict.ContainsKey("Title") && dict["Title"] != null)
|
|
||||||
role.Title = Sanitize(dict["Title"].ToString());
|
|
||||||
else
|
|
||||||
role.Title = string.Empty;
|
|
||||||
|
|
||||||
if (dict.ContainsKey("RoleID") && dict["RoleID"] != null)
|
|
||||||
role.RoleID = UUID.Parse(dict["RoleID"].ToString());
|
|
||||||
|
|
||||||
return role;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Dictionary<string, object> GroupRoleMembersData(ExtendedGroupRoleMembersData rmember)
|
|
||||||
{
|
|
||||||
Dictionary<string, object> dict = new Dictionary<string, object>();
|
|
||||||
|
|
||||||
dict["RoleID"] = rmember.RoleID.ToString();
|
|
||||||
dict["MemberID"] = rmember.MemberID;
|
|
||||||
return dict;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ExtendedGroupRoleMembersData GroupRoleMembersData(Dictionary<string, object> dict)
|
|
||||||
{
|
|
||||||
ExtendedGroupRoleMembersData rmember = new ExtendedGroupRoleMembersData();
|
|
||||||
|
|
||||||
if (dict.ContainsKey("RoleID") && dict["RoleID"] != null)
|
|
||||||
rmember.RoleID = new UUID(dict["RoleID"].ToString());
|
|
||||||
|
|
||||||
if (dict.ContainsKey("MemberID") && dict["MemberID"] != null)
|
|
||||||
rmember.MemberID = dict["MemberID"].ToString();
|
|
||||||
|
|
||||||
return rmember;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Dictionary<string, object> GroupInviteInfo(GroupInviteInfo invite)
|
|
||||||
{
|
|
||||||
Dictionary<string, object> dict = new Dictionary<string, object>();
|
|
||||||
|
|
||||||
dict["InviteID"] = invite.InviteID.ToString();
|
|
||||||
dict["GroupID"] = invite.GroupID.ToString();
|
|
||||||
dict["RoleID"] = invite.RoleID.ToString();
|
|
||||||
dict["AgentID"] = invite.AgentID;
|
|
||||||
|
|
||||||
return dict;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static GroupInviteInfo GroupInviteInfo(Dictionary<string, object> dict)
|
|
||||||
{
|
|
||||||
if (dict == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
GroupInviteInfo invite = new GroupInviteInfo();
|
|
||||||
|
|
||||||
invite.InviteID = new UUID(dict["InviteID"].ToString());
|
|
||||||
invite.GroupID = new UUID(dict["GroupID"].ToString());
|
|
||||||
invite.RoleID = new UUID(dict["RoleID"].ToString());
|
|
||||||
invite.AgentID = Sanitize(dict["AgentID"].ToString());
|
|
||||||
|
|
||||||
return invite;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Dictionary<string, object> GroupNoticeData(ExtendedGroupNoticeData notice)
|
|
||||||
{
|
|
||||||
Dictionary<string, object> dict = new Dictionary<string, object>();
|
|
||||||
|
|
||||||
dict["NoticeID"] = notice.NoticeID.ToString();
|
|
||||||
dict["Timestamp"] = notice.Timestamp.ToString();
|
|
||||||
dict["FromName"] = Sanitize(notice.FromName);
|
|
||||||
dict["Subject"] = Sanitize(notice.Subject);
|
|
||||||
dict["HasAttachment"] = notice.HasAttachment.ToString();
|
|
||||||
dict["AttachmentItemID"] = notice.AttachmentItemID.ToString();
|
|
||||||
dict["AttachmentName"] = Sanitize(notice.AttachmentName);
|
|
||||||
dict["AttachmentType"] = notice.AttachmentType.ToString();
|
|
||||||
dict["AttachmentOwnerID"] = Sanitize(notice.AttachmentOwnerID);
|
|
||||||
|
|
||||||
return dict;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ExtendedGroupNoticeData GroupNoticeData(Dictionary<string, object> dict)
|
|
||||||
{
|
|
||||||
ExtendedGroupNoticeData notice = new ExtendedGroupNoticeData();
|
|
||||||
|
|
||||||
if (dict == null)
|
|
||||||
return notice;
|
|
||||||
|
|
||||||
notice.NoticeID = new UUID(dict["NoticeID"].ToString());
|
|
||||||
notice.Timestamp = UInt32.Parse(dict["Timestamp"].ToString());
|
|
||||||
notice.FromName = Sanitize(dict["FromName"].ToString());
|
|
||||||
notice.Subject = Sanitize(dict["Subject"].ToString());
|
|
||||||
notice.HasAttachment = bool.Parse(dict["HasAttachment"].ToString());
|
|
||||||
notice.AttachmentItemID = new UUID(dict["AttachmentItemID"].ToString());
|
|
||||||
notice.AttachmentName = dict["AttachmentName"].ToString();
|
|
||||||
notice.AttachmentType = byte.Parse(dict["AttachmentType"].ToString());
|
|
||||||
notice.AttachmentOwnerID = dict["AttachmentOwnerID"].ToString();
|
|
||||||
|
|
||||||
return notice;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Dictionary<string, object> GroupNoticeInfo(GroupNoticeInfo notice)
|
|
||||||
{
|
|
||||||
Dictionary<string, object> dict = GroupNoticeData(notice.noticeData);
|
|
||||||
|
|
||||||
dict["GroupID"] = notice.GroupID.ToString();
|
|
||||||
dict["Message"] = Sanitize(notice.Message);
|
|
||||||
|
|
||||||
return dict;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static GroupNoticeInfo GroupNoticeInfo(Dictionary<string, object> dict)
|
|
||||||
{
|
|
||||||
GroupNoticeInfo notice = new GroupNoticeInfo();
|
|
||||||
|
|
||||||
notice.noticeData = GroupNoticeData(dict);
|
|
||||||
notice.GroupID = new UUID(dict["GroupID"].ToString());
|
|
||||||
notice.Message = Sanitize(dict["Message"].ToString());
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,841 +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.Reflection;
|
|
||||||
using log4net;
|
|
||||||
using Mono.Addins;
|
|
||||||
using Nini.Config;
|
|
||||||
using OpenMetaverse;
|
|
||||||
using OpenMetaverse.StructuredData;
|
|
||||||
using OpenSim.Framework;
|
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
|
||||||
using OpenSim.Region.Framework.Scenes;
|
|
||||||
using OpenSim.Services.Interfaces;
|
|
||||||
using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo;
|
|
||||||
using GridRegion = OpenSim.Services.Interfaces.GridRegion;
|
|
||||||
|
|
||||||
namespace OpenSim.Groups
|
|
||||||
{
|
|
||||||
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GroupsMessagingModule")]
|
|
||||||
public class GroupsMessagingModule : ISharedRegionModule, IGroupsMessagingModule
|
|
||||||
{
|
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
|
||||||
|
|
||||||
private List<Scene> m_sceneList = new List<Scene>();
|
|
||||||
private IPresenceService m_presenceService;
|
|
||||||
|
|
||||||
private IMessageTransferModule m_msgTransferModule = null;
|
|
||||||
private IUserManagement m_UserManagement = null;
|
|
||||||
private IGroupsServicesConnector m_groupData = null;
|
|
||||||
|
|
||||||
// Config Options
|
|
||||||
private bool m_groupMessagingEnabled;
|
|
||||||
private bool m_debugEnabled;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// If enabled, module only tries to send group IMs to online users by querying cached presence information.
|
|
||||||
/// </summary>
|
|
||||||
private bool m_messageOnlineAgentsOnly;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Cache for online users.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// Group ID is key, presence information for online members is value.
|
|
||||||
/// Will only be non-null if m_messageOnlineAgentsOnly = true
|
|
||||||
/// We cache here so that group messages don't constantly have to re-request the online user list to avoid
|
|
||||||
/// attempted expensive sending of messages to offline users.
|
|
||||||
/// The tradeoff is that a user that comes online will not receive messages consistently from all other users
|
|
||||||
/// until caches have updated.
|
|
||||||
/// Therefore, we set the cache expiry to just 20 seconds.
|
|
||||||
/// </remarks>
|
|
||||||
private ExpiringCache<UUID, PresenceInfo[]> m_usersOnlineCache;
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
public void Initialise(IConfigSource config)
|
|
||||||
{
|
|
||||||
IConfig groupsConfig = config.Configs["Groups"];
|
|
||||||
|
|
||||||
if (groupsConfig == null)
|
|
||||||
// Do not run this module by default.
|
|
||||||
return;
|
|
||||||
|
|
||||||
// if groups aren't enabled, we're not needed.
|
|
||||||
// if we're not specified as the connector to use, then we're not wanted
|
|
||||||
if ((groupsConfig.GetBoolean("Enabled", false) == false)
|
|
||||||
|| (groupsConfig.GetString("MessagingModule", "") != Name))
|
|
||||||
{
|
|
||||||
m_groupMessagingEnabled = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_groupMessagingEnabled = groupsConfig.GetBoolean("MessagingEnabled", true);
|
|
||||||
|
|
||||||
if (!m_groupMessagingEnabled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_messageOnlineAgentsOnly = groupsConfig.GetBoolean("MessageOnlineUsersOnly", false);
|
|
||||||
|
|
||||||
if (m_messageOnlineAgentsOnly)
|
|
||||||
{
|
|
||||||
m_usersOnlineCache = new ExpiringCache<UUID, PresenceInfo[]>();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_log.Error("[Groups.Messaging]: GroupsMessagingModule V2 requires MessageOnlineUsersOnly = true");
|
|
||||||
m_groupMessagingEnabled = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_debugEnabled = groupsConfig.GetBoolean("MessagingDebugEnabled", m_debugEnabled);
|
|
||||||
|
|
||||||
m_log.InfoFormat(
|
|
||||||
"[Groups.Messaging]: GroupsMessagingModule enabled with MessageOnlineOnly = {0}, DebugEnabled = {1}",
|
|
||||||
m_messageOnlineAgentsOnly, m_debugEnabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void AddRegion(Scene scene)
|
|
||||||
{
|
|
||||||
if (!m_groupMessagingEnabled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
scene.RegisterModuleInterface<IGroupsMessagingModule>(this);
|
|
||||||
m_sceneList.Add(scene);
|
|
||||||
|
|
||||||
scene.EventManager.OnNewClient += OnNewClient;
|
|
||||||
scene.EventManager.OnMakeRootAgent += OnMakeRootAgent;
|
|
||||||
scene.EventManager.OnMakeChildAgent += OnMakeChildAgent;
|
|
||||||
scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage;
|
|
||||||
scene.EventManager.OnClientLogin += OnClientLogin;
|
|
||||||
|
|
||||||
scene.AddCommand(
|
|
||||||
"Debug",
|
|
||||||
this,
|
|
||||||
"debug groups messaging verbose",
|
|
||||||
"debug groups messaging verbose <true|false>",
|
|
||||||
"This setting turns on very verbose groups messaging debugging",
|
|
||||||
HandleDebugGroupsMessagingVerbose);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RegionLoaded(Scene scene)
|
|
||||||
{
|
|
||||||
if (!m_groupMessagingEnabled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
|
|
||||||
|
|
||||||
m_groupData = scene.RequestModuleInterface<IGroupsServicesConnector>();
|
|
||||||
|
|
||||||
// No groups module, no groups messaging
|
|
||||||
if (m_groupData == null)
|
|
||||||
{
|
|
||||||
m_log.Error("[Groups.Messaging]: Could not get IGroupsServicesConnector, GroupsMessagingModule is now disabled.");
|
|
||||||
RemoveRegion(scene);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_msgTransferModule = scene.RequestModuleInterface<IMessageTransferModule>();
|
|
||||||
|
|
||||||
// No message transfer module, no groups messaging
|
|
||||||
if (m_msgTransferModule == null)
|
|
||||||
{
|
|
||||||
m_log.Error("[Groups.Messaging]: Could not get MessageTransferModule");
|
|
||||||
RemoveRegion(scene);
|
|
||||||
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)
|
|
||||||
m_presenceService = scene.PresenceService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RemoveRegion(Scene scene)
|
|
||||||
{
|
|
||||||
if (!m_groupMessagingEnabled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
|
|
||||||
|
|
||||||
m_sceneList.Remove(scene);
|
|
||||||
scene.EventManager.OnNewClient -= OnNewClient;
|
|
||||||
scene.EventManager.OnIncomingInstantMessage -= OnGridInstantMessage;
|
|
||||||
scene.EventManager.OnClientLogin -= OnClientLogin;
|
|
||||||
scene.UnregisterModuleInterface<IGroupsMessagingModule>(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Close()
|
|
||||||
{
|
|
||||||
if (!m_groupMessagingEnabled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (m_debugEnabled) m_log.Debug("[Groups.Messaging]: Shutting down GroupsMessagingModule module.");
|
|
||||||
|
|
||||||
m_sceneList.Clear();
|
|
||||||
|
|
||||||
m_groupData = null;
|
|
||||||
m_msgTransferModule = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Type ReplaceableInterface
|
|
||||||
{
|
|
||||||
get { return null; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Name
|
|
||||||
{
|
|
||||||
get { return "Groups Messaging Module V2"; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public void PostInitialise()
|
|
||||||
{
|
|
||||||
// NoOp
|
|
||||||
}
|
|
||||||
|
|
||||||
#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>
|
|
||||||
/// Not really needed, but does confirm that the group exists.
|
|
||||||
/// </summary>
|
|
||||||
public bool StartGroupChatSession(UUID agentID, UUID groupID)
|
|
||||||
{
|
|
||||||
if (m_debugEnabled)
|
|
||||||
m_log.DebugFormat("[Groups.Messaging]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
|
|
||||||
|
|
||||||
GroupRecord groupInfo = m_groupData.GetGroupRecord(agentID.ToString(), groupID, null);
|
|
||||||
|
|
||||||
if (groupInfo != null)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SendMessageToGroup(GridInstantMessage im, UUID groupID)
|
|
||||||
{
|
|
||||||
SendMessageToGroup(im, groupID, UUID.Zero, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SendMessageToGroup(
|
|
||||||
GridInstantMessage im, UUID groupID, UUID sendingAgentForGroupCalls, Func<GroupMembersData, bool> sendCondition)
|
|
||||||
{
|
|
||||||
int requestStartTick = Environment.TickCount;
|
|
||||||
|
|
||||||
UUID fromAgentID = new UUID(im.fromAgentID);
|
|
||||||
|
|
||||||
// Unlike current XmlRpcGroups, Groups V2 can accept UUID.Zero when a perms check for the requesting agent
|
|
||||||
// is not necessary.
|
|
||||||
List<GroupMembersData> groupMembers = m_groupData.GetGroupMembers(UUID.Zero.ToString(), groupID);
|
|
||||||
|
|
||||||
int groupMembersCount = groupMembers.Count;
|
|
||||||
PresenceInfo[] onlineAgents = null;
|
|
||||||
|
|
||||||
// In V2 we always only send to online members.
|
|
||||||
// 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);
|
|
||||||
m_usersOnlineCache.Add(groupID, onlineAgents, m_usersOnlineCacheExpirySeconds);
|
|
||||||
}
|
|
||||||
|
|
||||||
HashSet<string> onlineAgentsUuidSet = new HashSet<string>();
|
|
||||||
Array.ForEach<PresenceInfo>(onlineAgents, pi => onlineAgentsUuidSet.Add(pi.UserID));
|
|
||||||
|
|
||||||
groupMembers = groupMembers.Where(gmd => onlineAgentsUuidSet.Contains(gmd.AgentID.ToString())).ToList();
|
|
||||||
|
|
||||||
// if (m_debugEnabled)
|
|
||||||
// m_log.DebugFormat(
|
|
||||||
// "[Groups.Messaging]: SendMessageToGroup called for group {0} with {1} visible members, {2} online",
|
|
||||||
// groupID, groupMembersCount, groupMembers.Count());
|
|
||||||
|
|
||||||
im.imSessionID = groupID.Guid;
|
|
||||||
im.fromGroup = true;
|
|
||||||
IClientAPI thisClient = GetActiveClient(fromAgentID);
|
|
||||||
if (thisClient != null)
|
|
||||||
{
|
|
||||||
im.RegionID = thisClient.Scene.RegionInfo.RegionID.Guid;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((im.binaryBucket == null) || (im.binaryBucket.Length == 0) || ((im.binaryBucket.Length == 1 && im.binaryBucket[0] == 0)))
|
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
if (member.AgentID.Guid == im.fromAgentID)
|
|
||||||
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
|
|
||||||
if (m_debugEnabled)
|
|
||||||
m_log.DebugFormat("[Groups.Messaging]: {0} has dropped session, not delivering to them", member.AgentID);
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
im.toAgentID = member.AgentID.Guid;
|
|
||||||
|
|
||||||
IClientAPI client = GetActiveClient(member.AgentID);
|
|
||||||
if (client == null)
|
|
||||||
{
|
|
||||||
// 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);
|
|
||||||
|
|
||||||
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
|
|
||||||
{
|
|
||||||
// Deliver locally, directly
|
|
||||||
if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Passing to ProcessMessageFromGroupSession to deliver to {0} locally", client.Name);
|
|
||||||
|
|
||||||
ProcessMessageFromGroupSession(im);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_debugEnabled)
|
|
||||||
m_log.DebugFormat(
|
|
||||||
"[Groups.Messaging]: SendMessageToGroup for group {0} with {1} visible members, {2} online took {3}ms",
|
|
||||||
groupID, groupMembersCount, groupMembers.Count(), Environment.TickCount - requestStartTick);
|
|
||||||
}
|
|
||||||
|
|
||||||
#region SimGridEventHandlers
|
|
||||||
|
|
||||||
void OnClientLogin(IClientAPI client)
|
|
||||||
{
|
|
||||||
if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: OnInstantMessage registered for {0}", client.Name);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnNewClient(IClientAPI client)
|
|
||||||
{
|
|
||||||
if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: OnInstantMessage registered for {0}", client.Name);
|
|
||||||
|
|
||||||
ResetAgentGroupChatSessions(client.AgentId.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnMakeRootAgent(ScenePresence sp)
|
|
||||||
{
|
|
||||||
sp.ControllingClient.OnInstantMessage += OnInstantMessage;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnMakeChildAgent(ScenePresence sp)
|
|
||||||
{
|
|
||||||
sp.ControllingClient.OnInstantMessage -= OnInstantMessage;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void OnGridInstantMessage(GridInstantMessage msg)
|
|
||||||
{
|
|
||||||
// The instant message module will only deliver messages of dialog types:
|
|
||||||
// MessageFromAgent, StartTyping, StopTyping, MessageFromObject
|
|
||||||
//
|
|
||||||
// Any other message type will not be delivered to a client by the
|
|
||||||
// Instant Message Module
|
|
||||||
|
|
||||||
UUID regionID = new UUID(msg.RegionID);
|
|
||||||
if (m_debugEnabled)
|
|
||||||
{
|
|
||||||
m_log.DebugFormat("[Groups.Messaging]: {0} called, IM from region {1}",
|
|
||||||
System.Reflection.MethodBase.GetCurrentMethod().Name, regionID);
|
|
||||||
|
|
||||||
DebugGridInstantMessage(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Incoming message from a group
|
|
||||||
if ((msg.fromGroup == true) && (msg.dialog == (byte)InstantMessageDialog.SessionSend))
|
|
||||||
{
|
|
||||||
// We have to redistribute the message across all members of the group who are here
|
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ProcessMessageFromGroupSession(GridInstantMessage msg)
|
|
||||||
{
|
|
||||||
if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Session message from {0} going to agent {1}", msg.fromAgentName, msg.toAgentID);
|
|
||||||
|
|
||||||
UUID AgentID = new UUID(msg.fromAgentID);
|
|
||||||
UUID GroupID = new UUID(msg.imSessionID);
|
|
||||||
UUID toAgentID = new UUID(msg.toAgentID);
|
|
||||||
|
|
||||||
switch (msg.dialog)
|
|
||||||
{
|
|
||||||
case (byte)InstantMessageDialog.SessionAdd:
|
|
||||||
AgentInvitedToGroupChatSession(AgentID.ToString(), GroupID);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case (byte)InstantMessageDialog.SessionDrop:
|
|
||||||
AgentDroppedFromGroupChatSession(AgentID.ToString(), GroupID);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case (byte)InstantMessageDialog.SessionSend:
|
|
||||||
// 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);
|
|
||||||
|
|
||||||
if (!hasAgentDroppedGroupChatSession(toAgentID.ToString(), GroupID))
|
|
||||||
{
|
|
||||||
if (!hasAgentBeenInvitedToGroupChatSession(toAgentID.ToString(), GroupID))
|
|
||||||
// This actually sends the message too, so no need to resend it
|
|
||||||
// with client.SendInstantMessage
|
|
||||||
AddAgentToSession(toAgentID, GroupID, msg);
|
|
||||||
else
|
|
||||||
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;
|
|
||||||
|
|
||||||
default:
|
|
||||||
m_log.WarnFormat("[Groups.Messaging]: I don't know how to proccess a {0} message.", ((InstantMessageDialog)msg.dialog).ToString());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
|
|
||||||
#region ClientEvents
|
|
||||||
private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im)
|
|
||||||
{
|
|
||||||
if (m_debugEnabled)
|
|
||||||
{
|
|
||||||
m_log.DebugFormat("[Groups.Messaging]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
|
|
||||||
|
|
||||||
DebugGridInstantMessage(im);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start group IM session
|
|
||||||
if ((im.dialog == (byte)InstantMessageDialog.SessionGroupStart))
|
|
||||||
{
|
|
||||||
if (m_debugEnabled) m_log.InfoFormat("[Groups.Messaging]: imSessionID({0}) toAgentID({1})", im.imSessionID, im.toAgentID);
|
|
||||||
|
|
||||||
UUID GroupID = new UUID(im.imSessionID);
|
|
||||||
UUID AgentID = new UUID(im.fromAgentID);
|
|
||||||
|
|
||||||
GroupRecord groupInfo = m_groupData.GetGroupRecord(UUID.Zero.ToString(), GroupID, null);
|
|
||||||
|
|
||||||
if (groupInfo != null)
|
|
||||||
{
|
|
||||||
AgentInvitedToGroupChatSession(AgentID.ToString(), GroupID);
|
|
||||||
|
|
||||||
ChatterBoxSessionStartReplyViaCaps(remoteClient, groupInfo.GroupName, GroupID);
|
|
||||||
|
|
||||||
IEventQueue queue = remoteClient.Scene.RequestModuleInterface<IEventQueue>();
|
|
||||||
if (queue != null)
|
|
||||||
{
|
|
||||||
var update = new GroupChatListAgentUpdateData(AgentID);
|
|
||||||
var updates = new List<GroupChatListAgentUpdateData> { update };
|
|
||||||
queue.ChatterBoxSessionAgentListUpdates(GroupID, remoteClient.AgentId, updates);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send a message from locally connected client to a group
|
|
||||||
if ((im.dialog == (byte)InstantMessageDialog.SessionSend))
|
|
||||||
{
|
|
||||||
UUID GroupID = new UUID(im.imSessionID);
|
|
||||||
UUID AgentID = new UUID(im.fromAgentID);
|
|
||||||
|
|
||||||
if (m_debugEnabled)
|
|
||||||
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
|
|
||||||
AgentInvitedToGroupChatSession(AgentID.ToString(), GroupID);
|
|
||||||
|
|
||||||
SendMessageToGroup(im, GroupID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
void ChatterBoxSessionStartReplyViaCaps(IClientAPI remoteClient, string groupName, UUID groupID)
|
|
||||||
{
|
|
||||||
if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
|
|
||||||
|
|
||||||
OSDMap moderatedMap = new OSDMap(4);
|
|
||||||
moderatedMap.Add("voice", OSD.FromBoolean(false));
|
|
||||||
|
|
||||||
OSDMap sessionMap = new OSDMap(4);
|
|
||||||
sessionMap.Add("moderated_mode", moderatedMap);
|
|
||||||
sessionMap.Add("session_name", OSD.FromString(groupName));
|
|
||||||
sessionMap.Add("type", OSD.FromInteger(0));
|
|
||||||
sessionMap.Add("voice_enabled", OSD.FromBoolean(false));
|
|
||||||
|
|
||||||
OSDMap bodyMap = new OSDMap(4);
|
|
||||||
bodyMap.Add("session_id", OSD.FromUUID(groupID));
|
|
||||||
bodyMap.Add("temp_session_id", OSD.FromUUID(groupID));
|
|
||||||
bodyMap.Add("success", OSD.FromBoolean(true));
|
|
||||||
bodyMap.Add("session_info", sessionMap);
|
|
||||||
|
|
||||||
IEventQueue queue = remoteClient.Scene.RequestModuleInterface<IEventQueue>();
|
|
||||||
queue?.Enqueue(queue.BuildEvent("ChatterBoxSessionStartReply", bodyMap), remoteClient.AgentId);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void DebugGridInstantMessage(GridInstantMessage im)
|
|
||||||
{
|
|
||||||
// Don't log any normal IMs (privacy!)
|
|
||||||
if (m_debugEnabled && im.dialog != (byte)InstantMessageDialog.MessageFromAgent)
|
|
||||||
{
|
|
||||||
m_log.WarnFormat("[Groups.Messaging]: IM: fromGroup({0})", im.fromGroup ? "True" : "False");
|
|
||||||
m_log.WarnFormat("[Groups.Messaging]: IM: Dialog({0})", ((InstantMessageDialog)im.dialog).ToString());
|
|
||||||
m_log.WarnFormat("[Groups.Messaging]: IM: fromAgentID({0})", im.fromAgentID.ToString());
|
|
||||||
m_log.WarnFormat("[Groups.Messaging]: IM: fromAgentName({0})", im.fromAgentName.ToString());
|
|
||||||
m_log.WarnFormat("[Groups.Messaging]: IM: imSessionID({0})", im.imSessionID.ToString());
|
|
||||||
m_log.WarnFormat("[Groups.Messaging]: IM: message({0})", im.message.ToString());
|
|
||||||
m_log.WarnFormat("[Groups.Messaging]: IM: offline({0})", im.offline.ToString());
|
|
||||||
m_log.WarnFormat("[Groups.Messaging]: IM: toAgentID({0})", im.toAgentID.ToString());
|
|
||||||
m_log.WarnFormat("[Groups.Messaging]: IM: binaryBucket({0})", OpenMetaverse.Utils.BytesToHexString(im.binaryBucket, "BinaryBucket"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#region Client Tools
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Try to find an active IClientAPI reference for agentID giving preference to root connections
|
|
||||||
/// </summary>
|
|
||||||
private IClientAPI GetActiveClient(UUID agentID)
|
|
||||||
{
|
|
||||||
if (m_debugEnabled) m_log.WarnFormat("[Groups.Messaging]: Looking for local client {0}", agentID);
|
|
||||||
|
|
||||||
IClientAPI child = null;
|
|
||||||
|
|
||||||
// Try root avatar first
|
|
||||||
foreach (Scene scene in m_sceneList)
|
|
||||||
{
|
|
||||||
ScenePresence sp = scene.GetScenePresence(agentID);
|
|
||||||
if (sp != null)
|
|
||||||
{
|
|
||||||
if (!sp.IsChildAgent)
|
|
||||||
{
|
|
||||||
if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Found root agent for client : {0}", sp.ControllingClient.Name);
|
|
||||||
return sp.ControllingClient;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Found child agent for client : {0}", sp.ControllingClient.Name);
|
|
||||||
child = sp.ControllingClient;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we didn't find a root, then just return whichever child we found, or null if none
|
|
||||||
if (child == null)
|
|
||||||
{
|
|
||||||
if (m_debugEnabled) m_log.WarnFormat("[Groups.Messaging]: Could not find local client for agent : {0}", agentID);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (m_debugEnabled) m_log.WarnFormat("[Groups.Messaging]: Returning child agent for client : {0}", child.Name);
|
|
||||||
}
|
|
||||||
return child;
|
|
||||||
}
|
|
||||||
|
|
||||||
#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
|
@ -1,289 +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.Reflection;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
using OpenSim.Framework;
|
|
||||||
using OpenSim.Server.Base;
|
|
||||||
|
|
||||||
using OpenMetaverse;
|
|
||||||
using log4net;
|
|
||||||
|
|
||||||
namespace OpenSim.Groups
|
|
||||||
{
|
|
||||||
public class GroupsServiceHGConnector
|
|
||||||
{
|
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
|
||||||
|
|
||||||
private string m_ServerURI;
|
|
||||||
private object m_Lock = new object();
|
|
||||||
|
|
||||||
public GroupsServiceHGConnector(string url)
|
|
||||||
{
|
|
||||||
m_ServerURI = url;
|
|
||||||
if (!m_ServerURI.EndsWith("/"))
|
|
||||||
m_ServerURI += "/";
|
|
||||||
|
|
||||||
m_log.DebugFormat("[Groups.HGConnector]: Groups server at {0}", m_ServerURI);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool CreateProxy(string RequestingAgentID, string AgentID, string accessToken, UUID groupID, string url, string name, out string reason)
|
|
||||||
{
|
|
||||||
reason = string.Empty;
|
|
||||||
|
|
||||||
Dictionary<string, object> sendData = new Dictionary<string,object>();
|
|
||||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
|
||||||
sendData["AgentID"] = AgentID.ToString();
|
|
||||||
sendData["AccessToken"] = accessToken;
|
|
||||||
sendData["GroupID"] = groupID.ToString();
|
|
||||||
sendData["Location"] = url;
|
|
||||||
sendData["Name"] = name;
|
|
||||||
Dictionary<string, object> ret = MakeRequest("POSTGROUP", sendData);
|
|
||||||
|
|
||||||
if (ret == null)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!ret.ContainsKey("RESULT"))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (ret["RESULT"].ToString().ToLower() != "true")
|
|
||||||
{
|
|
||||||
reason = ret["REASON"].ToString();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RemoveAgentFromGroup(string AgentID, UUID GroupID, string token)
|
|
||||||
{
|
|
||||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
|
||||||
sendData["AgentID"] = AgentID;
|
|
||||||
sendData["GroupID"] = GroupID.ToString();
|
|
||||||
sendData["AccessToken"] = GroupsDataUtils.Sanitize(token);
|
|
||||||
MakeRequest("REMOVEAGENTFROMGROUP", sendData);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ExtendedGroupRecord GetGroupRecord(string RequestingAgentID, UUID GroupID, string GroupName, string token)
|
|
||||||
{
|
|
||||||
if (GroupID == UUID.Zero && (GroupName == null || (GroupName != null && GroupName == string.Empty)))
|
|
||||||
return null;
|
|
||||||
|
|
||||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
|
||||||
if (GroupID != UUID.Zero)
|
|
||||||
sendData["GroupID"] = GroupID.ToString();
|
|
||||||
if (!string.IsNullOrEmpty(GroupName))
|
|
||||||
sendData["Name"] = GroupsDataUtils.Sanitize(GroupName);
|
|
||||||
|
|
||||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
|
||||||
sendData["AccessToken"] = GroupsDataUtils.Sanitize(token);
|
|
||||||
|
|
||||||
Dictionary<string, object> ret = MakeRequest("GETGROUP", sendData);
|
|
||||||
|
|
||||||
if (ret == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
if (!ret.ContainsKey("RESULT"))
|
|
||||||
return null;
|
|
||||||
|
|
||||||
if (ret["RESULT"].ToString() == "NULL")
|
|
||||||
return null;
|
|
||||||
|
|
||||||
return GroupsDataUtils.GroupRecord((Dictionary<string, object>)ret["RESULT"]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<ExtendedGroupMembersData> GetGroupMembers(string RequestingAgentID, UUID GroupID, string token)
|
|
||||||
{
|
|
||||||
List<ExtendedGroupMembersData> members = new List<ExtendedGroupMembersData>();
|
|
||||||
|
|
||||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
|
||||||
sendData["GroupID"] = GroupID.ToString();
|
|
||||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
|
||||||
sendData["AccessToken"] = GroupsDataUtils.Sanitize(token);
|
|
||||||
Dictionary<string, object> ret = MakeRequest("GETGROUPMEMBERS", sendData);
|
|
||||||
|
|
||||||
if (ret == null)
|
|
||||||
return members;
|
|
||||||
|
|
||||||
if (!ret.ContainsKey("RESULT"))
|
|
||||||
return members;
|
|
||||||
|
|
||||||
if (ret["RESULT"].ToString() == "NULL")
|
|
||||||
return members;
|
|
||||||
foreach (object v in ((Dictionary<string, object>)ret["RESULT"]).Values)
|
|
||||||
{
|
|
||||||
ExtendedGroupMembersData m = GroupsDataUtils.GroupMembersData((Dictionary<string, object>)v);
|
|
||||||
members.Add(m);
|
|
||||||
}
|
|
||||||
|
|
||||||
return members;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<GroupRolesData> GetGroupRoles(string RequestingAgentID, UUID GroupID, string token)
|
|
||||||
{
|
|
||||||
List<GroupRolesData> roles = new List<GroupRolesData>();
|
|
||||||
|
|
||||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
|
||||||
sendData["GroupID"] = GroupID.ToString();
|
|
||||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
|
||||||
sendData["AccessToken"] = GroupsDataUtils.Sanitize(token);
|
|
||||||
Dictionary<string, object> ret = MakeRequest("GETGROUPROLES", sendData);
|
|
||||||
|
|
||||||
if (ret == null)
|
|
||||||
return roles;
|
|
||||||
|
|
||||||
if (!ret.ContainsKey("RESULT"))
|
|
||||||
return roles;
|
|
||||||
|
|
||||||
if (ret["RESULT"].ToString() == "NULL")
|
|
||||||
return roles;
|
|
||||||
foreach (object v in ((Dictionary<string, object>)ret["RESULT"]).Values)
|
|
||||||
{
|
|
||||||
GroupRolesData m = GroupsDataUtils.GroupRolesData((Dictionary<string, object>)v);
|
|
||||||
roles.Add(m);
|
|
||||||
}
|
|
||||||
|
|
||||||
return roles;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<ExtendedGroupRoleMembersData> GetGroupRoleMembers(string RequestingAgentID, UUID GroupID, string token)
|
|
||||||
{
|
|
||||||
List<ExtendedGroupRoleMembersData> rmembers = new List<ExtendedGroupRoleMembersData>();
|
|
||||||
|
|
||||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
|
||||||
sendData["GroupID"] = GroupID.ToString();
|
|
||||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
|
||||||
sendData["AccessToken"] = GroupsDataUtils.Sanitize(token);
|
|
||||||
Dictionary<string, object> ret = MakeRequest("GETROLEMEMBERS", sendData);
|
|
||||||
|
|
||||||
if (ret == null)
|
|
||||||
return rmembers;
|
|
||||||
|
|
||||||
if (!ret.ContainsKey("RESULT"))
|
|
||||||
return rmembers;
|
|
||||||
|
|
||||||
if (ret["RESULT"].ToString() == "NULL")
|
|
||||||
return rmembers;
|
|
||||||
|
|
||||||
foreach (object v in ((Dictionary<string, object>)ret["RESULT"]).Values)
|
|
||||||
{
|
|
||||||
ExtendedGroupRoleMembersData m = GroupsDataUtils.GroupRoleMembersData((Dictionary<string, object>)v);
|
|
||||||
rmembers.Add(m);
|
|
||||||
}
|
|
||||||
|
|
||||||
return rmembers;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool AddNotice(string RequestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message,
|
|
||||||
bool hasAttachment, byte attType, string attName, UUID attItemID, string attOwnerID)
|
|
||||||
{
|
|
||||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
|
||||||
sendData["GroupID"] = groupID.ToString();
|
|
||||||
sendData["NoticeID"] = noticeID.ToString();
|
|
||||||
sendData["FromName"] = GroupsDataUtils.Sanitize(fromName);
|
|
||||||
sendData["Subject"] = GroupsDataUtils.Sanitize(subject);
|
|
||||||
sendData["Message"] = GroupsDataUtils.Sanitize(message);
|
|
||||||
sendData["HasAttachment"] = hasAttachment.ToString();
|
|
||||||
if (hasAttachment)
|
|
||||||
{
|
|
||||||
sendData["AttachmentType"] = attType.ToString();
|
|
||||||
sendData["AttachmentName"] = attName.ToString();
|
|
||||||
sendData["AttachmentItemID"] = attItemID.ToString();
|
|
||||||
sendData["AttachmentOwnerID"] = attOwnerID;
|
|
||||||
}
|
|
||||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
|
||||||
|
|
||||||
Dictionary<string, object> ret = MakeRequest("ADDNOTICE", sendData);
|
|
||||||
|
|
||||||
if (ret == null)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!ret.ContainsKey("RESULT"))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (ret["RESULT"].ToString().ToLower() != "true")
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool VerifyNotice(UUID noticeID, UUID groupID)
|
|
||||||
{
|
|
||||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
|
||||||
sendData["NoticeID"] = noticeID.ToString();
|
|
||||||
sendData["GroupID"] = groupID.ToString();
|
|
||||||
Dictionary<string, object> ret = MakeRequest("VERIFYNOTICE", sendData);
|
|
||||||
|
|
||||||
if (ret == null)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!ret.ContainsKey("RESULT"))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (ret["RESULT"].ToString().ToLower() != "true")
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
|
|
||||||
#region Make Request
|
|
||||||
|
|
||||||
private Dictionary<string, object> MakeRequest(string method, Dictionary<string, object> sendData)
|
|
||||||
{
|
|
||||||
sendData["METHOD"] = method;
|
|
||||||
|
|
||||||
string reply = string.Empty;
|
|
||||||
lock (m_Lock)
|
|
||||||
reply = SynchronousRestFormsRequester.MakeRequest("POST",
|
|
||||||
m_ServerURI + "hg-groups",
|
|
||||||
ServerUtils.BuildQueryString(sendData));
|
|
||||||
|
|
||||||
//m_log.DebugFormat("[XXX]: reply was {0}", reply);
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(reply))
|
|
||||||
return null;
|
|
||||||
|
|
||||||
Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(
|
|
||||||
reply);
|
|
||||||
|
|
||||||
return replyData;
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,695 +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.Reflection;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
using OpenSim.Framework;
|
|
||||||
using OpenSim.Framework.Monitoring;
|
|
||||||
using OpenSim.Framework.Servers;
|
|
||||||
using OpenSim.Region.Framework.Scenes;
|
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
|
||||||
using OpenSim.Services.Interfaces;
|
|
||||||
|
|
||||||
using OpenMetaverse;
|
|
||||||
using Mono.Addins;
|
|
||||||
using log4net;
|
|
||||||
using Nini.Config;
|
|
||||||
|
|
||||||
namespace OpenSim.Groups
|
|
||||||
{
|
|
||||||
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GroupsServiceHGConnectorModule")]
|
|
||||||
public class GroupsServiceHGConnectorModule : ISharedRegionModule, IGroupsServicesConnector
|
|
||||||
{
|
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
|
||||||
|
|
||||||
private bool m_Enabled = false;
|
|
||||||
private IGroupsServicesConnector m_LocalGroupsConnector;
|
|
||||||
private string m_LocalGroupsServiceLocation;
|
|
||||||
private IUserManagement m_UserManagement;
|
|
||||||
private IOfflineIMService m_OfflineIM;
|
|
||||||
private IMessageTransferModule m_Messaging;
|
|
||||||
private List<Scene> m_Scenes;
|
|
||||||
private ForeignImporter m_ForeignImporter;
|
|
||||||
private string m_ServiceLocation;
|
|
||||||
private IConfigSource m_Config;
|
|
||||||
|
|
||||||
private Dictionary<string, GroupsServiceHGConnector> m_NetworkConnectors = new Dictionary<string, GroupsServiceHGConnector>();
|
|
||||||
private RemoteConnectorCacheWrapper m_CacheWrapper; // for caching info of external group services
|
|
||||||
|
|
||||||
#region ISharedRegionModule
|
|
||||||
|
|
||||||
public void Initialise(IConfigSource config)
|
|
||||||
{
|
|
||||||
IConfig groupsConfig = config.Configs["Groups"];
|
|
||||||
if (groupsConfig == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if ((groupsConfig.GetBoolean("Enabled", false) == false)
|
|
||||||
|| (groupsConfig.GetString("ServicesConnectorModule", string.Empty) != Name))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_Config = config;
|
|
||||||
m_ServiceLocation = groupsConfig.GetString("LocalService", "local"); // local or remote
|
|
||||||
m_LocalGroupsServiceLocation = groupsConfig.GetString("GroupsExternalURI", "http://127.0.0.1");
|
|
||||||
m_Scenes = new List<Scene>();
|
|
||||||
|
|
||||||
m_Enabled = true;
|
|
||||||
|
|
||||||
m_log.DebugFormat("[Groups]: Initializing {0} with LocalService {1}", this.Name, m_ServiceLocation);
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Name
|
|
||||||
{
|
|
||||||
get { return "Groups HG Service Connector"; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public Type ReplaceableInterface
|
|
||||||
{
|
|
||||||
get { return null; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public void AddRegion(Scene scene)
|
|
||||||
{
|
|
||||||
if (!m_Enabled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_log.DebugFormat("[Groups]: Registering {0} with {1}", this.Name, scene.RegionInfo.RegionName);
|
|
||||||
scene.RegisterModuleInterface<IGroupsServicesConnector>(this);
|
|
||||||
m_Scenes.Add(scene);
|
|
||||||
|
|
||||||
scene.EventManager.OnNewClient += OnNewClient;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RemoveRegion(Scene scene)
|
|
||||||
{
|
|
||||||
if (!m_Enabled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
scene.UnregisterModuleInterface<IGroupsServicesConnector>(this);
|
|
||||||
m_Scenes.Remove(scene);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RegionLoaded(Scene scene)
|
|
||||||
{
|
|
||||||
if (!m_Enabled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (m_UserManagement == null)
|
|
||||||
{
|
|
||||||
m_UserManagement = scene.RequestModuleInterface<IUserManagement>();
|
|
||||||
m_OfflineIM = scene.RequestModuleInterface<IOfflineIMService>();
|
|
||||||
m_Messaging = scene.RequestModuleInterface<IMessageTransferModule>();
|
|
||||||
m_ForeignImporter = new ForeignImporter(m_UserManagement);
|
|
||||||
|
|
||||||
if (m_ServiceLocation.Equals("local"))
|
|
||||||
{
|
|
||||||
m_LocalGroupsConnector = new GroupsServiceLocalConnectorModule(m_Config, m_UserManagement);
|
|
||||||
// Also, if local, create the endpoint for the HGGroupsService
|
|
||||||
new HGGroupsServiceRobustConnector(m_Config, MainServer.Instance, string.Empty,
|
|
||||||
scene.RequestModuleInterface<IOfflineIMService>(), scene.RequestModuleInterface<IUserAccountService>());
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
m_LocalGroupsConnector = new GroupsServiceRemoteConnectorModule(m_Config, m_UserManagement);
|
|
||||||
|
|
||||||
m_CacheWrapper = new RemoteConnectorCacheWrapper(m_UserManagement);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void PostInitialise()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Close()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
private void OnNewClient(IClientAPI client)
|
|
||||||
{
|
|
||||||
client.OnCompleteMovementToRegion += OnCompleteMovementToRegion;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnCompleteMovementToRegion(IClientAPI client, bool arg2)
|
|
||||||
{
|
|
||||||
object sp = null;
|
|
||||||
if (client.Scene.TryGetScenePresence(client.AgentId, out sp))
|
|
||||||
{
|
|
||||||
if (sp is ScenePresence && ((ScenePresence)sp).PresenceType != PresenceType.Npc)
|
|
||||||
{
|
|
||||||
AgentCircuitData aCircuit = ((ScenePresence)sp).Scene.AuthenticateHandler.GetAgentCircuitData(client.AgentId);
|
|
||||||
if (aCircuit != null && (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0 &&
|
|
||||||
m_OfflineIM != null && m_Messaging != null)
|
|
||||||
{
|
|
||||||
List<GridInstantMessage> ims = m_OfflineIM.GetMessages(aCircuit.AgentID);
|
|
||||||
if (ims != null && ims.Count > 0)
|
|
||||||
foreach (GridInstantMessage im in ims)
|
|
||||||
m_Messaging.SendInstantMessage(im, delegate(bool success) { });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#region IGroupsServicesConnector
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
reason = string.Empty;
|
|
||||||
if (m_UserManagement.IsLocalGridUser(RequestingAgentID))
|
|
||||||
return m_LocalGroupsConnector.CreateGroup(RequestingAgentID, name, charter, showInList, insigniaID,
|
|
||||||
membershipFee, openEnrollment, allowPublish, maturePublish, founderID, out reason);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
reason = "Only local grid users are allowed to create a new group";
|
|
||||||
return UUID.Zero;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool UpdateGroup(string RequestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee,
|
|
||||||
bool openEnrollment, bool allowPublish, bool maturePublish, out string reason)
|
|
||||||
{
|
|
||||||
reason = string.Empty;
|
|
||||||
string url = string.Empty;
|
|
||||||
string name = string.Empty;
|
|
||||||
if (IsLocal(groupID, out url, out name))
|
|
||||||
return m_LocalGroupsConnector.UpdateGroup(AgentUUI(RequestingAgentID), groupID, charter, showInList, insigniaID, membershipFee,
|
|
||||||
openEnrollment, allowPublish, maturePublish, out reason);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
reason = "Changes to remote group not allowed. Please go to the group's original world.";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ExtendedGroupRecord GetGroupRecord(string RequestingAgentID, UUID GroupID, string GroupName)
|
|
||||||
{
|
|
||||||
string url = string.Empty;
|
|
||||||
string name = string.Empty;
|
|
||||||
if (IsLocal(GroupID, out url, out name))
|
|
||||||
return m_LocalGroupsConnector.GetGroupRecord(AgentUUI(RequestingAgentID), GroupID, GroupName);
|
|
||||||
else if (url != string.Empty)
|
|
||||||
{
|
|
||||||
ExtendedGroupMembershipData membership = m_LocalGroupsConnector.GetAgentGroupMembership(RequestingAgentID, RequestingAgentID, GroupID);
|
|
||||||
string accessToken = string.Empty;
|
|
||||||
if (membership != null)
|
|
||||||
accessToken = membership.AccessToken;
|
|
||||||
else
|
|
||||||
return null;
|
|
||||||
|
|
||||||
GroupsServiceHGConnector c = GetConnector(url);
|
|
||||||
if (c != null)
|
|
||||||
{
|
|
||||||
ExtendedGroupRecord grec = m_CacheWrapper.GetGroupRecord(RequestingAgentID, GroupID, GroupName, delegate
|
|
||||||
{
|
|
||||||
return c.GetGroupRecord(AgentUUIForOutside(RequestingAgentID), GroupID, GroupName, accessToken);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (grec != null)
|
|
||||||
ImportForeigner(grec.FounderUUI);
|
|
||||||
return grec;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<DirGroupsReplyData> FindGroups(string RequestingAgentIDstr, string search)
|
|
||||||
{
|
|
||||||
return m_LocalGroupsConnector.FindGroups(RequestingAgentIDstr, search);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<GroupMembersData> GetGroupMembers(string RequestingAgentID, UUID GroupID)
|
|
||||||
{
|
|
||||||
string url = string.Empty, gname = string.Empty;
|
|
||||||
if (IsLocal(GroupID, out url, out gname))
|
|
||||||
{
|
|
||||||
string agentID = AgentUUI(RequestingAgentID);
|
|
||||||
return m_LocalGroupsConnector.GetGroupMembers(agentID, GroupID);
|
|
||||||
}
|
|
||||||
else if (!string.IsNullOrEmpty(url))
|
|
||||||
{
|
|
||||||
ExtendedGroupMembershipData membership = m_LocalGroupsConnector.GetAgentGroupMembership(RequestingAgentID, RequestingAgentID, GroupID);
|
|
||||||
string accessToken = string.Empty;
|
|
||||||
if (membership != null)
|
|
||||||
accessToken = membership.AccessToken;
|
|
||||||
else
|
|
||||||
return null;
|
|
||||||
|
|
||||||
GroupsServiceHGConnector c = GetConnector(url);
|
|
||||||
if (c != null)
|
|
||||||
{
|
|
||||||
return m_CacheWrapper.GetGroupMembers(RequestingAgentID, GroupID, delegate
|
|
||||||
{
|
|
||||||
return c.GetGroupMembers(AgentUUIForOutside(RequestingAgentID), GroupID, accessToken);
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new List<GroupMembersData>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool AddGroupRole(string RequestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers, out string reason)
|
|
||||||
{
|
|
||||||
reason = string.Empty;
|
|
||||||
string url = string.Empty, gname = string.Empty;
|
|
||||||
|
|
||||||
if (IsLocal(groupID, out url, out gname))
|
|
||||||
return m_LocalGroupsConnector.AddGroupRole(AgentUUI(RequestingAgentID), groupID, roleID, name, description, title, powers, out reason);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
reason = "Operation not allowed outside this group's origin world.";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool UpdateGroupRole(string RequestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers)
|
|
||||||
{
|
|
||||||
string url = string.Empty, gname = string.Empty;
|
|
||||||
|
|
||||||
if (IsLocal(groupID, out url, out gname))
|
|
||||||
return m_LocalGroupsConnector.UpdateGroupRole(AgentUUI(RequestingAgentID), groupID, roleID, name, description, title, powers);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RemoveGroupRole(string RequestingAgentID, UUID groupID, UUID roleID)
|
|
||||||
{
|
|
||||||
string url = string.Empty, gname = string.Empty;
|
|
||||||
|
|
||||||
if (IsLocal(groupID, out url, out gname))
|
|
||||||
m_LocalGroupsConnector.RemoveGroupRole(AgentUUI(RequestingAgentID), groupID, roleID);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<GroupRolesData> GetGroupRoles(string RequestingAgentID, UUID groupID)
|
|
||||||
{
|
|
||||||
string url = string.Empty, gname = string.Empty;
|
|
||||||
|
|
||||||
if (IsLocal(groupID, out url, out gname))
|
|
||||||
return m_LocalGroupsConnector.GetGroupRoles(AgentUUI(RequestingAgentID), groupID);
|
|
||||||
else if (!string.IsNullOrEmpty(url))
|
|
||||||
{
|
|
||||||
ExtendedGroupMembershipData membership = m_LocalGroupsConnector.GetAgentGroupMembership(RequestingAgentID, RequestingAgentID, groupID);
|
|
||||||
string accessToken = string.Empty;
|
|
||||||
if (membership != null)
|
|
||||||
accessToken = membership.AccessToken;
|
|
||||||
else
|
|
||||||
return null;
|
|
||||||
|
|
||||||
GroupsServiceHGConnector c = GetConnector(url);
|
|
||||||
if (c != null)
|
|
||||||
{
|
|
||||||
return m_CacheWrapper.GetGroupRoles(RequestingAgentID, groupID, delegate
|
|
||||||
{
|
|
||||||
return c.GetGroupRoles(AgentUUIForOutside(RequestingAgentID), groupID, accessToken);
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new List<GroupRolesData>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<GroupRoleMembersData> GetGroupRoleMembers(string RequestingAgentID, UUID groupID)
|
|
||||||
{
|
|
||||||
string url = string.Empty, gname = string.Empty;
|
|
||||||
|
|
||||||
if (IsLocal(groupID, out url, out gname))
|
|
||||||
return m_LocalGroupsConnector.GetGroupRoleMembers(AgentUUI(RequestingAgentID), groupID);
|
|
||||||
else if (!string.IsNullOrEmpty(url))
|
|
||||||
{
|
|
||||||
ExtendedGroupMembershipData membership = m_LocalGroupsConnector.GetAgentGroupMembership(RequestingAgentID, RequestingAgentID, groupID);
|
|
||||||
string accessToken = string.Empty;
|
|
||||||
if (membership != null)
|
|
||||||
accessToken = membership.AccessToken;
|
|
||||||
else
|
|
||||||
return null;
|
|
||||||
|
|
||||||
GroupsServiceHGConnector c = GetConnector(url);
|
|
||||||
if (c != null)
|
|
||||||
{
|
|
||||||
return m_CacheWrapper.GetGroupRoleMembers(RequestingAgentID, groupID, delegate
|
|
||||||
{
|
|
||||||
return c.GetGroupRoleMembers(AgentUUIForOutside(RequestingAgentID), groupID, accessToken);
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new List<GroupRoleMembersData>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool AddAgentToGroup(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID, string token, out string reason)
|
|
||||||
{
|
|
||||||
string url = string.Empty;
|
|
||||||
string name = string.Empty;
|
|
||||||
reason = string.Empty;
|
|
||||||
|
|
||||||
UUID uid = new UUID(AgentID);
|
|
||||||
if (IsLocal(GroupID, out url, out name))
|
|
||||||
{
|
|
||||||
if (m_UserManagement.IsLocalGridUser(uid)) // local user
|
|
||||||
{
|
|
||||||
// normal case: local group, local user
|
|
||||||
return m_LocalGroupsConnector.AddAgentToGroup(AgentUUI(RequestingAgentID), AgentUUI(AgentID), GroupID, RoleID, token, out reason);
|
|
||||||
}
|
|
||||||
else // local group, foreign user
|
|
||||||
{
|
|
||||||
// the user is accepting the invitation, or joining, where the group resides
|
|
||||||
token = UUID.Random().ToString();
|
|
||||||
bool success = m_LocalGroupsConnector.AddAgentToGroup(AgentUUI(RequestingAgentID), AgentUUI(AgentID), GroupID, RoleID, token, out reason);
|
|
||||||
|
|
||||||
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");
|
|
||||||
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.";
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
GroupsServiceHGConnector c = GetConnector(url);
|
|
||||||
if (c != null)
|
|
||||||
c.CreateProxy(AgentUUI(RequestingAgentID), AgentID, token, GroupID, m_LocalGroupsServiceLocation, name, out reason);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (m_UserManagement.IsLocalGridUser(uid)) // local user
|
|
||||||
{
|
|
||||||
// foreign group, local user. She's been added already by the HG service.
|
|
||||||
// Let's just check
|
|
||||||
if (m_LocalGroupsConnector.GetAgentGroupMembership(AgentUUI(RequestingAgentID), AgentUUI(AgentID), GroupID) != null)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
reason = "Operation not allowed outside this group's origin world";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void RemoveAgentFromGroup(string RequestingAgentID, string AgentID, UUID GroupID)
|
|
||||||
{
|
|
||||||
string url = string.Empty, name = string.Empty;
|
|
||||||
if (!IsLocal(GroupID, out url, out name) && url != string.Empty)
|
|
||||||
{
|
|
||||||
ExtendedGroupMembershipData membership = m_LocalGroupsConnector.GetAgentGroupMembership(AgentUUI(RequestingAgentID), AgentUUI(AgentID), GroupID);
|
|
||||||
if (membership != null)
|
|
||||||
{
|
|
||||||
GroupsServiceHGConnector c = GetConnector(url);
|
|
||||||
if (c != null)
|
|
||||||
c.RemoveAgentFromGroup(AgentUUIForOutside(AgentID), GroupID, membership.AccessToken);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove from local service
|
|
||||||
m_LocalGroupsConnector.RemoveAgentFromGroup(AgentUUI(RequestingAgentID), AgentUUI(AgentID), GroupID);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool AddAgentToGroupInvite(string RequestingAgentID, UUID inviteID, UUID groupID, UUID roleID, string agentID)
|
|
||||||
{
|
|
||||||
string url = string.Empty, gname = string.Empty;
|
|
||||||
|
|
||||||
if (IsLocal(groupID, out url, out gname))
|
|
||||||
return m_LocalGroupsConnector.AddAgentToGroupInvite(AgentUUI(RequestingAgentID), inviteID, groupID, roleID, AgentUUI(agentID));
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public GroupInviteInfo GetAgentToGroupInvite(string RequestingAgentID, UUID inviteID)
|
|
||||||
{
|
|
||||||
return m_LocalGroupsConnector.GetAgentToGroupInvite(AgentUUI(RequestingAgentID), inviteID); ;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RemoveAgentToGroupInvite(string RequestingAgentID, UUID inviteID)
|
|
||||||
{
|
|
||||||
m_LocalGroupsConnector.RemoveAgentToGroupInvite(AgentUUI(RequestingAgentID), inviteID);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void AddAgentToGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID)
|
|
||||||
{
|
|
||||||
string url = string.Empty, gname = string.Empty;
|
|
||||||
|
|
||||||
if (IsLocal(GroupID, out url, out gname))
|
|
||||||
m_LocalGroupsConnector.AddAgentToGroupRole(AgentUUI(RequestingAgentID), AgentUUI(AgentID), GroupID, RoleID);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RemoveAgentFromGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID)
|
|
||||||
{
|
|
||||||
string url = string.Empty, gname = string.Empty;
|
|
||||||
|
|
||||||
if (IsLocal(GroupID, out url, out gname))
|
|
||||||
m_LocalGroupsConnector.RemoveAgentFromGroupRole(AgentUUI(RequestingAgentID), AgentUUI(AgentID), GroupID, RoleID);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<GroupRolesData> GetAgentGroupRoles(string RequestingAgentID, string AgentID, UUID GroupID)
|
|
||||||
{
|
|
||||||
string url = string.Empty, gname = string.Empty;
|
|
||||||
|
|
||||||
if (IsLocal(GroupID, out url, out gname))
|
|
||||||
return m_LocalGroupsConnector.GetAgentGroupRoles(AgentUUI(RequestingAgentID), AgentUUI(AgentID), GroupID);
|
|
||||||
else
|
|
||||||
return new List<GroupRolesData>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetAgentActiveGroup(string RequestingAgentID, string AgentID, UUID GroupID)
|
|
||||||
{
|
|
||||||
string url = string.Empty, gname = string.Empty;
|
|
||||||
|
|
||||||
if (IsLocal(GroupID, out url, out gname))
|
|
||||||
m_LocalGroupsConnector.SetAgentActiveGroup(AgentUUI(RequestingAgentID), AgentUUI(AgentID), GroupID);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ExtendedGroupMembershipData GetAgentActiveMembership(string RequestingAgentID, string AgentID)
|
|
||||||
{
|
|
||||||
return m_LocalGroupsConnector.GetAgentActiveMembership(AgentUUI(RequestingAgentID), AgentUUI(AgentID));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetAgentActiveGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID)
|
|
||||||
{
|
|
||||||
string url = string.Empty, gname = string.Empty;
|
|
||||||
|
|
||||||
if (IsLocal(GroupID, out url, out gname))
|
|
||||||
m_LocalGroupsConnector.SetAgentActiveGroupRole(AgentUUI(RequestingAgentID), AgentUUI(AgentID), GroupID, RoleID);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UpdateMembership(string RequestingAgentID, string AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile)
|
|
||||||
{
|
|
||||||
m_LocalGroupsConnector.UpdateMembership(AgentUUI(RequestingAgentID), AgentUUI(AgentID), GroupID, AcceptNotices, ListInProfile);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ExtendedGroupMembershipData GetAgentGroupMembership(string RequestingAgentID, string AgentID, UUID GroupID)
|
|
||||||
{
|
|
||||||
string url = string.Empty, gname = string.Empty;
|
|
||||||
|
|
||||||
if (IsLocal(GroupID, out url, out gname))
|
|
||||||
return m_LocalGroupsConnector.GetAgentGroupMembership(AgentUUI(RequestingAgentID), AgentUUI(AgentID), GroupID);
|
|
||||||
else
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<GroupMembershipData> GetAgentGroupMemberships(string RequestingAgentID, string AgentID)
|
|
||||||
{
|
|
||||||
return m_LocalGroupsConnector.GetAgentGroupMemberships(AgentUUI(RequestingAgentID), AgentUUI(AgentID));
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
string url = string.Empty, gname = string.Empty;
|
|
||||||
|
|
||||||
if (IsLocal(groupID, out url, out gname))
|
|
||||||
{
|
|
||||||
if (m_LocalGroupsConnector.AddGroupNotice(AgentUUI(RequestingAgentID), groupID, noticeID, fromName, subject, message,
|
|
||||||
hasAttachment, attType, attName, attItemID, AgentUUI(attOwnerID)))
|
|
||||||
{
|
|
||||||
// then send the notice to every grid for which there are members in this group
|
|
||||||
List<GroupMembersData> members = m_LocalGroupsConnector.GetGroupMembers(AgentUUI(RequestingAgentID), groupID);
|
|
||||||
List<string> urls = new List<string>();
|
|
||||||
foreach (GroupMembersData m in members)
|
|
||||||
{
|
|
||||||
if (!m_UserManagement.IsLocalGridUser(m.AgentID))
|
|
||||||
{
|
|
||||||
string gURL = m_UserManagement.GetUserServerURL(m.AgentID, "GroupsServerURI");
|
|
||||||
if (!urls.Contains(gURL))
|
|
||||||
urls.Add(gURL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// so we have the list of urls to send the notice to
|
|
||||||
// this may take a long time...
|
|
||||||
WorkManager.RunInThread(delegate
|
|
||||||
{
|
|
||||||
foreach (string u in urls)
|
|
||||||
{
|
|
||||||
GroupsServiceHGConnector c = GetConnector(u);
|
|
||||||
if (c != null)
|
|
||||||
{
|
|
||||||
c.AddNotice(AgentUUIForOutside(RequestingAgentID), groupID, noticeID, fromName, subject, message,
|
|
||||||
hasAttachment, attType, attName, attItemID, AgentUUIForOutside(attOwnerID));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, null, string.Format("AddGroupNotice (agent {0}, group {1})", RequestingAgentID, groupID));
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public GroupNoticeInfo GetGroupNotice(string RequestingAgentID, UUID noticeID)
|
|
||||||
{
|
|
||||||
GroupNoticeInfo notice = m_LocalGroupsConnector.GetGroupNotice(AgentUUI(RequestingAgentID), noticeID);
|
|
||||||
|
|
||||||
if (notice != null && notice.noticeData.HasAttachment && notice.noticeData.AttachmentOwnerID != null)
|
|
||||||
ImportForeigner(notice.noticeData.AttachmentOwnerID);
|
|
||||||
|
|
||||||
return notice;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<ExtendedGroupNoticeData> GetGroupNotices(string RequestingAgentID, UUID GroupID)
|
|
||||||
{
|
|
||||||
return m_LocalGroupsConnector.GetGroupNotices(AgentUUI(RequestingAgentID), GroupID);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region hypergrid groups
|
|
||||||
|
|
||||||
private string AgentUUI(string AgentIDStr)
|
|
||||||
{
|
|
||||||
UUID AgentID = UUID.Zero;
|
|
||||||
if (!UUID.TryParse(AgentIDStr, out AgentID) || AgentID == UUID.Zero)
|
|
||||||
return UUID.Zero.ToString();
|
|
||||||
|
|
||||||
if (m_UserManagement.IsLocalGridUser(AgentID))
|
|
||||||
return AgentID.ToString();
|
|
||||||
|
|
||||||
AgentCircuitData agent = null;
|
|
||||||
foreach (Scene scene in m_Scenes)
|
|
||||||
{
|
|
||||||
agent = scene.AuthenticateHandler.GetAgentCircuitData(AgentID);
|
|
||||||
if (agent != null)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (agent != null)
|
|
||||||
return Util.ProduceUserUniversalIdentifier(agent);
|
|
||||||
|
|
||||||
// we don't know anything about this foreign user
|
|
||||||
// try asking the user management module, which may know more
|
|
||||||
return m_UserManagement.GetUserUUI(AgentID);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private string AgentUUIForOutside(string AgentIDStr)
|
|
||||||
{
|
|
||||||
UUID AgentID = UUID.Zero;
|
|
||||||
if (!UUID.TryParse(AgentIDStr, out AgentID) || AgentID == UUID.Zero)
|
|
||||||
return UUID.Zero.ToString();
|
|
||||||
|
|
||||||
AgentCircuitData agent = null;
|
|
||||||
foreach (Scene scene in m_Scenes)
|
|
||||||
{
|
|
||||||
agent = scene.AuthenticateHandler.GetAgentCircuitData(AgentID);
|
|
||||||
if (agent != null)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (agent == null) // oops
|
|
||||||
return AgentID.ToString();
|
|
||||||
|
|
||||||
return Util.ProduceUserUniversalIdentifier(agent);
|
|
||||||
}
|
|
||||||
|
|
||||||
private UUID ImportForeigner(string uID)
|
|
||||||
{
|
|
||||||
UUID userID = UUID.Zero;
|
|
||||||
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))
|
|
||||||
m_UserManagement.AddUser(userID, first, last, url);
|
|
||||||
|
|
||||||
return userID;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool IsLocal(UUID groupID, out string serviceLocation, out string name)
|
|
||||||
{
|
|
||||||
serviceLocation = string.Empty;
|
|
||||||
name = string.Empty;
|
|
||||||
if (groupID.Equals(UUID.Zero))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
ExtendedGroupRecord group = m_LocalGroupsConnector.GetGroupRecord(UUID.Zero.ToString(), groupID, string.Empty);
|
|
||||||
if (group == null)
|
|
||||||
{
|
|
||||||
//m_log.DebugFormat("[XXX]: IsLocal? group {0} not found -- no.", groupID);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
serviceLocation = group.ServiceLocation;
|
|
||||||
name = group.GroupName;
|
|
||||||
bool isLocal = (group.ServiceLocation == string.Empty);
|
|
||||||
//m_log.DebugFormat("[XXX]: IsLocal? {0}", isLocal);
|
|
||||||
return isLocal;
|
|
||||||
}
|
|
||||||
|
|
||||||
private GroupsServiceHGConnector GetConnector(string url)
|
|
||||||
{
|
|
||||||
lock (m_NetworkConnectors)
|
|
||||||
{
|
|
||||||
if (m_NetworkConnectors.ContainsKey(url))
|
|
||||||
return m_NetworkConnectors[url];
|
|
||||||
|
|
||||||
GroupsServiceHGConnector c = new GroupsServiceHGConnector(url);
|
|
||||||
m_NetworkConnectors[url] = c;
|
|
||||||
}
|
|
||||||
|
|
||||||
return m_NetworkConnectors[url];
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,445 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
* * Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* * Neither the name of the OpenSimulator Project nor the
|
|
||||||
* names of its contributors may be used to endorse or promote products
|
|
||||||
* derived from this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
|
||||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Text;
|
|
||||||
using System.Xml;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using Nini.Config;
|
|
||||||
using OpenSim.Framework;
|
|
||||||
using OpenSim.Server.Base;
|
|
||||||
using OpenSim.Services.Interfaces;
|
|
||||||
using OpenSim.Framework.Servers.HttpServer;
|
|
||||||
using OpenSim.Server.Handlers.Base;
|
|
||||||
using log4net;
|
|
||||||
using OpenMetaverse;
|
|
||||||
|
|
||||||
namespace OpenSim.Groups
|
|
||||||
{
|
|
||||||
public class HGGroupsServiceRobustConnector : ServiceConnector
|
|
||||||
{
|
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
|
||||||
|
|
||||||
private HGGroupsService m_GroupsService;
|
|
||||||
private string m_ConfigName = "Groups";
|
|
||||||
|
|
||||||
// Called by Robust shell
|
|
||||||
public HGGroupsServiceRobustConnector(IConfigSource config, IHttpServer server, string configName) :
|
|
||||||
this(config, server, configName, null, null)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// Called by the sim-bound module
|
|
||||||
public HGGroupsServiceRobustConnector(IConfigSource config, IHttpServer server, string configName, IOfflineIMService im, IUserAccountService users) :
|
|
||||||
base(config, server, configName)
|
|
||||||
{
|
|
||||||
if (configName != String.Empty)
|
|
||||||
m_ConfigName = configName;
|
|
||||||
|
|
||||||
m_log.DebugFormat("[Groups.RobustHGConnector]: Starting with config name {0}", m_ConfigName);
|
|
||||||
|
|
||||||
string homeURI = Util.GetConfigVarFromSections<string>(config, "HomeURI",
|
|
||||||
new string[] { "Startup", "Hypergrid", m_ConfigName}, string.Empty);
|
|
||||||
if (homeURI == string.Empty)
|
|
||||||
throw new Exception(String.Format("[Groups.RobustHGConnector]: please provide the HomeURI [Startup] or in section {0}", m_ConfigName));
|
|
||||||
|
|
||||||
IConfig cnf = config.Configs[m_ConfigName];
|
|
||||||
if (cnf == null)
|
|
||||||
throw new Exception(String.Format("[Groups.RobustHGConnector]: {0} section does not exist", m_ConfigName));
|
|
||||||
|
|
||||||
if (im == null)
|
|
||||||
{
|
|
||||||
string imDll = cnf.GetString("OfflineIMService", string.Empty);
|
|
||||||
if (imDll == string.Empty)
|
|
||||||
throw new Exception(String.Format("[Groups.RobustHGConnector]: please provide OfflineIMService in section {0}", m_ConfigName));
|
|
||||||
|
|
||||||
Object[] args = new Object[] { config };
|
|
||||||
im = ServerUtils.LoadPlugin<IOfflineIMService>(imDll, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (users == null)
|
|
||||||
{
|
|
||||||
string usersDll = cnf.GetString("UserAccountService", string.Empty);
|
|
||||||
if (usersDll == string.Empty)
|
|
||||||
throw new Exception(String.Format("[Groups.RobustHGConnector]: please provide UserAccountService in section {0}", m_ConfigName));
|
|
||||||
|
|
||||||
Object[] args = new Object[] { config };
|
|
||||||
users = ServerUtils.LoadPlugin<IUserAccountService>(usersDll, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_GroupsService = new HGGroupsService(config, im, users, homeURI);
|
|
||||||
|
|
||||||
server.AddStreamHandler(new HGGroupsServicePostHandler(m_GroupsService));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public class HGGroupsServicePostHandler : BaseStreamHandler
|
|
||||||
{
|
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
|
||||||
|
|
||||||
private HGGroupsService m_GroupsService;
|
|
||||||
|
|
||||||
public HGGroupsServicePostHandler(HGGroupsService service) :
|
|
||||||
base("POST", "/hg-groups")
|
|
||||||
{
|
|
||||||
m_GroupsService = service;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override byte[] ProcessRequest(string path, Stream requestData,
|
|
||||||
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
|
||||||
{
|
|
||||||
string body;
|
|
||||||
using(StreamReader sr = new StreamReader(requestData))
|
|
||||||
body = sr.ReadToEnd();
|
|
||||||
|
|
||||||
body = body.Trim();
|
|
||||||
|
|
||||||
//m_log.DebugFormat("[XXX]: query String: {0}", body);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Dictionary<string, object> request =
|
|
||||||
ServerUtils.ParseQueryString(body);
|
|
||||||
|
|
||||||
if (!request.ContainsKey("METHOD"))
|
|
||||||
return FailureResult();
|
|
||||||
|
|
||||||
string method = request["METHOD"].ToString();
|
|
||||||
request.Remove("METHOD");
|
|
||||||
|
|
||||||
m_log.DebugFormat("[Groups.RobustHGConnector]: {0}", method);
|
|
||||||
switch (method)
|
|
||||||
{
|
|
||||||
case "POSTGROUP":
|
|
||||||
return HandleAddGroupProxy(request);
|
|
||||||
case "REMOVEAGENTFROMGROUP":
|
|
||||||
return HandleRemoveAgentFromGroup(request);
|
|
||||||
case "GETGROUP":
|
|
||||||
return HandleGetGroup(request);
|
|
||||||
case "ADDNOTICE":
|
|
||||||
return HandleAddNotice(request);
|
|
||||||
case "VERIFYNOTICE":
|
|
||||||
return HandleVerifyNotice(request);
|
|
||||||
case "GETGROUPMEMBERS":
|
|
||||||
return HandleGetGroupMembers(request);
|
|
||||||
case "GETGROUPROLES":
|
|
||||||
return HandleGetGroupRoles(request);
|
|
||||||
case "GETROLEMEMBERS":
|
|
||||||
return HandleGetRoleMembers(request);
|
|
||||||
|
|
||||||
}
|
|
||||||
m_log.DebugFormat("[Groups.RobustHGConnector]: unknown method request: {0}", method);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
m_log.Error(string.Format("[Groups.RobustHGConnector]: Exception {0} ", e.Message), e);
|
|
||||||
}
|
|
||||||
|
|
||||||
return FailureResult();
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] HandleAddGroupProxy(Dictionary<string, object> request)
|
|
||||||
{
|
|
||||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
|
||||||
|
|
||||||
if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("GroupID")
|
|
||||||
|| !request.ContainsKey("AgentID")
|
|
||||||
|| !request.ContainsKey("AccessToken") || !request.ContainsKey("Location"))
|
|
||||||
NullResult(result, "Bad network data");
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
string RequestingAgentID = request["RequestingAgentID"].ToString();
|
|
||||||
string agentID = request["AgentID"].ToString();
|
|
||||||
UUID groupID = new UUID(request["GroupID"].ToString());
|
|
||||||
string accessToken = request["AccessToken"].ToString();
|
|
||||||
string location = request["Location"].ToString();
|
|
||||||
string name = string.Empty;
|
|
||||||
if (request.ContainsKey("Name"))
|
|
||||||
name = request["Name"].ToString();
|
|
||||||
|
|
||||||
string reason = string.Empty;
|
|
||||||
bool success = m_GroupsService.CreateGroupProxy(RequestingAgentID, agentID, accessToken, groupID, location, name, out reason);
|
|
||||||
result["REASON"] = reason;
|
|
||||||
result["RESULT"] = success.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
string xmlString = ServerUtils.BuildXmlResponse(result);
|
|
||||||
|
|
||||||
//m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
|
|
||||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] HandleRemoveAgentFromGroup(Dictionary<string, object> request)
|
|
||||||
{
|
|
||||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
|
||||||
|
|
||||||
if (!request.ContainsKey("AccessToken") || !request.ContainsKey("AgentID") ||
|
|
||||||
!request.ContainsKey("GroupID"))
|
|
||||||
NullResult(result, "Bad network data");
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UUID groupID = new UUID(request["GroupID"].ToString());
|
|
||||||
string agentID = request["AgentID"].ToString();
|
|
||||||
string token = request["AccessToken"].ToString();
|
|
||||||
|
|
||||||
if (!m_GroupsService.RemoveAgentFromGroup(agentID, agentID, groupID, token))
|
|
||||||
NullResult(result, "Internal error");
|
|
||||||
else
|
|
||||||
result["RESULT"] = "true";
|
|
||||||
}
|
|
||||||
|
|
||||||
//m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
|
|
||||||
return Util.UTF8NoBomEncoding.GetBytes(ServerUtils.BuildXmlResponse(result));
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] HandleGetGroup(Dictionary<string, object> request)
|
|
||||||
{
|
|
||||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
|
||||||
|
|
||||||
if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("AccessToken"))
|
|
||||||
NullResult(result, "Bad network data");
|
|
||||||
else
|
|
||||||
{
|
|
||||||
string RequestingAgentID = request["RequestingAgentID"].ToString();
|
|
||||||
string token = request["AccessToken"].ToString();
|
|
||||||
|
|
||||||
UUID groupID = UUID.Zero;
|
|
||||||
string groupName = string.Empty;
|
|
||||||
|
|
||||||
if (request.ContainsKey("GroupID"))
|
|
||||||
groupID = new UUID(request["GroupID"].ToString());
|
|
||||||
if (request.ContainsKey("Name"))
|
|
||||||
groupName = request["Name"].ToString();
|
|
||||||
|
|
||||||
ExtendedGroupRecord grec = m_GroupsService.GetGroupRecord(RequestingAgentID, groupID, groupName, token);
|
|
||||||
if (grec == null)
|
|
||||||
NullResult(result, "Group not found");
|
|
||||||
else
|
|
||||||
result["RESULT"] = GroupsDataUtils.GroupRecord(grec);
|
|
||||||
}
|
|
||||||
|
|
||||||
string xmlString = ServerUtils.BuildXmlResponse(result);
|
|
||||||
|
|
||||||
//m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
|
|
||||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] HandleGetGroupMembers(Dictionary<string, object> request)
|
|
||||||
{
|
|
||||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
|
||||||
|
|
||||||
if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("GroupID") || !request.ContainsKey("AccessToken"))
|
|
||||||
NullResult(result, "Bad network data");
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UUID groupID = new UUID(request["GroupID"].ToString());
|
|
||||||
string requestingAgentID = request["RequestingAgentID"].ToString();
|
|
||||||
string token = request["AccessToken"].ToString();
|
|
||||||
|
|
||||||
List<ExtendedGroupMembersData> members = m_GroupsService.GetGroupMembers(requestingAgentID, groupID, token);
|
|
||||||
if (members == null || (members != null && members.Count == 0))
|
|
||||||
{
|
|
||||||
NullResult(result, "No members");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Dictionary<string, object> dict = new Dictionary<string, object>();
|
|
||||||
int i = 0;
|
|
||||||
foreach (ExtendedGroupMembersData m in members)
|
|
||||||
{
|
|
||||||
dict["m-" + i++] = GroupsDataUtils.GroupMembersData(m);
|
|
||||||
}
|
|
||||||
|
|
||||||
result["RESULT"] = dict;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
string xmlString = ServerUtils.BuildXmlResponse(result);
|
|
||||||
|
|
||||||
//m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
|
|
||||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] HandleGetGroupRoles(Dictionary<string, object> request)
|
|
||||||
{
|
|
||||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
|
||||||
|
|
||||||
if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("GroupID") || !request.ContainsKey("AccessToken"))
|
|
||||||
NullResult(result, "Bad network data");
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UUID groupID = new UUID(request["GroupID"].ToString());
|
|
||||||
string requestingAgentID = request["RequestingAgentID"].ToString();
|
|
||||||
string token = request["AccessToken"].ToString();
|
|
||||||
|
|
||||||
List<GroupRolesData> roles = m_GroupsService.GetGroupRoles(requestingAgentID, groupID, token);
|
|
||||||
if (roles == null || (roles != null && roles.Count == 0))
|
|
||||||
{
|
|
||||||
NullResult(result, "No members");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Dictionary<string, object> dict = new Dictionary<string, object>();
|
|
||||||
int i = 0;
|
|
||||||
foreach (GroupRolesData r in roles)
|
|
||||||
dict["r-" + i++] = GroupsDataUtils.GroupRolesData(r);
|
|
||||||
|
|
||||||
result["RESULT"] = dict;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
string xmlString = ServerUtils.BuildXmlResponse(result);
|
|
||||||
|
|
||||||
//m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
|
|
||||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] HandleGetRoleMembers(Dictionary<string, object> request)
|
|
||||||
{
|
|
||||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
|
||||||
|
|
||||||
if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("GroupID") || !request.ContainsKey("AccessToken"))
|
|
||||||
NullResult(result, "Bad network data");
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UUID groupID = new UUID(request["GroupID"].ToString());
|
|
||||||
string requestingAgentID = request["RequestingAgentID"].ToString();
|
|
||||||
string token = request["AccessToken"].ToString();
|
|
||||||
|
|
||||||
List<ExtendedGroupRoleMembersData> rmembers = m_GroupsService.GetGroupRoleMembers(requestingAgentID, groupID, token);
|
|
||||||
if (rmembers == null || (rmembers != null && rmembers.Count == 0))
|
|
||||||
{
|
|
||||||
NullResult(result, "No members");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Dictionary<string, object> dict = new Dictionary<string, object>();
|
|
||||||
int i = 0;
|
|
||||||
foreach (ExtendedGroupRoleMembersData rm in rmembers)
|
|
||||||
dict["rm-" + i++] = GroupsDataUtils.GroupRoleMembersData(rm);
|
|
||||||
|
|
||||||
result["RESULT"] = dict;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
string xmlString = ServerUtils.BuildXmlResponse(result);
|
|
||||||
|
|
||||||
//m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
|
|
||||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] HandleAddNotice(Dictionary<string, object> request)
|
|
||||||
{
|
|
||||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
|
||||||
|
|
||||||
if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("GroupID") || !request.ContainsKey("NoticeID") ||
|
|
||||||
!request.ContainsKey("FromName") || !request.ContainsKey("Subject") || !request.ContainsKey("Message") ||
|
|
||||||
!request.ContainsKey("HasAttachment"))
|
|
||||||
NullResult(result, "Bad network data");
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
bool hasAtt = bool.Parse(request["HasAttachment"].ToString());
|
|
||||||
byte attType = 0;
|
|
||||||
string attName = string.Empty;
|
|
||||||
string attOwner = string.Empty;
|
|
||||||
UUID attItem = UUID.Zero;
|
|
||||||
if (request.ContainsKey("AttachmentType"))
|
|
||||||
attType = byte.Parse(request["AttachmentType"].ToString());
|
|
||||||
if (request.ContainsKey("AttachmentName"))
|
|
||||||
attName = request["AttachmentType"].ToString();
|
|
||||||
if (request.ContainsKey("AttachmentItemID"))
|
|
||||||
attItem = new UUID(request["AttachmentItemID"].ToString());
|
|
||||||
if (request.ContainsKey("AttachmentOwnerID"))
|
|
||||||
attOwner = request["AttachmentOwnerID"].ToString();
|
|
||||||
|
|
||||||
bool success = m_GroupsService.AddNotice(request["RequestingAgentID"].ToString(), new UUID(request["GroupID"].ToString()),
|
|
||||||
new UUID(request["NoticeID"].ToString()), request["FromName"].ToString(), request["Subject"].ToString(),
|
|
||||||
request["Message"].ToString(), hasAtt, attType, attName, attItem, attOwner);
|
|
||||||
|
|
||||||
result["RESULT"] = success.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
string xmlString = ServerUtils.BuildXmlResponse(result);
|
|
||||||
|
|
||||||
//m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
|
|
||||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] HandleVerifyNotice(Dictionary<string, object> request)
|
|
||||||
{
|
|
||||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
|
||||||
|
|
||||||
if (!request.ContainsKey("NoticeID") || !request.ContainsKey("GroupID"))
|
|
||||||
NullResult(result, "Bad network data");
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UUID noticeID = new UUID(request["NoticeID"].ToString());
|
|
||||||
UUID groupID = new UUID(request["GroupID"].ToString());
|
|
||||||
|
|
||||||
bool success = m_GroupsService.VerifyNotice(noticeID, groupID);
|
|
||||||
//m_log.DebugFormat("[XXX]: VerifyNotice returned {0}", success);
|
|
||||||
result["RESULT"] = success.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
string xmlString = ServerUtils.BuildXmlResponse(result);
|
|
||||||
|
|
||||||
//m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
|
|
||||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
|
|
||||||
#region Helpers
|
|
||||||
|
|
||||||
private void NullResult(Dictionary<string, object> result, string reason)
|
|
||||||
{
|
|
||||||
result["RESULT"] = "NULL";
|
|
||||||
result["REASON"] = reason;
|
|
||||||
}
|
|
||||||
|
|
||||||
private byte[] FailureResult()
|
|
||||||
{
|
|
||||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
|
||||||
NullResult(result, "Unknown method");
|
|
||||||
string xmlString = ServerUtils.BuildXmlResponse(result);
|
|
||||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,112 +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 OpenMetaverse;
|
|
||||||
using OpenSim.Framework;
|
|
||||||
|
|
||||||
namespace OpenSim.Groups
|
|
||||||
{
|
|
||||||
public interface IGroupsServicesConnector
|
|
||||||
{
|
|
||||||
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 UpdateGroup(string RequestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee,
|
|
||||||
bool openEnrollment, bool allowPublish, bool maturePublish, out string reason);
|
|
||||||
ExtendedGroupRecord GetGroupRecord(string RequestingAgentID, UUID GroupID, string GroupName);
|
|
||||||
List<DirGroupsReplyData> FindGroups(string RequestingAgentIDstr, string search);
|
|
||||||
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 UpdateGroupRole(string RequestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers);
|
|
||||||
void RemoveGroupRole(string RequestingAgentID, UUID groupID, UUID roleID);
|
|
||||||
List<GroupRolesData> GetGroupRoles(string RequestingAgentID, UUID GroupID);
|
|
||||||
List<GroupRoleMembersData> GetGroupRoleMembers(string RequestingAgentID, UUID GroupID);
|
|
||||||
|
|
||||||
bool AddAgentToGroup(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID, string token, out string reason);
|
|
||||||
void RemoveAgentFromGroup(string RequestingAgentID, string AgentID, UUID GroupID);
|
|
||||||
|
|
||||||
bool AddAgentToGroupInvite(string RequestingAgentID, UUID inviteID, UUID groupID, UUID roleID, string agentID);
|
|
||||||
GroupInviteInfo GetAgentToGroupInvite(string RequestingAgentID, UUID inviteID);
|
|
||||||
void RemoveAgentToGroupInvite(string RequestingAgentID, UUID inviteID);
|
|
||||||
|
|
||||||
void AddAgentToGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID);
|
|
||||||
void RemoveAgentFromGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID);
|
|
||||||
List<GroupRolesData> GetAgentGroupRoles(string RequestingAgentID, string AgentID, UUID GroupID);
|
|
||||||
|
|
||||||
void SetAgentActiveGroup(string RequestingAgentID, string AgentID, UUID GroupID);
|
|
||||||
ExtendedGroupMembershipData GetAgentActiveMembership(string RequestingAgentID, string AgentID);
|
|
||||||
|
|
||||||
void SetAgentActiveGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID);
|
|
||||||
void UpdateMembership(string RequestingAgentID, string AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get information about a specific group to which the user belongs.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="RequestingAgentID">The agent requesting the information.</param>
|
|
||||||
/// <param name="AgentID">The agent requested.</param>
|
|
||||||
/// <param name="GroupID">The group requested.</param>
|
|
||||||
/// <returns>
|
|
||||||
/// If the user is a member of the group then the data structure is returned. If not, then null is returned.
|
|
||||||
/// </returns>
|
|
||||||
ExtendedGroupMembershipData GetAgentGroupMembership(string RequestingAgentID, string AgentID, UUID GroupID);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get information about the groups to which a user belongs.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="RequestingAgentID">The agent requesting the information.</param>
|
|
||||||
/// <param name="AgentID">The agent requested.</param>
|
|
||||||
/// <returns>
|
|
||||||
/// Information about the groups to which the user belongs. If the user belongs to no groups then an empty
|
|
||||||
/// list is returned.
|
|
||||||
/// </returns>
|
|
||||||
List<GroupMembershipData> GetAgentGroupMemberships(string RequestingAgentID, string AgentID);
|
|
||||||
|
|
||||||
bool AddGroupNotice(string RequestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message,
|
|
||||||
bool hasAttachment, byte attType, string attName, UUID attItemID, string attOwnerID);
|
|
||||||
GroupNoticeInfo GetGroupNotice(string RequestingAgentID, UUID noticeID);
|
|
||||||
List<ExtendedGroupNoticeData> GetGroupNotices(string RequestingAgentID, UUID GroupID);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public class GroupInviteInfo
|
|
||||||
{
|
|
||||||
public UUID GroupID = UUID.Zero;
|
|
||||||
public UUID RoleID = UUID.Zero;
|
|
||||||
public string AgentID = string.Empty;
|
|
||||||
public UUID InviteID = UUID.Zero;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class GroupNoticeInfo
|
|
||||||
{
|
|
||||||
public ExtendedGroupNoticeData noticeData = new ExtendedGroupNoticeData();
|
|
||||||
public UUID GroupID = UUID.Zero;
|
|
||||||
public string Message = string.Empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,326 +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.Reflection;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
using OpenSim.Framework;
|
|
||||||
using OpenSim.Region.Framework.Scenes;
|
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
|
||||||
using OpenSim.Services.Interfaces;
|
|
||||||
|
|
||||||
using OpenMetaverse;
|
|
||||||
using Mono.Addins;
|
|
||||||
using log4net;
|
|
||||||
using Nini.Config;
|
|
||||||
|
|
||||||
namespace OpenSim.Groups
|
|
||||||
{
|
|
||||||
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GroupsServiceLocalConnectorModule")]
|
|
||||||
public class GroupsServiceLocalConnectorModule : ISharedRegionModule, IGroupsServicesConnector
|
|
||||||
{
|
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
|
||||||
|
|
||||||
private bool m_Enabled = false;
|
|
||||||
private GroupsService m_GroupsService;
|
|
||||||
private IUserManagement m_UserManagement;
|
|
||||||
private List<Scene> m_Scenes;
|
|
||||||
private ForeignImporter m_ForeignImporter;
|
|
||||||
|
|
||||||
#region constructors
|
|
||||||
public GroupsServiceLocalConnectorModule()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public GroupsServiceLocalConnectorModule(IConfigSource config, IUserManagement uman)
|
|
||||||
{
|
|
||||||
Init(config);
|
|
||||||
m_UserManagement = uman;
|
|
||||||
m_ForeignImporter = new ForeignImporter(uman);
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
private void Init(IConfigSource config)
|
|
||||||
{
|
|
||||||
m_GroupsService = new GroupsService(config);
|
|
||||||
m_Scenes = new List<Scene>();
|
|
||||||
}
|
|
||||||
|
|
||||||
#region ISharedRegionModule
|
|
||||||
|
|
||||||
public void Initialise(IConfigSource config)
|
|
||||||
{
|
|
||||||
IConfig groupsConfig = config.Configs["Groups"];
|
|
||||||
if (groupsConfig == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if ((groupsConfig.GetBoolean("Enabled", false) == false)
|
|
||||||
|| (groupsConfig.GetString("ServicesConnectorModule", string.Empty) != Name))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Init(config);
|
|
||||||
m_Enabled = true;
|
|
||||||
|
|
||||||
m_log.DebugFormat("[Groups]: Initializing {0}", this.Name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Name
|
|
||||||
{
|
|
||||||
get { return "Groups Local Service Connector"; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public Type ReplaceableInterface
|
|
||||||
{
|
|
||||||
get { return null; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public void AddRegion(Scene scene)
|
|
||||||
{
|
|
||||||
if (!m_Enabled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_log.DebugFormat("[Groups]: Registering {0} with {1}", this.Name, scene.RegionInfo.RegionName);
|
|
||||||
scene.RegisterModuleInterface<IGroupsServicesConnector>(this);
|
|
||||||
m_Scenes.Add(scene);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RemoveRegion(Scene scene)
|
|
||||||
{
|
|
||||||
if (!m_Enabled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
scene.UnregisterModuleInterface<IGroupsServicesConnector>(this);
|
|
||||||
m_Scenes.Remove(scene);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RegionLoaded(Scene scene)
|
|
||||||
{
|
|
||||||
if (!m_Enabled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (m_UserManagement == null)
|
|
||||||
{
|
|
||||||
m_UserManagement = scene.RequestModuleInterface<IUserManagement>();
|
|
||||||
m_ForeignImporter = new ForeignImporter(m_UserManagement);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void PostInitialise()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Close()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region IGroupsServicesConnector
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
m_log.DebugFormat("[Groups]: Creating group {0}", name);
|
|
||||||
reason = string.Empty;
|
|
||||||
return m_GroupsService.CreateGroup(RequestingAgentID.ToString(), name, charter, showInList, insigniaID,
|
|
||||||
membershipFee, openEnrollment, allowPublish, maturePublish, founderID, out reason);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool UpdateGroup(string RequestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee,
|
|
||||||
bool openEnrollment, bool allowPublish, bool maturePublish, out string reason)
|
|
||||||
{
|
|
||||||
reason = string.Empty;
|
|
||||||
m_GroupsService.UpdateGroup(RequestingAgentID, groupID, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ExtendedGroupRecord GetGroupRecord(string RequestingAgentID, UUID GroupID, string GroupName)
|
|
||||||
{
|
|
||||||
if (GroupID != UUID.Zero)
|
|
||||||
return m_GroupsService.GetGroupRecord(RequestingAgentID, GroupID);
|
|
||||||
else if (GroupName != null)
|
|
||||||
return m_GroupsService.GetGroupRecord(RequestingAgentID, GroupName);
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<DirGroupsReplyData> FindGroups(string RequestingAgentIDstr, string search)
|
|
||||||
{
|
|
||||||
return m_GroupsService.FindGroups(RequestingAgentIDstr, search);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<GroupMembersData> GetGroupMembers(string RequestingAgentID, UUID GroupID)
|
|
||||||
{
|
|
||||||
List<ExtendedGroupMembersData> _members = m_GroupsService.GetGroupMembers(RequestingAgentID, GroupID);
|
|
||||||
if (_members != null && _members.Count > 0)
|
|
||||||
{
|
|
||||||
List<GroupMembersData> members = _members.ConvertAll<GroupMembersData>(new Converter<ExtendedGroupMembersData, GroupMembersData>(m_ForeignImporter.ConvertGroupMembersData));
|
|
||||||
return members;
|
|
||||||
}
|
|
||||||
|
|
||||||
return new List<GroupMembersData>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool AddGroupRole(string RequestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers, out string reason)
|
|
||||||
{
|
|
||||||
return m_GroupsService.AddGroupRole(RequestingAgentID, groupID, roleID, name, description, title, powers, out reason);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool UpdateGroupRole(string RequestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers)
|
|
||||||
{
|
|
||||||
return m_GroupsService.UpdateGroupRole(RequestingAgentID, groupID, roleID, name, description, title, powers);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RemoveGroupRole(string RequestingAgentID, UUID groupID, UUID roleID)
|
|
||||||
{
|
|
||||||
m_GroupsService.RemoveGroupRole(RequestingAgentID, groupID, roleID);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<GroupRolesData> GetGroupRoles(string RequestingAgentID, UUID GroupID)
|
|
||||||
{
|
|
||||||
return m_GroupsService.GetGroupRoles(RequestingAgentID, GroupID);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<GroupRoleMembersData> GetGroupRoleMembers(string RequestingAgentID, UUID GroupID)
|
|
||||||
{
|
|
||||||
List<ExtendedGroupRoleMembersData> _rm = m_GroupsService.GetGroupRoleMembers(RequestingAgentID, GroupID);
|
|
||||||
if (_rm != null && _rm.Count > 0)
|
|
||||||
{
|
|
||||||
List<GroupRoleMembersData> rm = _rm.ConvertAll<GroupRoleMembersData>(new Converter<ExtendedGroupRoleMembersData, GroupRoleMembersData>(m_ForeignImporter.ConvertGroupRoleMembersData));
|
|
||||||
return rm;
|
|
||||||
}
|
|
||||||
|
|
||||||
return new List<GroupRoleMembersData>();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool AddAgentToGroup(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID, string token, out string reason)
|
|
||||||
{
|
|
||||||
return m_GroupsService.AddAgentToGroup(RequestingAgentID, AgentID, GroupID, RoleID, token, out reason);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RemoveAgentFromGroup(string RequestingAgentID, string AgentID, UUID GroupID)
|
|
||||||
{
|
|
||||||
m_GroupsService.RemoveAgentFromGroup(RequestingAgentID, AgentID, GroupID);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool AddAgentToGroupInvite(string RequestingAgentID, UUID inviteID, UUID groupID, UUID roleID, string agentID)
|
|
||||||
{
|
|
||||||
return m_GroupsService.AddAgentToGroupInvite(RequestingAgentID, inviteID, groupID, roleID, agentID);
|
|
||||||
}
|
|
||||||
|
|
||||||
public GroupInviteInfo GetAgentToGroupInvite(string RequestingAgentID, UUID inviteID)
|
|
||||||
{
|
|
||||||
return m_GroupsService.GetAgentToGroupInvite(RequestingAgentID, inviteID); ;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RemoveAgentToGroupInvite(string RequestingAgentID, UUID inviteID)
|
|
||||||
{
|
|
||||||
m_GroupsService.RemoveAgentToGroupInvite(RequestingAgentID, inviteID);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void AddAgentToGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID)
|
|
||||||
{
|
|
||||||
m_GroupsService.AddAgentToGroupRole(RequestingAgentID, AgentID, GroupID, RoleID);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RemoveAgentFromGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID)
|
|
||||||
{
|
|
||||||
m_GroupsService.RemoveAgentFromGroupRole(RequestingAgentID, AgentID, GroupID, RoleID);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<GroupRolesData> GetAgentGroupRoles(string RequestingAgentID, string AgentID, UUID GroupID)
|
|
||||||
{
|
|
||||||
return m_GroupsService.GetAgentGroupRoles(RequestingAgentID, AgentID, GroupID);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetAgentActiveGroup(string RequestingAgentID, string AgentID, UUID GroupID)
|
|
||||||
{
|
|
||||||
m_GroupsService.SetAgentActiveGroup(RequestingAgentID, AgentID, GroupID);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ExtendedGroupMembershipData GetAgentActiveMembership(string RequestingAgentID, string AgentID)
|
|
||||||
{
|
|
||||||
return m_GroupsService.GetAgentActiveMembership(RequestingAgentID, AgentID);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetAgentActiveGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID)
|
|
||||||
{
|
|
||||||
m_GroupsService.SetAgentActiveGroupRole(RequestingAgentID, AgentID, GroupID, RoleID);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UpdateMembership(string RequestingAgentID, string AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile)
|
|
||||||
{
|
|
||||||
m_GroupsService.UpdateMembership(RequestingAgentID, AgentID, GroupID, AcceptNotices, ListInProfile);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ExtendedGroupMembershipData GetAgentGroupMembership(string RequestingAgentID, string AgentID, UUID GroupID)
|
|
||||||
{
|
|
||||||
return m_GroupsService.GetAgentGroupMembership(RequestingAgentID, AgentID, GroupID); ;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<GroupMembershipData> GetAgentGroupMemberships(string RequestingAgentID, string AgentID)
|
|
||||||
{
|
|
||||||
return m_GroupsService.GetAgentGroupMemberships(RequestingAgentID, AgentID);
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
return m_GroupsService.AddGroupNotice(RequestingAgentID, groupID, noticeID, fromName, subject, message,
|
|
||||||
hasAttachment, attType, attName, attItemID, attOwnerID);
|
|
||||||
}
|
|
||||||
|
|
||||||
public GroupNoticeInfo GetGroupNotice(string RequestingAgentID, UUID noticeID)
|
|
||||||
{
|
|
||||||
GroupNoticeInfo notice = m_GroupsService.GetGroupNotice(RequestingAgentID, noticeID);
|
|
||||||
|
|
||||||
//if (notice != null && notice.noticeData.HasAttachment && notice.noticeData.AttachmentOwnerID != null)
|
|
||||||
//{
|
|
||||||
// UUID userID = UUID.Zero;
|
|
||||||
// string url = string.Empty, first = string.Empty, last = string.Empty, tmp = string.Empty;
|
|
||||||
// Util.ParseUniversalUserIdentifier(notice.noticeData.AttachmentOwnerID, out userID, out url, out first, out last, out tmp);
|
|
||||||
// if (url != string.Empty)
|
|
||||||
// m_UserManagement.AddUser(userID, first, last, url);
|
|
||||||
//}
|
|
||||||
|
|
||||||
return notice;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<ExtendedGroupNoticeData> GetGroupNotices(string RequestingAgentID, UUID GroupID)
|
|
||||||
{
|
|
||||||
return m_GroupsService.GetGroupNotices(RequestingAgentID, GroupID);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
using System.Reflection;
|
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using Mono.Addins;
|
|
||||||
|
|
||||||
// General Information about an assembly is controlled through the following
|
|
||||||
// set of attributes. Change these attribute values to modify the information
|
|
||||||
// associated with an assembly.
|
|
||||||
[assembly: AssemblyTitle("OpenSim.Addons.Groups")]
|
|
||||||
[assembly: AssemblyDescription("")]
|
|
||||||
[assembly: AssemblyConfiguration("")]
|
|
||||||
[assembly: AssemblyCompany("http://opensimulator.org")]
|
|
||||||
[assembly: AssemblyProduct("OpenSim.Addons.Groups")]
|
|
||||||
[assembly: AssemblyCopyright("Copyright (c) OpenSimulator.org Developers")]
|
|
||||||
[assembly: AssemblyTrademark("")]
|
|
||||||
[assembly: AssemblyCulture("")]
|
|
||||||
|
|
||||||
// Setting ComVisible to false makes the types in this assembly not visible
|
|
||||||
// to COM components. If you need to access a type in this assembly from
|
|
||||||
// COM, set the ComVisible attribute to true on that type.
|
|
||||||
[assembly: ComVisible(false)]
|
|
||||||
|
|
||||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
|
||||||
[assembly: Guid("313d4865-d179-4735-9b5a-fe74885878b2")]
|
|
||||||
|
|
||||||
// Version information for an assembly consists of the following four values:
|
|
||||||
//
|
|
||||||
// Major Version
|
|
||||||
// Minor Version
|
|
||||||
// Build Number
|
|
||||||
// Revision
|
|
||||||
//
|
|
||||||
[assembly: AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)]
|
|
||||||
|
|
||||||
[assembly: Addin("OpenSim.Groups", OpenSim.VersionInfo.VersionNumber)]
|
|
||||||
[assembly: AddinDependency("OpenSim.Region.Framework", OpenSim.VersionInfo.VersionNumber)]
|
|
|
@ -1,696 +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.Reflection;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
using OpenSim.Framework;
|
|
||||||
using OpenSim.Framework.ServiceAuth;
|
|
||||||
using OpenSim.Server.Base;
|
|
||||||
|
|
||||||
using OpenMetaverse;
|
|
||||||
using log4net;
|
|
||||||
using Nini.Config;
|
|
||||||
|
|
||||||
namespace OpenSim.Groups
|
|
||||||
{
|
|
||||||
public class GroupsServiceRemoteConnector
|
|
||||||
{
|
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
|
||||||
|
|
||||||
private string m_ServerURI;
|
|
||||||
private IServiceAuth m_Auth;
|
|
||||||
private object m_Lock = new object();
|
|
||||||
|
|
||||||
public GroupsServiceRemoteConnector(IConfigSource config)
|
|
||||||
{
|
|
||||||
IConfig groupsConfig = config.Configs["Groups"];
|
|
||||||
string url = groupsConfig.GetString("GroupsServerURI", string.Empty);
|
|
||||||
if (!Uri.IsWellFormedUriString(url, UriKind.Absolute))
|
|
||||||
throw new Exception(string.Format("[Groups.RemoteConnector]: Malformed groups server URL {0}. Fix it or disable the Groups feature.", url));
|
|
||||||
|
|
||||||
m_ServerURI = url;
|
|
||||||
if (!m_ServerURI.EndsWith("/"))
|
|
||||||
m_ServerURI += "/";
|
|
||||||
|
|
||||||
/// This is from BaseServiceConnector
|
|
||||||
string authType = Util.GetConfigVarFromSections<string>(config, "AuthType", new string[] { "Network", "Groups" }, "None");
|
|
||||||
|
|
||||||
switch (authType)
|
|
||||||
{
|
|
||||||
case "BasicHttpAuthentication":
|
|
||||||
m_Auth = new BasicHttpAuthentication(config, "Groups");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
///
|
|
||||||
|
|
||||||
m_log.DebugFormat("[Groups.RemoteConnector]: Groups server at {0}, authentication {1}",
|
|
||||||
m_ServerURI, (m_Auth == null ? "None" : m_Auth.GetType().ToString()));
|
|
||||||
}
|
|
||||||
|
|
||||||
public ExtendedGroupRecord CreateGroup(string RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment,
|
|
||||||
bool allowPublish, bool maturePublish, UUID founderID, out string reason)
|
|
||||||
{
|
|
||||||
reason = string.Empty;
|
|
||||||
|
|
||||||
ExtendedGroupRecord rec = new ExtendedGroupRecord();
|
|
||||||
rec.AllowPublish = allowPublish;
|
|
||||||
rec.Charter = charter;
|
|
||||||
rec.FounderID = founderID;
|
|
||||||
rec.GroupName = name;
|
|
||||||
rec.GroupPicture = insigniaID;
|
|
||||||
rec.MaturePublish = maturePublish;
|
|
||||||
rec.MembershipFee = membershipFee;
|
|
||||||
rec.OpenEnrollment = openEnrollment;
|
|
||||||
rec.ShowInList = showInList;
|
|
||||||
|
|
||||||
Dictionary<string, object> sendData = GroupsDataUtils.GroupRecord(rec);
|
|
||||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
|
||||||
sendData["OP"] = "ADD";
|
|
||||||
Dictionary<string, object> ret = MakeRequest("PUTGROUP", sendData);
|
|
||||||
|
|
||||||
if (ret == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
if (ret["RESULT"].ToString() == "NULL")
|
|
||||||
{
|
|
||||||
reason = ret["REASON"].ToString();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return GroupsDataUtils.GroupRecord((Dictionary<string, object>)ret["RESULT"]);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public ExtendedGroupRecord UpdateGroup(string RequestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish)
|
|
||||||
{
|
|
||||||
ExtendedGroupRecord rec = new ExtendedGroupRecord();
|
|
||||||
rec.AllowPublish = allowPublish;
|
|
||||||
rec.Charter = charter;
|
|
||||||
rec.GroupPicture = insigniaID;
|
|
||||||
rec.MaturePublish = maturePublish;
|
|
||||||
rec.GroupID = groupID;
|
|
||||||
rec.MembershipFee = membershipFee;
|
|
||||||
rec.OpenEnrollment = openEnrollment;
|
|
||||||
rec.ShowInList = showInList;
|
|
||||||
|
|
||||||
Dictionary<string, object> sendData = GroupsDataUtils.GroupRecord(rec);
|
|
||||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
|
||||||
sendData["OP"] = "UPDATE";
|
|
||||||
Dictionary<string, object> ret = MakeRequest("PUTGROUP", sendData);
|
|
||||||
|
|
||||||
if (ret == null || (ret != null && (!ret.ContainsKey("RESULT") || ret["RESULT"].ToString() == "NULL")))
|
|
||||||
return null;
|
|
||||||
|
|
||||||
return GroupsDataUtils.GroupRecord((Dictionary<string, object>)ret["RESULT"]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ExtendedGroupRecord GetGroupRecord(string RequestingAgentID, UUID GroupID, string GroupName)
|
|
||||||
{
|
|
||||||
if (GroupID == UUID.Zero && (GroupName == null || (GroupName != null && GroupName == string.Empty)))
|
|
||||||
return null;
|
|
||||||
|
|
||||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
|
||||||
if (GroupID != UUID.Zero)
|
|
||||||
sendData["GroupID"] = GroupID.ToString();
|
|
||||||
if (!string.IsNullOrEmpty(GroupName))
|
|
||||||
sendData["Name"] = GroupsDataUtils.Sanitize(GroupName);
|
|
||||||
|
|
||||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
|
||||||
|
|
||||||
Dictionary<string, object> ret = MakeRequest("GETGROUP", sendData);
|
|
||||||
|
|
||||||
if (ret == null || (ret != null && (!ret.ContainsKey("RESULT") || ret["RESULT"].ToString() == "NULL")))
|
|
||||||
return null;
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
reason = string.Empty;
|
|
||||||
|
|
||||||
Dictionary<string, object> sendData = new Dictionary<string,object>();
|
|
||||||
sendData["AgentID"] = AgentID;
|
|
||||||
sendData["GroupID"] = GroupID.ToString();
|
|
||||||
sendData["RoleID"] = RoleID.ToString();
|
|
||||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
|
||||||
sendData["AccessToken"] = token;
|
|
||||||
Dictionary<string, object> ret = MakeRequest("ADDAGENTTOGROUP", sendData);
|
|
||||||
|
|
||||||
if (ret == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
if (!ret.ContainsKey("RESULT"))
|
|
||||||
return null;
|
|
||||||
|
|
||||||
if (ret["RESULT"].ToString() == "NULL")
|
|
||||||
{
|
|
||||||
reason = ret["REASON"].ToString();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return GroupsDataUtils.GroupMembershipData((Dictionary<string, object>)ret["RESULT"]);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RemoveAgentFromGroup(string RequestingAgentID, string AgentID, UUID GroupID)
|
|
||||||
{
|
|
||||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
|
||||||
sendData["AgentID"] = AgentID;
|
|
||||||
sendData["GroupID"] = GroupID.ToString();
|
|
||||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
|
||||||
MakeRequest("REMOVEAGENTFROMGROUP", sendData);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ExtendedGroupMembershipData GetMembership(string RequestingAgentID, string AgentID, UUID GroupID)
|
|
||||||
{
|
|
||||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
|
||||||
sendData["AgentID"] = AgentID;
|
|
||||||
if (GroupID != UUID.Zero)
|
|
||||||
sendData["GroupID"] = GroupID.ToString();
|
|
||||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
|
||||||
Dictionary<string, object> ret = MakeRequest("GETMEMBERSHIP", sendData);
|
|
||||||
|
|
||||||
if (ret == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
if (!ret.ContainsKey("RESULT"))
|
|
||||||
return null;
|
|
||||||
|
|
||||||
if (ret["RESULT"].ToString() == "NULL")
|
|
||||||
return null;
|
|
||||||
|
|
||||||
return GroupsDataUtils.GroupMembershipData((Dictionary<string, object>)ret["RESULT"]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<GroupMembershipData> GetMemberships(string RequestingAgentID, string AgentID)
|
|
||||||
{
|
|
||||||
List<GroupMembershipData> memberships = new List<GroupMembershipData>();
|
|
||||||
|
|
||||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
|
||||||
sendData["AgentID"] = AgentID;
|
|
||||||
sendData["ALL"] = "true";
|
|
||||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
|
||||||
Dictionary<string, object> ret = MakeRequest("GETMEMBERSHIP", sendData);
|
|
||||||
|
|
||||||
if (ret == null)
|
|
||||||
return memberships;
|
|
||||||
|
|
||||||
if (!ret.ContainsKey("RESULT"))
|
|
||||||
return memberships;
|
|
||||||
|
|
||||||
if (ret["RESULT"].ToString() == "NULL")
|
|
||||||
return memberships;
|
|
||||||
|
|
||||||
foreach (object v in ((Dictionary<string, object>)ret["RESULT"]).Values)
|
|
||||||
{
|
|
||||||
GroupMembershipData m = GroupsDataUtils.GroupMembershipData((Dictionary<string, object>)v);
|
|
||||||
memberships.Add(m);
|
|
||||||
}
|
|
||||||
|
|
||||||
return memberships;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<ExtendedGroupMembersData> GetGroupMembers(string RequestingAgentID, UUID GroupID)
|
|
||||||
{
|
|
||||||
List<ExtendedGroupMembersData> members = new List<ExtendedGroupMembersData>();
|
|
||||||
|
|
||||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
|
||||||
sendData["GroupID"] = GroupID.ToString();
|
|
||||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
|
||||||
|
|
||||||
Dictionary<string, object> ret = MakeRequest("GETGROUPMEMBERS", sendData);
|
|
||||||
|
|
||||||
if (ret == null)
|
|
||||||
return members;
|
|
||||||
|
|
||||||
if (!ret.ContainsKey("RESULT"))
|
|
||||||
return members;
|
|
||||||
|
|
||||||
if (ret["RESULT"].ToString() == "NULL")
|
|
||||||
return members;
|
|
||||||
|
|
||||||
foreach (object v in ((Dictionary<string, object>)ret["RESULT"]).Values)
|
|
||||||
{
|
|
||||||
ExtendedGroupMembersData m = GroupsDataUtils.GroupMembersData((Dictionary<string, object>)v);
|
|
||||||
members.Add(m);
|
|
||||||
}
|
|
||||||
|
|
||||||
return members;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool AddGroupRole(string RequestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers, out string reason)
|
|
||||||
{
|
|
||||||
reason = string.Empty;
|
|
||||||
|
|
||||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
|
||||||
sendData["GroupID"] = groupID.ToString();
|
|
||||||
sendData["RoleID"] = roleID.ToString();
|
|
||||||
sendData["Name"] = GroupsDataUtils.Sanitize(name);
|
|
||||||
sendData["Description"] = GroupsDataUtils.Sanitize(description);
|
|
||||||
sendData["Title"] = GroupsDataUtils.Sanitize(title);
|
|
||||||
sendData["Powers"] = powers.ToString();
|
|
||||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
|
||||||
sendData["OP"] = "ADD";
|
|
||||||
Dictionary<string, object> ret = MakeRequest("PUTROLE", sendData);
|
|
||||||
|
|
||||||
if (ret == null)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!ret.ContainsKey("RESULT"))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (ret["RESULT"].ToString().ToLower() != "true")
|
|
||||||
{
|
|
||||||
reason = ret["REASON"].ToString();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool UpdateGroupRole(string RequestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers)
|
|
||||||
{
|
|
||||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
|
||||||
sendData["GroupID"] = groupID.ToString();
|
|
||||||
sendData["RoleID"] = roleID.ToString();
|
|
||||||
sendData["Name"] = GroupsDataUtils.Sanitize(name);
|
|
||||||
sendData["Description"] = GroupsDataUtils.Sanitize(description);
|
|
||||||
sendData["Title"] = GroupsDataUtils.Sanitize(title);
|
|
||||||
sendData["Powers"] = powers.ToString();
|
|
||||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
|
||||||
sendData["OP"] = "UPDATE";
|
|
||||||
Dictionary<string, object> ret = MakeRequest("PUTROLE", sendData);
|
|
||||||
|
|
||||||
if (ret == null)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!ret.ContainsKey("RESULT"))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (ret["RESULT"].ToString().ToLower() != "true")
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RemoveGroupRole(string RequestingAgentID, UUID groupID, UUID roleID)
|
|
||||||
{
|
|
||||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
|
||||||
sendData["GroupID"] = groupID.ToString();
|
|
||||||
sendData["RoleID"] = roleID.ToString();
|
|
||||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
|
||||||
MakeRequest("REMOVEROLE", sendData);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<GroupRolesData> GetGroupRoles(string RequestingAgentID, UUID GroupID)
|
|
||||||
{
|
|
||||||
List<GroupRolesData> roles = new List<GroupRolesData>();
|
|
||||||
|
|
||||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
|
||||||
sendData["GroupID"] = GroupID.ToString();
|
|
||||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
|
||||||
Dictionary<string, object> ret = MakeRequest("GETGROUPROLES", sendData);
|
|
||||||
|
|
||||||
if (ret == null)
|
|
||||||
return roles;
|
|
||||||
|
|
||||||
if (!ret.ContainsKey("RESULT"))
|
|
||||||
return roles;
|
|
||||||
|
|
||||||
if (ret["RESULT"].ToString() == "NULL")
|
|
||||||
return roles;
|
|
||||||
|
|
||||||
foreach (object v in ((Dictionary<string, object>)ret["RESULT"]).Values)
|
|
||||||
{
|
|
||||||
GroupRolesData m = GroupsDataUtils.GroupRolesData((Dictionary<string, object>)v);
|
|
||||||
roles.Add(m);
|
|
||||||
}
|
|
||||||
|
|
||||||
return roles;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<ExtendedGroupRoleMembersData> GetGroupRoleMembers(string RequestingAgentID, UUID GroupID)
|
|
||||||
{
|
|
||||||
List<ExtendedGroupRoleMembersData> rmembers = new List<ExtendedGroupRoleMembersData>();
|
|
||||||
|
|
||||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
|
||||||
sendData["GroupID"] = GroupID.ToString();
|
|
||||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
|
||||||
Dictionary<string, object> ret = MakeRequest("GETROLEMEMBERS", sendData);
|
|
||||||
|
|
||||||
if (ret == null)
|
|
||||||
return rmembers;
|
|
||||||
|
|
||||||
if (!ret.ContainsKey("RESULT"))
|
|
||||||
return rmembers;
|
|
||||||
|
|
||||||
if (ret["RESULT"].ToString() == "NULL")
|
|
||||||
return rmembers;
|
|
||||||
|
|
||||||
foreach (object v in ((Dictionary<string, object>)ret["RESULT"]).Values)
|
|
||||||
{
|
|
||||||
ExtendedGroupRoleMembersData m = GroupsDataUtils.GroupRoleMembersData((Dictionary<string, object>)v);
|
|
||||||
rmembers.Add(m);
|
|
||||||
}
|
|
||||||
|
|
||||||
return rmembers;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool AddAgentToGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID)
|
|
||||||
{
|
|
||||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
|
||||||
sendData["AgentID"] = AgentID.ToString();
|
|
||||||
sendData["GroupID"] = GroupID.ToString();
|
|
||||||
sendData["RoleID"] = RoleID.ToString();
|
|
||||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
|
||||||
sendData["OP"] = "ADD";
|
|
||||||
|
|
||||||
Dictionary<string, object> ret = MakeRequest("AGENTROLE", sendData);
|
|
||||||
|
|
||||||
if (ret == null)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!ret.ContainsKey("RESULT"))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (ret["RESULT"].ToString().ToLower() != "true")
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool RemoveAgentFromGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID)
|
|
||||||
{
|
|
||||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
|
||||||
sendData["AgentID"] = AgentID.ToString();
|
|
||||||
sendData["GroupID"] = GroupID.ToString();
|
|
||||||
sendData["RoleID"] = RoleID.ToString();
|
|
||||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
|
||||||
sendData["OP"] = "DELETE";
|
|
||||||
|
|
||||||
Dictionary<string, object> ret = MakeRequest("AGENTROLE", sendData);
|
|
||||||
|
|
||||||
if (ret == null)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!ret.ContainsKey("RESULT"))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (ret["RESULT"].ToString().ToLower() != "true")
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<GroupRolesData> GetAgentGroupRoles(string RequestingAgentID, string AgentID, UUID GroupID)
|
|
||||||
{
|
|
||||||
List<GroupRolesData> roles = new List<GroupRolesData>();
|
|
||||||
|
|
||||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
|
||||||
sendData["AgentID"] = AgentID.ToString();
|
|
||||||
sendData["GroupID"] = GroupID.ToString();
|
|
||||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
|
||||||
Dictionary<string, object> ret = MakeRequest("GETAGENTROLES", sendData);
|
|
||||||
|
|
||||||
if (ret == null)
|
|
||||||
return roles;
|
|
||||||
|
|
||||||
if (!ret.ContainsKey("RESULT"))
|
|
||||||
return roles;
|
|
||||||
|
|
||||||
if (ret["RESULT"].ToString() == "NULL")
|
|
||||||
return roles;
|
|
||||||
|
|
||||||
foreach (object v in ((Dictionary<string, object>)ret["RESULT"]).Values)
|
|
||||||
{
|
|
||||||
GroupRolesData m = GroupsDataUtils.GroupRolesData((Dictionary<string, object>)v);
|
|
||||||
roles.Add(m);
|
|
||||||
}
|
|
||||||
|
|
||||||
return roles;
|
|
||||||
}
|
|
||||||
|
|
||||||
public GroupMembershipData SetAgentActiveGroup(string RequestingAgentID, string AgentID, UUID GroupID)
|
|
||||||
{
|
|
||||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
|
||||||
sendData["AgentID"] = AgentID.ToString();
|
|
||||||
sendData["GroupID"] = GroupID.ToString();
|
|
||||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
|
||||||
sendData["OP"] = "GROUP";
|
|
||||||
|
|
||||||
Dictionary<string, object> ret = MakeRequest("SETACTIVE", sendData);
|
|
||||||
|
|
||||||
if (ret == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
if (!ret.ContainsKey("RESULT"))
|
|
||||||
return null;
|
|
||||||
|
|
||||||
if (ret["RESULT"].ToString() == "NULL")
|
|
||||||
return null;
|
|
||||||
|
|
||||||
return GroupsDataUtils.GroupMembershipData((Dictionary<string, object>)ret["RESULT"]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetAgentActiveGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID)
|
|
||||||
{
|
|
||||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
|
||||||
sendData["AgentID"] = AgentID.ToString();
|
|
||||||
sendData["GroupID"] = GroupID.ToString();
|
|
||||||
sendData["RoleID"] = RoleID.ToString();
|
|
||||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
|
||||||
sendData["OP"] = "ROLE";
|
|
||||||
|
|
||||||
MakeRequest("SETACTIVE", sendData);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UpdateMembership(string RequestingAgentID, string AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile)
|
|
||||||
{
|
|
||||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
|
||||||
sendData["AgentID"] = AgentID.ToString();
|
|
||||||
sendData["GroupID"] = GroupID.ToString();
|
|
||||||
sendData["AcceptNotices"] = AcceptNotices.ToString();
|
|
||||||
sendData["ListInProfile"] = ListInProfile.ToString();
|
|
||||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
|
||||||
MakeRequest("UPDATEMEMBERSHIP", sendData);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool AddAgentToGroupInvite(string RequestingAgentID, UUID inviteID, UUID groupID, UUID roleID, string agentID)
|
|
||||||
{
|
|
||||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
|
||||||
sendData["InviteID"] = inviteID.ToString();
|
|
||||||
sendData["GroupID"] = groupID.ToString();
|
|
||||||
sendData["RoleID"] = roleID.ToString();
|
|
||||||
sendData["AgentID"] = agentID.ToString();
|
|
||||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
|
||||||
sendData["OP"] = "ADD";
|
|
||||||
|
|
||||||
Dictionary<string, object> ret = MakeRequest("INVITE", sendData);
|
|
||||||
|
|
||||||
if (ret == null)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!ret.ContainsKey("RESULT"))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (ret["RESULT"].ToString().ToLower() != "true") // it may return "NULL"
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public GroupInviteInfo GetAgentToGroupInvite(string RequestingAgentID, UUID inviteID)
|
|
||||||
{
|
|
||||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
|
||||||
sendData["InviteID"] = inviteID.ToString();
|
|
||||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
|
||||||
sendData["OP"] = "GET";
|
|
||||||
|
|
||||||
Dictionary<string, object> ret = MakeRequest("INVITE", sendData);
|
|
||||||
|
|
||||||
if (ret == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
if (!ret.ContainsKey("RESULT"))
|
|
||||||
return null;
|
|
||||||
|
|
||||||
if (ret["RESULT"].ToString() == "NULL")
|
|
||||||
return null;
|
|
||||||
|
|
||||||
return GroupsDataUtils.GroupInviteInfo((Dictionary<string, object>)ret["RESULT"]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RemoveAgentToGroupInvite(string RequestingAgentID, UUID inviteID)
|
|
||||||
{
|
|
||||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
|
||||||
sendData["InviteID"] = inviteID.ToString();
|
|
||||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
|
||||||
sendData["OP"] = "DELETE";
|
|
||||||
|
|
||||||
MakeRequest("INVITE", sendData);
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
|
||||||
sendData["GroupID"] = groupID.ToString();
|
|
||||||
sendData["NoticeID"] = noticeID.ToString();
|
|
||||||
sendData["FromName"] = GroupsDataUtils.Sanitize(fromName);
|
|
||||||
sendData["Subject"] = GroupsDataUtils.Sanitize(subject);
|
|
||||||
sendData["Message"] = GroupsDataUtils.Sanitize(message);
|
|
||||||
sendData["HasAttachment"] = hasAttachment.ToString();
|
|
||||||
if (hasAttachment)
|
|
||||||
{
|
|
||||||
sendData["AttachmentType"] = attType.ToString();
|
|
||||||
sendData["AttachmentName"] = attName.ToString();
|
|
||||||
sendData["AttachmentItemID"] = attItemID.ToString();
|
|
||||||
sendData["AttachmentOwnerID"] = attOwnerID;
|
|
||||||
}
|
|
||||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
|
||||||
|
|
||||||
Dictionary<string, object> ret = MakeRequest("ADDNOTICE", sendData);
|
|
||||||
|
|
||||||
if (ret == null)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!ret.ContainsKey("RESULT"))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (ret["RESULT"].ToString().ToLower() != "true")
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public GroupNoticeInfo GetGroupNotice(string RequestingAgentID, UUID noticeID)
|
|
||||||
{
|
|
||||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
|
||||||
sendData["NoticeID"] = noticeID.ToString();
|
|
||||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
|
||||||
|
|
||||||
Dictionary<string, object> ret = MakeRequest("GETNOTICES", sendData);
|
|
||||||
|
|
||||||
if (ret == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
if (!ret.ContainsKey("RESULT"))
|
|
||||||
return null;
|
|
||||||
|
|
||||||
if (ret["RESULT"].ToString() == "NULL")
|
|
||||||
return null;
|
|
||||||
|
|
||||||
return GroupsDataUtils.GroupNoticeInfo((Dictionary<string, object>)ret["RESULT"]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<ExtendedGroupNoticeData> GetGroupNotices(string RequestingAgentID, UUID GroupID)
|
|
||||||
{
|
|
||||||
List<ExtendedGroupNoticeData> notices = new List<ExtendedGroupNoticeData>();
|
|
||||||
|
|
||||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
|
||||||
sendData["GroupID"] = GroupID.ToString();
|
|
||||||
sendData["RequestingAgentID"] = RequestingAgentID;
|
|
||||||
Dictionary<string, object> ret = MakeRequest("GETNOTICES", sendData);
|
|
||||||
|
|
||||||
if (ret == null)
|
|
||||||
return notices;
|
|
||||||
|
|
||||||
if (!ret.ContainsKey("RESULT"))
|
|
||||||
return notices;
|
|
||||||
|
|
||||||
if (ret["RESULT"].ToString() == "NULL")
|
|
||||||
return notices;
|
|
||||||
|
|
||||||
foreach (object v in ((Dictionary<string, object>)ret["RESULT"]).Values)
|
|
||||||
{
|
|
||||||
ExtendedGroupNoticeData m = GroupsDataUtils.GroupNoticeData((Dictionary<string, object>)v);
|
|
||||||
notices.Add(m);
|
|
||||||
}
|
|
||||||
|
|
||||||
return notices;
|
|
||||||
}
|
|
||||||
|
|
||||||
#region Make Request
|
|
||||||
|
|
||||||
private Dictionary<string, object> MakeRequest(string method, Dictionary<string, object> sendData)
|
|
||||||
{
|
|
||||||
sendData["METHOD"] = method;
|
|
||||||
|
|
||||||
string reply = string.Empty;
|
|
||||||
lock (m_Lock)
|
|
||||||
reply = SynchronousRestFormsRequester.MakeRequest("POST",
|
|
||||||
m_ServerURI + "groups",
|
|
||||||
ServerUtils.BuildQueryString(sendData),
|
|
||||||
m_Auth);
|
|
||||||
|
|
||||||
if (reply == string.Empty)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(
|
|
||||||
reply);
|
|
||||||
|
|
||||||
return replyData;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,408 +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.Reflection;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
using OpenSim.Framework;
|
|
||||||
using OpenSim.Region.Framework.Scenes;
|
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
|
||||||
using OpenSim.Server.Base;
|
|
||||||
using OpenSim.Services.Interfaces;
|
|
||||||
|
|
||||||
using OpenMetaverse;
|
|
||||||
using Mono.Addins;
|
|
||||||
using log4net;
|
|
||||||
using Nini.Config;
|
|
||||||
|
|
||||||
namespace OpenSim.Groups
|
|
||||||
{
|
|
||||||
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GroupsServiceRemoteConnectorModule")]
|
|
||||||
public class GroupsServiceRemoteConnectorModule : ISharedRegionModule, IGroupsServicesConnector
|
|
||||||
{
|
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
|
||||||
|
|
||||||
private bool m_Enabled = false;
|
|
||||||
private GroupsServiceRemoteConnector m_GroupsService;
|
|
||||||
private IUserManagement m_UserManagement;
|
|
||||||
private List<Scene> m_Scenes;
|
|
||||||
|
|
||||||
private RemoteConnectorCacheWrapper m_CacheWrapper;
|
|
||||||
|
|
||||||
#region constructors
|
|
||||||
public GroupsServiceRemoteConnectorModule()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public GroupsServiceRemoteConnectorModule(IConfigSource config, IUserManagement uman)
|
|
||||||
{
|
|
||||||
Init(config);
|
|
||||||
m_UserManagement = uman;
|
|
||||||
m_CacheWrapper = new RemoteConnectorCacheWrapper(m_UserManagement);
|
|
||||||
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
private void Init(IConfigSource config)
|
|
||||||
{
|
|
||||||
m_GroupsService = new GroupsServiceRemoteConnector(config);
|
|
||||||
m_Scenes = new List<Scene>();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#region ISharedRegionModule
|
|
||||||
|
|
||||||
public void Initialise(IConfigSource config)
|
|
||||||
{
|
|
||||||
IConfig groupsConfig = config.Configs["Groups"];
|
|
||||||
if (groupsConfig == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if ((groupsConfig.GetBoolean("Enabled", false) == false)
|
|
||||||
|| (groupsConfig.GetString("ServicesConnectorModule", string.Empty) != Name))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Init(config);
|
|
||||||
|
|
||||||
m_Enabled = true;
|
|
||||||
m_log.DebugFormat("[Groups.RemoteConnector]: Initializing {0}", this.Name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Name
|
|
||||||
{
|
|
||||||
get { return "Groups Remote Service Connector"; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public Type ReplaceableInterface
|
|
||||||
{
|
|
||||||
get { return null; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public void AddRegion(Scene scene)
|
|
||||||
{
|
|
||||||
if (!m_Enabled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_log.DebugFormat("[Groups.RemoteConnector]: Registering {0} with {1}", this.Name, scene.RegionInfo.RegionName);
|
|
||||||
scene.RegisterModuleInterface<IGroupsServicesConnector>(this);
|
|
||||||
m_Scenes.Add(scene);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RemoveRegion(Scene scene)
|
|
||||||
{
|
|
||||||
if (!m_Enabled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
scene.UnregisterModuleInterface<IGroupsServicesConnector>(this);
|
|
||||||
m_Scenes.Remove(scene);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RegionLoaded(Scene scene)
|
|
||||||
{
|
|
||||||
if (!m_Enabled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (m_UserManagement == null)
|
|
||||||
{
|
|
||||||
m_UserManagement = scene.RequestModuleInterface<IUserManagement>();
|
|
||||||
m_CacheWrapper = new RemoteConnectorCacheWrapper(m_UserManagement);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void PostInitialise()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Close()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region IGroupsServicesConnector
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
m_log.DebugFormat("[Groups.RemoteConnector]: Creating group {0}", name);
|
|
||||||
string r = string.Empty;
|
|
||||||
|
|
||||||
UUID groupID = m_CacheWrapper.CreateGroup(RequestingAgentID, delegate
|
|
||||||
{
|
|
||||||
return m_GroupsService.CreateGroup(RequestingAgentID.ToString(), name, charter, showInList, insigniaID,
|
|
||||||
membershipFee, openEnrollment, allowPublish, maturePublish, founderID, out r);
|
|
||||||
});
|
|
||||||
|
|
||||||
reason = r;
|
|
||||||
return groupID;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool UpdateGroup(string RequestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee,
|
|
||||||
bool openEnrollment, bool allowPublish, bool maturePublish, out string reason)
|
|
||||||
{
|
|
||||||
string r = string.Empty;
|
|
||||||
|
|
||||||
bool success = m_CacheWrapper.UpdateGroup(groupID, delegate
|
|
||||||
{
|
|
||||||
return m_GroupsService.UpdateGroup(RequestingAgentID, groupID, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish);
|
|
||||||
});
|
|
||||||
|
|
||||||
reason = r;
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ExtendedGroupRecord GetGroupRecord(string RequestingAgentID, UUID GroupID, string GroupName)
|
|
||||||
{
|
|
||||||
if (GroupID == UUID.Zero && (GroupName == null || GroupName != null && GroupName == string.Empty))
|
|
||||||
return null;
|
|
||||||
|
|
||||||
return m_CacheWrapper.GetGroupRecord(RequestingAgentID,GroupID,GroupName, delegate
|
|
||||||
{
|
|
||||||
return m_GroupsService.GetGroupRecord(RequestingAgentID, GroupID, GroupName);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<DirGroupsReplyData> FindGroups(string RequestingAgentIDstr, string search)
|
|
||||||
{
|
|
||||||
// TODO!
|
|
||||||
return m_GroupsService.FindGroups(RequestingAgentIDstr, search);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool AddAgentToGroup(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID, string token, out string reason)
|
|
||||||
{
|
|
||||||
string agentFullID = AgentID;
|
|
||||||
m_log.DebugFormat("[Groups.RemoteConnector]: Add agent {0} to group {1}", agentFullID, GroupID);
|
|
||||||
string r = string.Empty;
|
|
||||||
|
|
||||||
bool success = m_CacheWrapper.AddAgentToGroup(RequestingAgentID, AgentID, GroupID, delegate
|
|
||||||
{
|
|
||||||
return m_GroupsService.AddAgentToGroup(RequestingAgentID, agentFullID, GroupID, RoleID, token, out r);
|
|
||||||
});
|
|
||||||
|
|
||||||
reason = r;
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RemoveAgentFromGroup(string RequestingAgentID, string AgentID, UUID GroupID)
|
|
||||||
{
|
|
||||||
m_CacheWrapper.RemoveAgentFromGroup(RequestingAgentID, AgentID, GroupID, delegate
|
|
||||||
{
|
|
||||||
m_GroupsService.RemoveAgentFromGroup(RequestingAgentID, AgentID, GroupID);
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetAgentActiveGroup(string RequestingAgentID, string AgentID, UUID GroupID)
|
|
||||||
{
|
|
||||||
m_CacheWrapper.SetAgentActiveGroup(AgentID, delegate
|
|
||||||
{
|
|
||||||
return m_GroupsService.SetAgentActiveGroup(RequestingAgentID, AgentID, GroupID);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public ExtendedGroupMembershipData GetAgentActiveMembership(string RequestingAgentID, string AgentID)
|
|
||||||
{
|
|
||||||
return m_CacheWrapper.GetAgentActiveMembership(AgentID, delegate
|
|
||||||
{
|
|
||||||
return m_GroupsService.GetMembership(RequestingAgentID, AgentID, UUID.Zero);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public ExtendedGroupMembershipData GetAgentGroupMembership(string RequestingAgentID, string AgentID, UUID GroupID)
|
|
||||||
{
|
|
||||||
return m_CacheWrapper.GetAgentGroupMembership(AgentID, GroupID, delegate
|
|
||||||
{
|
|
||||||
return m_GroupsService.GetMembership(RequestingAgentID, AgentID, GroupID);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<GroupMembershipData> GetAgentGroupMemberships(string RequestingAgentID, string AgentID)
|
|
||||||
{
|
|
||||||
return m_CacheWrapper.GetAgentGroupMemberships(AgentID, delegate
|
|
||||||
{
|
|
||||||
return m_GroupsService.GetMemberships(RequestingAgentID, AgentID);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public List<GroupMembersData> GetGroupMembers(string RequestingAgentID, UUID GroupID)
|
|
||||||
{
|
|
||||||
return m_CacheWrapper.GetGroupMembers(RequestingAgentID, GroupID, delegate
|
|
||||||
{
|
|
||||||
return m_GroupsService.GetGroupMembers(RequestingAgentID, GroupID);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool AddGroupRole(string RequestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers, out string reason)
|
|
||||||
{
|
|
||||||
string r = string.Empty;
|
|
||||||
bool success = m_CacheWrapper.AddGroupRole(groupID, roleID, description, name, powers, title, delegate
|
|
||||||
{
|
|
||||||
return m_GroupsService.AddGroupRole(RequestingAgentID, groupID, roleID, name, description, title, powers, out r);
|
|
||||||
});
|
|
||||||
|
|
||||||
reason = r;
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool UpdateGroupRole(string RequestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers)
|
|
||||||
{
|
|
||||||
return m_CacheWrapper.UpdateGroupRole(groupID, roleID, name, description, title, powers, delegate
|
|
||||||
{
|
|
||||||
return m_GroupsService.UpdateGroupRole(RequestingAgentID, groupID, roleID, name, description, title, powers);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RemoveGroupRole(string RequestingAgentID, UUID groupID, UUID roleID)
|
|
||||||
{
|
|
||||||
m_CacheWrapper.RemoveGroupRole(RequestingAgentID, groupID, roleID, delegate
|
|
||||||
{
|
|
||||||
m_GroupsService.RemoveGroupRole(RequestingAgentID, groupID, roleID);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<GroupRolesData> GetGroupRoles(string RequestingAgentID, UUID GroupID)
|
|
||||||
{
|
|
||||||
return m_CacheWrapper.GetGroupRoles(RequestingAgentID, GroupID, delegate
|
|
||||||
{
|
|
||||||
return m_GroupsService.GetGroupRoles(RequestingAgentID, GroupID);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<GroupRoleMembersData> GetGroupRoleMembers(string RequestingAgentID, UUID GroupID)
|
|
||||||
{
|
|
||||||
return m_CacheWrapper.GetGroupRoleMembers(RequestingAgentID, GroupID, delegate
|
|
||||||
{
|
|
||||||
return m_GroupsService.GetGroupRoleMembers(RequestingAgentID, GroupID);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void AddAgentToGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID)
|
|
||||||
{
|
|
||||||
m_CacheWrapper.AddAgentToGroupRole(RequestingAgentID, AgentID, GroupID, RoleID, delegate
|
|
||||||
{
|
|
||||||
return m_GroupsService.AddAgentToGroupRole(RequestingAgentID, AgentID, GroupID, RoleID);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RemoveAgentFromGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID)
|
|
||||||
{
|
|
||||||
m_CacheWrapper.RemoveAgentFromGroupRole(RequestingAgentID, AgentID, GroupID, RoleID, delegate
|
|
||||||
{
|
|
||||||
return m_GroupsService.RemoveAgentFromGroupRole(RequestingAgentID, AgentID, GroupID, RoleID);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<GroupRolesData> GetAgentGroupRoles(string RequestingAgentID, string AgentID, UUID GroupID)
|
|
||||||
{
|
|
||||||
return m_CacheWrapper.GetAgentGroupRoles(RequestingAgentID, AgentID, GroupID, delegate
|
|
||||||
{
|
|
||||||
return m_GroupsService.GetAgentGroupRoles(RequestingAgentID, AgentID, GroupID); ;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetAgentActiveGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID)
|
|
||||||
{
|
|
||||||
m_CacheWrapper.SetAgentActiveGroupRole(AgentID, GroupID, delegate
|
|
||||||
{
|
|
||||||
m_GroupsService.SetAgentActiveGroupRole(RequestingAgentID, AgentID, GroupID, RoleID);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UpdateMembership(string RequestingAgentID, string AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile)
|
|
||||||
{
|
|
||||||
m_CacheWrapper.UpdateMembership(AgentID, GroupID, AcceptNotices, ListInProfile, delegate
|
|
||||||
{
|
|
||||||
m_GroupsService.UpdateMembership(RequestingAgentID, AgentID, GroupID, AcceptNotices, ListInProfile);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool AddAgentToGroupInvite(string RequestingAgentID, UUID inviteID, UUID groupID, UUID roleID, string agentID)
|
|
||||||
{
|
|
||||||
return m_GroupsService.AddAgentToGroupInvite(RequestingAgentID, inviteID, groupID, roleID, agentID);
|
|
||||||
}
|
|
||||||
|
|
||||||
public GroupInviteInfo GetAgentToGroupInvite(string RequestingAgentID, UUID inviteID)
|
|
||||||
{
|
|
||||||
return m_GroupsService.GetAgentToGroupInvite(RequestingAgentID, inviteID);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RemoveAgentToGroupInvite(string RequestingAgentID, UUID inviteID)
|
|
||||||
{
|
|
||||||
m_GroupsService.RemoveAgentToGroupInvite(RequestingAgentID, inviteID);
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
GroupNoticeInfo notice = new GroupNoticeInfo();
|
|
||||||
notice.GroupID = groupID;
|
|
||||||
notice.Message = message;
|
|
||||||
notice.noticeData = new ExtendedGroupNoticeData();
|
|
||||||
notice.noticeData.AttachmentItemID = attItemID;
|
|
||||||
notice.noticeData.AttachmentName = attName;
|
|
||||||
notice.noticeData.AttachmentOwnerID = attOwnerID.ToString();
|
|
||||||
notice.noticeData.AttachmentType = attType;
|
|
||||||
notice.noticeData.FromName = fromName;
|
|
||||||
notice.noticeData.HasAttachment = hasAttachment;
|
|
||||||
notice.noticeData.NoticeID = noticeID;
|
|
||||||
notice.noticeData.Subject = subject;
|
|
||||||
notice.noticeData.Timestamp = (uint)Util.UnixTimeSinceEpoch();
|
|
||||||
|
|
||||||
return m_CacheWrapper.AddGroupNotice(groupID, noticeID, notice, delegate
|
|
||||||
{
|
|
||||||
return m_GroupsService.AddGroupNotice(RequestingAgentID, groupID, noticeID, fromName, subject, message,
|
|
||||||
hasAttachment, attType, attName, attItemID, attOwnerID);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public GroupNoticeInfo GetGroupNotice(string RequestingAgentID, UUID noticeID)
|
|
||||||
{
|
|
||||||
return m_CacheWrapper.GetGroupNotice(noticeID, delegate
|
|
||||||
{
|
|
||||||
return m_GroupsService.GetGroupNotice(RequestingAgentID, noticeID);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<ExtendedGroupNoticeData> GetGroupNotices(string RequestingAgentID, UUID GroupID)
|
|
||||||
{
|
|
||||||
return m_CacheWrapper.GetGroupNotices(GroupID, delegate
|
|
||||||
{
|
|
||||||
return m_GroupsService.GetGroupNotices(RequestingAgentID, GroupID);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,817 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
* * Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* * Neither the name of the OpenSimulator Project nor the
|
|
||||||
* names of its contributors may be used to endorse or promote products
|
|
||||||
* derived from this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
|
||||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Text;
|
|
||||||
using System.Xml;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using Nini.Config;
|
|
||||||
using OpenSim.Framework;
|
|
||||||
using OpenSim.Server.Base;
|
|
||||||
using OpenSim.Services.Interfaces;
|
|
||||||
using OpenSim.Framework.Servers.HttpServer;
|
|
||||||
using OpenSim.Framework.ServiceAuth;
|
|
||||||
using OpenSim.Server.Handlers.Base;
|
|
||||||
using log4net;
|
|
||||||
using OpenMetaverse;
|
|
||||||
|
|
||||||
namespace OpenSim.Groups
|
|
||||||
{
|
|
||||||
public class GroupsServiceRobustConnector : ServiceConnector
|
|
||||||
{
|
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
|
||||||
|
|
||||||
private GroupsService m_GroupsService;
|
|
||||||
private string m_ConfigName = "Groups";
|
|
||||||
|
|
||||||
public GroupsServiceRobustConnector(IConfigSource config, IHttpServer server, string configName) :
|
|
||||||
base(config, server, configName)
|
|
||||||
{
|
|
||||||
string key = string.Empty;
|
|
||||||
if (configName != String.Empty)
|
|
||||||
m_ConfigName = configName;
|
|
||||||
|
|
||||||
m_log.DebugFormat("[Groups.RobustConnector]: Starting with config name {0}", m_ConfigName);
|
|
||||||
|
|
||||||
IConfig groupsConfig = config.Configs[m_ConfigName];
|
|
||||||
if (groupsConfig != null)
|
|
||||||
{
|
|
||||||
key = groupsConfig.GetString("SecretKey", string.Empty);
|
|
||||||
m_log.DebugFormat("[Groups.RobustConnector]: Starting with secret key {0}", key);
|
|
||||||
}
|
|
||||||
// else
|
|
||||||
// m_log.DebugFormat("[Groups.RobustConnector]: Unable to find {0} section in configuration", m_ConfigName);
|
|
||||||
|
|
||||||
m_GroupsService = new GroupsService(config);
|
|
||||||
|
|
||||||
IServiceAuth auth = ServiceAuth.Create(config, m_ConfigName);
|
|
||||||
|
|
||||||
server.AddStreamHandler(new GroupsServicePostHandler(m_GroupsService, auth));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class GroupsServicePostHandler : BaseStreamHandler
|
|
||||||
{
|
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
|
||||||
|
|
||||||
private GroupsService m_GroupsService;
|
|
||||||
|
|
||||||
public GroupsServicePostHandler(GroupsService service, IServiceAuth auth) :
|
|
||||||
base("POST", "/groups", auth)
|
|
||||||
{
|
|
||||||
m_GroupsService = service;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override byte[] ProcessRequest(string path, Stream requestData,
|
|
||||||
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
|
||||||
{
|
|
||||||
string body;
|
|
||||||
using(StreamReader sr = new StreamReader(requestData))
|
|
||||||
body = sr.ReadToEnd();
|
|
||||||
|
|
||||||
body = body.Trim();
|
|
||||||
|
|
||||||
//m_log.DebugFormat("[XXX]: query String: {0}", body);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Dictionary<string, object> request =
|
|
||||||
ServerUtils.ParseQueryString(body);
|
|
||||||
|
|
||||||
if (!request.ContainsKey("METHOD"))
|
|
||||||
return FailureResult();
|
|
||||||
|
|
||||||
string method = request["METHOD"].ToString();
|
|
||||||
request.Remove("METHOD");
|
|
||||||
|
|
||||||
// m_log.DebugFormat("[Groups.Handler]: {0}", method);
|
|
||||||
switch (method)
|
|
||||||
{
|
|
||||||
case "PUTGROUP":
|
|
||||||
return HandleAddOrUpdateGroup(request);
|
|
||||||
case "GETGROUP":
|
|
||||||
return HandleGetGroup(request);
|
|
||||||
case "ADDAGENTTOGROUP":
|
|
||||||
return HandleAddAgentToGroup(request);
|
|
||||||
case "REMOVEAGENTFROMGROUP":
|
|
||||||
return HandleRemoveAgentFromGroup(request);
|
|
||||||
case "GETMEMBERSHIP":
|
|
||||||
return HandleGetMembership(request);
|
|
||||||
case "GETGROUPMEMBERS":
|
|
||||||
return HandleGetGroupMembers(request);
|
|
||||||
case "PUTROLE":
|
|
||||||
return HandlePutRole(request);
|
|
||||||
case "REMOVEROLE":
|
|
||||||
return HandleRemoveRole(request);
|
|
||||||
case "GETGROUPROLES":
|
|
||||||
return HandleGetGroupRoles(request);
|
|
||||||
case "GETROLEMEMBERS":
|
|
||||||
return HandleGetRoleMembers(request);
|
|
||||||
case "AGENTROLE":
|
|
||||||
return HandleAgentRole(request);
|
|
||||||
case "GETAGENTROLES":
|
|
||||||
return HandleGetAgentRoles(request);
|
|
||||||
case "SETACTIVE":
|
|
||||||
return HandleSetActive(request);
|
|
||||||
case "UPDATEMEMBERSHIP":
|
|
||||||
return HandleUpdateMembership(request);
|
|
||||||
case "INVITE":
|
|
||||||
return HandleInvite(request);
|
|
||||||
case "ADDNOTICE":
|
|
||||||
return HandleAddNotice(request);
|
|
||||||
case "GETNOTICES":
|
|
||||||
return HandleGetNotices(request);
|
|
||||||
case "FINDGROUPS":
|
|
||||||
return HandleFindGroups(request);
|
|
||||||
}
|
|
||||||
m_log.DebugFormat("[GROUPS HANDLER]: unknown method request: {0}", method);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
m_log.Error(string.Format("[GROUPS HANDLER]: Exception {0} ", e.Message), e);
|
|
||||||
}
|
|
||||||
|
|
||||||
return FailureResult();
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] HandleAddOrUpdateGroup(Dictionary<string, object> request)
|
|
||||||
{
|
|
||||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
|
||||||
|
|
||||||
ExtendedGroupRecord grec = GroupsDataUtils.GroupRecord(request);
|
|
||||||
if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("OP"))
|
|
||||||
NullResult(result, "Bad network data");
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
string RequestingAgentID = request["RequestingAgentID"].ToString();
|
|
||||||
string reason = string.Empty;
|
|
||||||
string op = request["OP"].ToString();
|
|
||||||
if (op == "ADD")
|
|
||||||
{
|
|
||||||
grec.GroupID = m_GroupsService.CreateGroup(RequestingAgentID, grec.GroupName, grec.Charter, grec.ShowInList, grec.GroupPicture, grec.MembershipFee,
|
|
||||||
grec.OpenEnrollment, grec.AllowPublish, grec.MaturePublish, grec.FounderID, out reason);
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (op == "UPDATE")
|
|
||||||
{
|
|
||||||
m_GroupsService.UpdateGroup(RequestingAgentID, grec.GroupID, grec.Charter, grec.ShowInList, grec.GroupPicture, grec.MembershipFee,
|
|
||||||
grec.OpenEnrollment, grec.AllowPublish, grec.MaturePublish);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (grec.GroupID != UUID.Zero)
|
|
||||||
{
|
|
||||||
grec = m_GroupsService.GetGroupRecord(RequestingAgentID, grec.GroupID);
|
|
||||||
if (grec == null)
|
|
||||||
NullResult(result, "Internal Error");
|
|
||||||
else
|
|
||||||
result["RESULT"] = GroupsDataUtils.GroupRecord(grec);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
NullResult(result, reason);
|
|
||||||
}
|
|
||||||
|
|
||||||
string xmlString = ServerUtils.BuildXmlResponse(result);
|
|
||||||
|
|
||||||
//m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
|
|
||||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] HandleGetGroup(Dictionary<string, object> request)
|
|
||||||
{
|
|
||||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
|
||||||
|
|
||||||
if (!request.ContainsKey("RequestingAgentID"))
|
|
||||||
NullResult(result, "Bad network data");
|
|
||||||
else
|
|
||||||
{
|
|
||||||
string RequestingAgentID = request["RequestingAgentID"].ToString();
|
|
||||||
ExtendedGroupRecord grec = null;
|
|
||||||
if (request.ContainsKey("GroupID"))
|
|
||||||
{
|
|
||||||
UUID groupID = new UUID(request["GroupID"].ToString());
|
|
||||||
grec = m_GroupsService.GetGroupRecord(RequestingAgentID, groupID);
|
|
||||||
}
|
|
||||||
else if (request.ContainsKey("Name"))
|
|
||||||
{
|
|
||||||
string name = request["Name"].ToString();
|
|
||||||
grec = m_GroupsService.GetGroupRecord(RequestingAgentID, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (grec == null)
|
|
||||||
NullResult(result, "Group not found");
|
|
||||||
else
|
|
||||||
result["RESULT"] = GroupsDataUtils.GroupRecord(grec);
|
|
||||||
}
|
|
||||||
|
|
||||||
string xmlString = ServerUtils.BuildXmlResponse(result);
|
|
||||||
|
|
||||||
//m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
|
|
||||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] HandleAddAgentToGroup(Dictionary<string, object> request)
|
|
||||||
{
|
|
||||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
|
||||||
|
|
||||||
if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("AgentID") ||
|
|
||||||
!request.ContainsKey("GroupID") || !request.ContainsKey("RoleID"))
|
|
||||||
NullResult(result, "Bad network data");
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UUID groupID = new UUID(request["GroupID"].ToString());
|
|
||||||
UUID roleID = new UUID(request["RoleID"].ToString());
|
|
||||||
string agentID = request["AgentID"].ToString();
|
|
||||||
string requestingAgentID = request["RequestingAgentID"].ToString();
|
|
||||||
string token = string.Empty;
|
|
||||||
string reason = string.Empty;
|
|
||||||
|
|
||||||
if (request.ContainsKey("AccessToken"))
|
|
||||||
token = request["AccessToken"].ToString();
|
|
||||||
|
|
||||||
if (!m_GroupsService.AddAgentToGroup(requestingAgentID, agentID, groupID, roleID, token, out reason))
|
|
||||||
NullResult(result, reason);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
GroupMembershipData membership = m_GroupsService.GetAgentGroupMembership(requestingAgentID, agentID, groupID);
|
|
||||||
if (membership == null)
|
|
||||||
NullResult(result, "Internal error");
|
|
||||||
else
|
|
||||||
result["RESULT"] = GroupsDataUtils.GroupMembershipData((ExtendedGroupMembershipData)membership);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
string xmlString = ServerUtils.BuildXmlResponse(result);
|
|
||||||
|
|
||||||
//m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
|
|
||||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] HandleRemoveAgentFromGroup(Dictionary<string, object> request)
|
|
||||||
{
|
|
||||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
|
||||||
|
|
||||||
if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("AgentID") || !request.ContainsKey("GroupID"))
|
|
||||||
NullResult(result, "Bad network data");
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UUID groupID = new UUID(request["GroupID"].ToString());
|
|
||||||
string agentID = request["AgentID"].ToString();
|
|
||||||
string requestingAgentID = request["RequestingAgentID"].ToString();
|
|
||||||
|
|
||||||
if (!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);
|
|
||||||
return Util.UTF8NoBomEncoding.GetBytes(ServerUtils.BuildXmlResponse(result));
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] HandleGetMembership(Dictionary<string, object> request)
|
|
||||||
{
|
|
||||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
|
||||||
|
|
||||||
if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("AgentID"))
|
|
||||||
NullResult(result, "Bad network data");
|
|
||||||
else
|
|
||||||
{
|
|
||||||
string agentID = request["AgentID"].ToString();
|
|
||||||
UUID groupID = UUID.Zero;
|
|
||||||
if (request.ContainsKey("GroupID"))
|
|
||||||
groupID = new UUID(request["GroupID"].ToString());
|
|
||||||
string requestingAgentID = request["RequestingAgentID"].ToString();
|
|
||||||
bool all = request.ContainsKey("ALL");
|
|
||||||
|
|
||||||
if (!all)
|
|
||||||
{
|
|
||||||
ExtendedGroupMembershipData membership = null;
|
|
||||||
if (groupID == UUID.Zero)
|
|
||||||
{
|
|
||||||
membership = m_GroupsService.GetAgentActiveMembership(requestingAgentID, agentID);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
membership = m_GroupsService.GetAgentGroupMembership(requestingAgentID, agentID, groupID);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (membership == null)
|
|
||||||
NullResult(result, "No such membership");
|
|
||||||
else
|
|
||||||
result["RESULT"] = GroupsDataUtils.GroupMembershipData(membership);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
List<GroupMembershipData> memberships = m_GroupsService.GetAgentGroupMemberships(requestingAgentID, agentID);
|
|
||||||
if (memberships == null || (memberships != null && memberships.Count == 0))
|
|
||||||
{
|
|
||||||
NullResult(result, "No memberships");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Dictionary<string, object> dict = new Dictionary<string, object>();
|
|
||||||
int i = 0;
|
|
||||||
foreach (GroupMembershipData m in memberships)
|
|
||||||
dict["m-" + i++] = GroupsDataUtils.GroupMembershipData((ExtendedGroupMembershipData)m);
|
|
||||||
|
|
||||||
result["RESULT"] = dict;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
string xmlString = ServerUtils.BuildXmlResponse(result);
|
|
||||||
|
|
||||||
//m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
|
|
||||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] HandleGetGroupMembers(Dictionary<string, object> request)
|
|
||||||
{
|
|
||||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
|
||||||
|
|
||||||
if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("GroupID"))
|
|
||||||
NullResult(result, "Bad network data");
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UUID groupID = new UUID(request["GroupID"].ToString());
|
|
||||||
string requestingAgentID = request["RequestingAgentID"].ToString();
|
|
||||||
|
|
||||||
List<ExtendedGroupMembersData> members = m_GroupsService.GetGroupMembers(requestingAgentID, groupID);
|
|
||||||
if (members == null || (members != null && members.Count == 0))
|
|
||||||
{
|
|
||||||
NullResult(result, "No members");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Dictionary<string, object> dict = new Dictionary<string, object>();
|
|
||||||
int i = 0;
|
|
||||||
foreach (ExtendedGroupMembersData m in members)
|
|
||||||
{
|
|
||||||
dict["m-" + i++] = GroupsDataUtils.GroupMembersData(m);
|
|
||||||
}
|
|
||||||
|
|
||||||
result["RESULT"] = dict;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
string xmlString = ServerUtils.BuildXmlResponse(result);
|
|
||||||
|
|
||||||
//m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
|
|
||||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] HandlePutRole(Dictionary<string, object> request)
|
|
||||||
{
|
|
||||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
|
||||||
|
|
||||||
if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("GroupID") || !request.ContainsKey("RoleID") ||
|
|
||||||
!request.ContainsKey("Name") || !request.ContainsKey("Description") || !request.ContainsKey("Title") ||
|
|
||||||
!request.ContainsKey("Powers") || !request.ContainsKey("OP"))
|
|
||||||
NullResult(result, "Bad network data");
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
string op = request["OP"].ToString();
|
|
||||||
string reason = string.Empty;
|
|
||||||
|
|
||||||
bool success = false;
|
|
||||||
if (op == "ADD")
|
|
||||||
success = m_GroupsService.AddGroupRole(request["RequestingAgentID"].ToString(), new UUID(request["GroupID"].ToString()),
|
|
||||||
new UUID(request["RoleID"].ToString()), request["Name"].ToString(), request["Description"].ToString(),
|
|
||||||
request["Title"].ToString(), UInt64.Parse(request["Powers"].ToString()), out reason);
|
|
||||||
|
|
||||||
else if (op == "UPDATE")
|
|
||||||
success = m_GroupsService.UpdateGroupRole(request["RequestingAgentID"].ToString(), new UUID(request["GroupID"].ToString()),
|
|
||||||
new UUID(request["RoleID"].ToString()), request["Name"].ToString(), request["Description"].ToString(),
|
|
||||||
request["Title"].ToString(), UInt64.Parse(request["Powers"].ToString()));
|
|
||||||
|
|
||||||
result["RESULT"] = success.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
string xmlString = ServerUtils.BuildXmlResponse(result);
|
|
||||||
|
|
||||||
//m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
|
|
||||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] HandleRemoveRole(Dictionary<string, object> request)
|
|
||||||
{
|
|
||||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
|
||||||
|
|
||||||
if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("GroupID") || !request.ContainsKey("RoleID"))
|
|
||||||
NullResult(result, "Bad network data");
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_GroupsService.RemoveGroupRole(request["RequestingAgentID"].ToString(), new UUID(request["GroupID"].ToString()),
|
|
||||||
new UUID(request["RoleID"].ToString()));
|
|
||||||
result["RESULT"] = "true";
|
|
||||||
}
|
|
||||||
|
|
||||||
//m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
|
|
||||||
return Util.UTF8NoBomEncoding.GetBytes(ServerUtils.BuildXmlResponse(result));
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] HandleGetGroupRoles(Dictionary<string, object> request)
|
|
||||||
{
|
|
||||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
|
||||||
|
|
||||||
if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("GroupID"))
|
|
||||||
NullResult(result, "Bad network data");
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UUID groupID = new UUID(request["GroupID"].ToString());
|
|
||||||
string requestingAgentID = request["RequestingAgentID"].ToString();
|
|
||||||
|
|
||||||
List<GroupRolesData> roles = m_GroupsService.GetGroupRoles(requestingAgentID, groupID);
|
|
||||||
if (roles == null || (roles != null && roles.Count == 0))
|
|
||||||
{
|
|
||||||
NullResult(result, "No members");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Dictionary<string, object> dict = new Dictionary<string, object>();
|
|
||||||
int i = 0;
|
|
||||||
foreach (GroupRolesData r in roles)
|
|
||||||
dict["r-" + i++] = GroupsDataUtils.GroupRolesData(r);
|
|
||||||
|
|
||||||
result["RESULT"] = dict;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
string xmlString = ServerUtils.BuildXmlResponse(result);
|
|
||||||
|
|
||||||
//m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
|
|
||||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] HandleGetRoleMembers(Dictionary<string, object> request)
|
|
||||||
{
|
|
||||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
|
||||||
|
|
||||||
if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("GroupID"))
|
|
||||||
NullResult(result, "Bad network data");
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UUID groupID = new UUID(request["GroupID"].ToString());
|
|
||||||
string requestingAgentID = request["RequestingAgentID"].ToString();
|
|
||||||
|
|
||||||
List<ExtendedGroupRoleMembersData> rmembers = m_GroupsService.GetGroupRoleMembers(requestingAgentID, groupID);
|
|
||||||
if (rmembers == null || (rmembers != null && rmembers.Count == 0))
|
|
||||||
{
|
|
||||||
NullResult(result, "No members");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Dictionary<string, object> dict = new Dictionary<string, object>();
|
|
||||||
int i = 0;
|
|
||||||
foreach (ExtendedGroupRoleMembersData rm in rmembers)
|
|
||||||
dict["rm-" + i++] = GroupsDataUtils.GroupRoleMembersData(rm);
|
|
||||||
|
|
||||||
result["RESULT"] = dict;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
string xmlString = ServerUtils.BuildXmlResponse(result);
|
|
||||||
|
|
||||||
//m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
|
|
||||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] HandleAgentRole(Dictionary<string, object> request)
|
|
||||||
{
|
|
||||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
|
||||||
|
|
||||||
if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("GroupID") || !request.ContainsKey("RoleID") ||
|
|
||||||
!request.ContainsKey("AgentID") || !request.ContainsKey("OP"))
|
|
||||||
NullResult(result, "Bad network data");
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
string op = request["OP"].ToString();
|
|
||||||
|
|
||||||
bool success = false;
|
|
||||||
if (op == "ADD")
|
|
||||||
success = m_GroupsService.AddAgentToGroupRole(request["RequestingAgentID"].ToString(), request["AgentID"].ToString(),
|
|
||||||
new UUID(request["GroupID"].ToString()), new UUID(request["RoleID"].ToString()));
|
|
||||||
|
|
||||||
else if (op == "DELETE")
|
|
||||||
success = m_GroupsService.RemoveAgentFromGroupRole(request["RequestingAgentID"].ToString(), request["AgentID"].ToString(),
|
|
||||||
new UUID(request["GroupID"].ToString()), new UUID(request["RoleID"].ToString()));
|
|
||||||
|
|
||||||
result["RESULT"] = success.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
string xmlString = ServerUtils.BuildXmlResponse(result);
|
|
||||||
|
|
||||||
//m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
|
|
||||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] HandleGetAgentRoles(Dictionary<string, object> request)
|
|
||||||
{
|
|
||||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
|
||||||
|
|
||||||
if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("GroupID") || !request.ContainsKey("AgentID"))
|
|
||||||
NullResult(result, "Bad network data");
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UUID groupID = new UUID(request["GroupID"].ToString());
|
|
||||||
string agentID = request["AgentID"].ToString();
|
|
||||||
string requestingAgentID = request["RequestingAgentID"].ToString();
|
|
||||||
|
|
||||||
List<GroupRolesData> roles = m_GroupsService.GetAgentGroupRoles(requestingAgentID, agentID, groupID);
|
|
||||||
if (roles == null || (roles != null && roles.Count == 0))
|
|
||||||
{
|
|
||||||
NullResult(result, "No members");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Dictionary<string, object> dict = new Dictionary<string, object>();
|
|
||||||
int i = 0;
|
|
||||||
foreach (GroupRolesData r in roles)
|
|
||||||
dict["r-" + i++] = GroupsDataUtils.GroupRolesData(r);
|
|
||||||
|
|
||||||
result["RESULT"] = dict;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
string xmlString = ServerUtils.BuildXmlResponse(result);
|
|
||||||
|
|
||||||
//m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
|
|
||||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] HandleSetActive(Dictionary<string, object> request)
|
|
||||||
{
|
|
||||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
|
||||||
|
|
||||||
if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("GroupID") ||
|
|
||||||
!request.ContainsKey("AgentID") || !request.ContainsKey("OP"))
|
|
||||||
{
|
|
||||||
NullResult(result, "Bad network data");
|
|
||||||
string xmlString = ServerUtils.BuildXmlResponse(result);
|
|
||||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
string op = request["OP"].ToString();
|
|
||||||
|
|
||||||
if (op == "GROUP")
|
|
||||||
{
|
|
||||||
ExtendedGroupMembershipData group = m_GroupsService.SetAgentActiveGroup(request["RequestingAgentID"].ToString(),
|
|
||||||
request["AgentID"].ToString(), new UUID(request["GroupID"].ToString()));
|
|
||||||
|
|
||||||
if (group == null)
|
|
||||||
NullResult(result, "Internal error");
|
|
||||||
else
|
|
||||||
result["RESULT"] = GroupsDataUtils.GroupMembershipData(group);
|
|
||||||
|
|
||||||
string xmlString = ServerUtils.BuildXmlResponse(result);
|
|
||||||
|
|
||||||
//m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
|
|
||||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (op == "ROLE" && request.ContainsKey("RoleID"))
|
|
||||||
{
|
|
||||||
m_GroupsService.SetAgentActiveGroupRole(request["RequestingAgentID"].ToString(), request["AgentID"].ToString(),
|
|
||||||
new UUID(request["GroupID"].ToString()), new UUID(request["RoleID"].ToString()));
|
|
||||||
result["RESULT"] = "true";
|
|
||||||
}
|
|
||||||
|
|
||||||
return Util.UTF8NoBomEncoding.GetBytes(ServerUtils.BuildXmlResponse(result));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] HandleUpdateMembership(Dictionary<string, object> request)
|
|
||||||
{
|
|
||||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
|
||||||
|
|
||||||
if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("AgentID") || !request.ContainsKey("GroupID") ||
|
|
||||||
!request.ContainsKey("AcceptNotices") || !request.ContainsKey("ListInProfile"))
|
|
||||||
NullResult(result, "Bad network data");
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_GroupsService.UpdateMembership(request["RequestingAgentID"].ToString(), request["AgentID"].ToString(), new UUID(request["GroupID"].ToString()),
|
|
||||||
bool.Parse(request["AcceptNotices"].ToString()), bool.Parse(request["ListInProfile"].ToString()));
|
|
||||||
|
|
||||||
result["RESULT"] = "true";
|
|
||||||
}
|
|
||||||
|
|
||||||
//m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
|
|
||||||
return Util.UTF8NoBomEncoding.GetBytes(ServerUtils.BuildXmlResponse(result));
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] HandleInvite(Dictionary<string, object> request)
|
|
||||||
{
|
|
||||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
|
||||||
|
|
||||||
if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("InviteID"))
|
|
||||||
{
|
|
||||||
NullResult(result, "Bad network data");
|
|
||||||
string xmlString = ServerUtils.BuildXmlResponse(result);
|
|
||||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
string op = request["OP"].ToString();
|
|
||||||
|
|
||||||
if (op == "ADD" && request.ContainsKey("GroupID") && request.ContainsKey("RoleID") && request.ContainsKey("AgentID"))
|
|
||||||
{
|
|
||||||
bool success = m_GroupsService.AddAgentToGroupInvite(request["RequestingAgentID"].ToString(),
|
|
||||||
new UUID(request["InviteID"].ToString()), new UUID(request["GroupID"].ToString()),
|
|
||||||
new UUID(request["RoleID"].ToString()), request["AgentID"].ToString());
|
|
||||||
|
|
||||||
result["RESULT"] = success.ToString();
|
|
||||||
return Util.UTF8NoBomEncoding.GetBytes(ServerUtils.BuildXmlResponse(result));
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (op == "DELETE")
|
|
||||||
{
|
|
||||||
m_GroupsService.RemoveAgentToGroupInvite(request["RequestingAgentID"].ToString(), new UUID(request["InviteID"].ToString()));
|
|
||||||
result["RESULT"] = "true";
|
|
||||||
return Util.UTF8NoBomEncoding.GetBytes(ServerUtils.BuildXmlResponse(result));
|
|
||||||
}
|
|
||||||
else if (op == "GET")
|
|
||||||
{
|
|
||||||
GroupInviteInfo invite = m_GroupsService.GetAgentToGroupInvite(request["RequestingAgentID"].ToString(),
|
|
||||||
new UUID(request["InviteID"].ToString()));
|
|
||||||
|
|
||||||
if (invite != null)
|
|
||||||
result["RESULT"] = GroupsDataUtils.GroupInviteInfo(invite);
|
|
||||||
else
|
|
||||||
result["RESULT"] = "NULL";
|
|
||||||
|
|
||||||
return Util.UTF8NoBomEncoding.GetBytes(ServerUtils.BuildXmlResponse(result));
|
|
||||||
}
|
|
||||||
|
|
||||||
NullResult(result, "Bad OP in request");
|
|
||||||
return Util.UTF8NoBomEncoding.GetBytes(ServerUtils.BuildXmlResponse(result));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] HandleAddNotice(Dictionary<string, object> request)
|
|
||||||
{
|
|
||||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
|
||||||
|
|
||||||
if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("GroupID") || !request.ContainsKey("NoticeID") ||
|
|
||||||
!request.ContainsKey("FromName") || !request.ContainsKey("Subject") || !request.ContainsKey("Message") ||
|
|
||||||
!request.ContainsKey("HasAttachment"))
|
|
||||||
NullResult(result, "Bad network data");
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
bool hasAtt = bool.Parse(request["HasAttachment"].ToString());
|
|
||||||
byte attType = 0;
|
|
||||||
string attName = string.Empty;
|
|
||||||
string attOwner = string.Empty;
|
|
||||||
UUID attItem = UUID.Zero;
|
|
||||||
if (request.ContainsKey("AttachmentType"))
|
|
||||||
attType = byte.Parse(request["AttachmentType"].ToString());
|
|
||||||
if (request.ContainsKey("AttachmentName"))
|
|
||||||
attName = request["AttachmentName"].ToString();
|
|
||||||
if (request.ContainsKey("AttachmentItemID"))
|
|
||||||
attItem = new UUID(request["AttachmentItemID"].ToString());
|
|
||||||
if (request.ContainsKey("AttachmentOwnerID"))
|
|
||||||
attOwner = request["AttachmentOwnerID"].ToString();
|
|
||||||
|
|
||||||
bool success = m_GroupsService.AddGroupNotice(request["RequestingAgentID"].ToString(), new UUID(request["GroupID"].ToString()),
|
|
||||||
new UUID(request["NoticeID"].ToString()), request["FromName"].ToString(), request["Subject"].ToString(),
|
|
||||||
request["Message"].ToString(), hasAtt, attType, attName, attItem, attOwner);
|
|
||||||
|
|
||||||
result["RESULT"] = success.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
string xmlString = ServerUtils.BuildXmlResponse(result);
|
|
||||||
|
|
||||||
//m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
|
|
||||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] HandleGetNotices(Dictionary<string, object> request)
|
|
||||||
{
|
|
||||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
|
||||||
|
|
||||||
if (!request.ContainsKey("RequestingAgentID"))
|
|
||||||
NullResult(result, "Bad network data");
|
|
||||||
|
|
||||||
else if (request.ContainsKey("NoticeID")) // just one
|
|
||||||
{
|
|
||||||
GroupNoticeInfo notice = m_GroupsService.GetGroupNotice(request["RequestingAgentID"].ToString(), new UUID(request["NoticeID"].ToString()));
|
|
||||||
|
|
||||||
if (notice == null)
|
|
||||||
NullResult(result, "NO such notice");
|
|
||||||
else
|
|
||||||
result["RESULT"] = GroupsDataUtils.GroupNoticeInfo(notice);
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (request.ContainsKey("GroupID")) // all notices for group
|
|
||||||
{
|
|
||||||
List<ExtendedGroupNoticeData> notices = m_GroupsService.GetGroupNotices(request["RequestingAgentID"].ToString(), new UUID(request["GroupID"].ToString()));
|
|
||||||
|
|
||||||
if (notices == null || (notices != null && notices.Count == 0))
|
|
||||||
NullResult(result, "No notices");
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Dictionary<string, object> dict = new Dictionary<string, object>();
|
|
||||||
int i = 0;
|
|
||||||
foreach (ExtendedGroupNoticeData n in notices)
|
|
||||||
dict["n-" + i++] = GroupsDataUtils.GroupNoticeData(n);
|
|
||||||
|
|
||||||
result["RESULT"] = dict;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
NullResult(result, "Bad OP in request");
|
|
||||||
|
|
||||||
string xmlString = ServerUtils.BuildXmlResponse(result);
|
|
||||||
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
|
|
||||||
|
|
||||||
private void NullResult(Dictionary<string, object> result, string reason)
|
|
||||||
{
|
|
||||||
result["RESULT"] = "NULL";
|
|
||||||
result["REASON"] = reason;
|
|
||||||
}
|
|
||||||
|
|
||||||
private byte[] FailureResult()
|
|
||||||
{
|
|
||||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
|
||||||
NullResult(result, "Unknown method");
|
|
||||||
string xmlString = ServerUtils.BuildXmlResponse(result);
|
|
||||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
|
||||||
}
|
|
||||||
|
|
||||||
private byte[] FailureResult(string reason)
|
|
||||||
{
|
|
||||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
|
||||||
NullResult(result, reason);
|
|
||||||
string xmlString = ServerUtils.BuildXmlResponse(result);
|
|
||||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,888 +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.Reflection;
|
|
||||||
using System.Threading;
|
|
||||||
|
|
||||||
using OpenSim.Framework;
|
|
||||||
//using OpenSim.Region.Framework.Interfaces;
|
|
||||||
using OpenSim.Services.Interfaces;
|
|
||||||
|
|
||||||
using OpenMetaverse;
|
|
||||||
|
|
||||||
namespace OpenSim.Groups
|
|
||||||
{
|
|
||||||
public delegate ExtendedGroupRecord GroupRecordDelegate();
|
|
||||||
public delegate GroupMembershipData GroupMembershipDelegate();
|
|
||||||
public delegate List<GroupMembershipData> GroupMembershipListDelegate();
|
|
||||||
public delegate List<ExtendedGroupMembersData> GroupMembersListDelegate();
|
|
||||||
public delegate List<GroupRolesData> GroupRolesListDelegate();
|
|
||||||
public delegate List<ExtendedGroupRoleMembersData> RoleMembersListDelegate();
|
|
||||||
public delegate GroupNoticeInfo NoticeDelegate();
|
|
||||||
public delegate List<ExtendedGroupNoticeData> NoticeListDelegate();
|
|
||||||
public delegate void VoidDelegate();
|
|
||||||
public delegate bool BooleanDelegate();
|
|
||||||
|
|
||||||
public class RemoteConnectorCacheWrapper
|
|
||||||
{
|
|
||||||
private ForeignImporter m_ForeignImporter;
|
|
||||||
|
|
||||||
private Dictionary<string, bool> m_ActiveRequests = new Dictionary<string, bool>();
|
|
||||||
private const int GROUPS_CACHE_TIMEOUT = 1 * 60; // 1 minutes
|
|
||||||
|
|
||||||
// This all important cache cahces objects of different types:
|
|
||||||
// group-<GroupID> or group-<Name> => ExtendedGroupRecord
|
|
||||||
// active-<AgentID> => GroupMembershipData
|
|
||||||
// membership-<AgentID>-<GroupID> => GroupMembershipData
|
|
||||||
// memberships-<AgentID> => List<GroupMembershipData>
|
|
||||||
// members-<RequestingAgentID>-<GroupID> => List<ExtendedGroupMembersData>
|
|
||||||
// role-<RoleID> => GroupRolesData
|
|
||||||
// roles-<GroupID> => List<GroupRolesData> ; all roles in the group
|
|
||||||
// roles-<GroupID>-<AgentID> => List<GroupRolesData> ; roles that the agent has
|
|
||||||
// rolemembers-<RequestingAgentID>-<GroupID> => List<ExtendedGroupRoleMembersData>
|
|
||||||
// notice-<noticeID> => GroupNoticeInfo
|
|
||||||
// notices-<GroupID> => List<ExtendedGroupNoticeData>
|
|
||||||
private ExpiringCache<string, object> m_Cache = new ExpiringCache<string, object>();
|
|
||||||
|
|
||||||
public RemoteConnectorCacheWrapper(IUserManagement uman)
|
|
||||||
{
|
|
||||||
m_ForeignImporter = new ForeignImporter(uman);
|
|
||||||
}
|
|
||||||
|
|
||||||
public UUID CreateGroup(UUID RequestingAgentID, GroupRecordDelegate d)
|
|
||||||
{
|
|
||||||
//m_log.DebugFormat("[Groups.RemoteConnector]: Creating group {0}", name);
|
|
||||||
//reason = string.Empty;
|
|
||||||
|
|
||||||
//ExtendedGroupRecord group = m_GroupsService.CreateGroup(RequestingAgentID.ToString(), name, charter, showInList, insigniaID,
|
|
||||||
// membershipFee, openEnrollment, allowPublish, maturePublish, founderID, out reason);
|
|
||||||
ExtendedGroupRecord group = d();
|
|
||||||
|
|
||||||
if (group == null)
|
|
||||||
return UUID.Zero;
|
|
||||||
|
|
||||||
if (group.GroupID != UUID.Zero)
|
|
||||||
lock (m_Cache)
|
|
||||||
{
|
|
||||||
m_Cache.Add("group-" + group.GroupID.ToString(), group, GROUPS_CACHE_TIMEOUT);
|
|
||||||
if (m_Cache.Contains("memberships-" + RequestingAgentID.ToString()))
|
|
||||||
m_Cache.Remove("memberships-" + RequestingAgentID.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
return group.GroupID;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool UpdateGroup(UUID groupID, GroupRecordDelegate d)
|
|
||||||
{
|
|
||||||
//reason = string.Empty;
|
|
||||||
//ExtendedGroupRecord group = m_GroupsService.UpdateGroup(RequestingAgentID, groupID, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish);
|
|
||||||
ExtendedGroupRecord group = d();
|
|
||||||
|
|
||||||
if (group != null && group.GroupID != UUID.Zero)
|
|
||||||
lock (m_Cache)
|
|
||||||
m_Cache.AddOrUpdate("group-" + group.GroupID.ToString(), group, GROUPS_CACHE_TIMEOUT);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ExtendedGroupRecord GetGroupRecord(string RequestingAgentID, UUID GroupID, string GroupName, GroupRecordDelegate d)
|
|
||||||
{
|
|
||||||
//if (GroupID == UUID.Zero && (GroupName == null || GroupName != null && GroupName == string.Empty))
|
|
||||||
// return null;
|
|
||||||
|
|
||||||
object group = null;
|
|
||||||
bool firstCall = false;
|
|
||||||
string cacheKey = "group-";
|
|
||||||
if (GroupID != UUID.Zero)
|
|
||||||
cacheKey += GroupID.ToString();
|
|
||||||
else
|
|
||||||
cacheKey += GroupName;
|
|
||||||
|
|
||||||
//m_log.DebugFormat("[XXX]: GetGroupRecord {0}", cacheKey);
|
|
||||||
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
lock (m_Cache)
|
|
||||||
{
|
|
||||||
if (m_Cache.TryGetValue(cacheKey, out group))
|
|
||||||
{
|
|
||||||
//m_log.DebugFormat("[XXX]: GetGroupRecord {0} cached!", cacheKey);
|
|
||||||
return (ExtendedGroupRecord)group;
|
|
||||||
}
|
|
||||||
|
|
||||||
// not cached
|
|
||||||
if (!m_ActiveRequests.ContainsKey(cacheKey))
|
|
||||||
{
|
|
||||||
m_ActiveRequests.Add(cacheKey, true);
|
|
||||||
firstCall = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (firstCall)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
//group = m_GroupsService.GetGroupRecord(RequestingAgentID, GroupID, GroupName);
|
|
||||||
group = d();
|
|
||||||
|
|
||||||
lock (m_Cache)
|
|
||||||
{
|
|
||||||
m_Cache.AddOrUpdate(cacheKey, group, GROUPS_CACHE_TIMEOUT);
|
|
||||||
return (ExtendedGroupRecord)group;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
m_ActiveRequests.Remove(cacheKey);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Thread.Sleep(50);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool AddAgentToGroup(string RequestingAgentID, string AgentID, UUID GroupID, GroupMembershipDelegate d)
|
|
||||||
{
|
|
||||||
GroupMembershipData membership = d();
|
|
||||||
if (membership == null)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
lock (m_Cache)
|
|
||||||
{
|
|
||||||
// first, remove everything! add a user is a heavy-duty op
|
|
||||||
m_Cache.Clear();
|
|
||||||
|
|
||||||
m_Cache.AddOrUpdate("active-" + AgentID.ToString(), membership, GROUPS_CACHE_TIMEOUT);
|
|
||||||
m_Cache.AddOrUpdate("membership-" + AgentID.ToString() + "-" + GroupID.ToString(), membership, GROUPS_CACHE_TIMEOUT);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RemoveAgentFromGroup(string RequestingAgentID, string AgentID, UUID GroupID, VoidDelegate d)
|
|
||||||
{
|
|
||||||
d();
|
|
||||||
|
|
||||||
lock (m_Cache)
|
|
||||||
{
|
|
||||||
string cacheKey = "active-" + AgentID.ToString();
|
|
||||||
if (m_Cache.Contains(cacheKey))
|
|
||||||
m_Cache.Remove(cacheKey);
|
|
||||||
|
|
||||||
cacheKey = "memberships-" + AgentID.ToString();
|
|
||||||
if (m_Cache.Contains(cacheKey))
|
|
||||||
m_Cache.Remove(cacheKey);
|
|
||||||
|
|
||||||
cacheKey = "membership-" + AgentID.ToString() + "-" + GroupID.ToString();
|
|
||||||
if (m_Cache.Contains(cacheKey))
|
|
||||||
m_Cache.Remove(cacheKey);
|
|
||||||
|
|
||||||
cacheKey = "members-" + RequestingAgentID.ToString() + "-" + GroupID.ToString();
|
|
||||||
if (m_Cache.Contains(cacheKey))
|
|
||||||
m_Cache.Remove(cacheKey);
|
|
||||||
|
|
||||||
cacheKey = "roles-" + "-" + GroupID.ToString() + "-" + AgentID.ToString();
|
|
||||||
if (m_Cache.Contains(cacheKey))
|
|
||||||
m_Cache.Remove(cacheKey);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetAgentActiveGroup(string AgentID, GroupMembershipDelegate d)
|
|
||||||
{
|
|
||||||
GroupMembershipData activeGroup = d();
|
|
||||||
string cacheKey = "active-" + AgentID.ToString();
|
|
||||||
lock (m_Cache)
|
|
||||||
if (m_Cache.Contains(cacheKey))
|
|
||||||
m_Cache.AddOrUpdate(cacheKey, activeGroup, GROUPS_CACHE_TIMEOUT);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ExtendedGroupMembershipData GetAgentActiveMembership(string AgentID, GroupMembershipDelegate d)
|
|
||||||
{
|
|
||||||
object membership = null;
|
|
||||||
bool firstCall = false;
|
|
||||||
string cacheKey = "active-" + AgentID.ToString();
|
|
||||||
|
|
||||||
//m_log.DebugFormat("[XXX]: GetAgentActiveMembership {0}", cacheKey);
|
|
||||||
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
lock (m_Cache)
|
|
||||||
{
|
|
||||||
if (m_Cache.TryGetValue(cacheKey, out membership))
|
|
||||||
{
|
|
||||||
//m_log.DebugFormat("[XXX]: GetAgentActiveMembership {0} cached!", cacheKey);
|
|
||||||
return (ExtendedGroupMembershipData)membership;
|
|
||||||
}
|
|
||||||
|
|
||||||
// not cached
|
|
||||||
if (!m_ActiveRequests.ContainsKey(cacheKey))
|
|
||||||
{
|
|
||||||
m_ActiveRequests.Add(cacheKey, true);
|
|
||||||
firstCall = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (firstCall)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
membership = d();
|
|
||||||
|
|
||||||
lock (m_Cache)
|
|
||||||
{
|
|
||||||
m_Cache.AddOrUpdate(cacheKey, membership, GROUPS_CACHE_TIMEOUT);
|
|
||||||
return (ExtendedGroupMembershipData)membership;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
m_ActiveRequests.Remove(cacheKey);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Thread.Sleep(50);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public ExtendedGroupMembershipData GetAgentGroupMembership(string AgentID, UUID GroupID, GroupMembershipDelegate d)
|
|
||||||
{
|
|
||||||
object membership = null;
|
|
||||||
bool firstCall = false;
|
|
||||||
string cacheKey = "membership-" + AgentID.ToString() + "-" + GroupID.ToString();
|
|
||||||
|
|
||||||
//m_log.DebugFormat("[XXX]: GetAgentGroupMembership {0}", cacheKey);
|
|
||||||
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
lock (m_Cache)
|
|
||||||
{
|
|
||||||
if (m_Cache.TryGetValue(cacheKey, out membership))
|
|
||||||
{
|
|
||||||
//m_log.DebugFormat("[XXX]: GetAgentGroupMembership {0}", cacheKey);
|
|
||||||
return (ExtendedGroupMembershipData)membership;
|
|
||||||
}
|
|
||||||
|
|
||||||
// not cached
|
|
||||||
if (!m_ActiveRequests.ContainsKey(cacheKey))
|
|
||||||
{
|
|
||||||
m_ActiveRequests.Add(cacheKey, true);
|
|
||||||
firstCall = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (firstCall)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
membership = d();
|
|
||||||
lock (m_Cache)
|
|
||||||
{
|
|
||||||
m_Cache.AddOrUpdate(cacheKey, membership, GROUPS_CACHE_TIMEOUT);
|
|
||||||
return (ExtendedGroupMembershipData)membership;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
m_ActiveRequests.Remove(cacheKey);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Thread.Sleep(50);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<GroupMembershipData> GetAgentGroupMemberships(string AgentID, GroupMembershipListDelegate d)
|
|
||||||
{
|
|
||||||
object memberships = null;
|
|
||||||
bool firstCall = false;
|
|
||||||
string cacheKey = "memberships-" + AgentID.ToString();
|
|
||||||
|
|
||||||
//m_log.DebugFormat("[XXX]: GetAgentGroupMemberships {0}", cacheKey);
|
|
||||||
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
lock (m_Cache)
|
|
||||||
{
|
|
||||||
if (m_Cache.TryGetValue(cacheKey, out memberships))
|
|
||||||
{
|
|
||||||
//m_log.DebugFormat("[XXX]: GetAgentGroupMemberships {0} cached!", cacheKey);
|
|
||||||
return (List<GroupMembershipData>)memberships;
|
|
||||||
}
|
|
||||||
|
|
||||||
// not cached
|
|
||||||
if (!m_ActiveRequests.ContainsKey(cacheKey))
|
|
||||||
{
|
|
||||||
m_ActiveRequests.Add(cacheKey, true);
|
|
||||||
firstCall = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (firstCall)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
memberships = d();
|
|
||||||
lock (m_Cache)
|
|
||||||
{
|
|
||||||
m_Cache.AddOrUpdate(cacheKey, memberships, GROUPS_CACHE_TIMEOUT);
|
|
||||||
return (List<GroupMembershipData>)memberships;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
m_ActiveRequests.Remove(cacheKey);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Thread.Sleep(50);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<GroupMembersData> GetGroupMembers(string RequestingAgentID, UUID GroupID, GroupMembersListDelegate d)
|
|
||||||
{
|
|
||||||
object members = null;
|
|
||||||
bool firstCall = false;
|
|
||||||
// we need to key in also on the requester, because different ppl have different view privileges
|
|
||||||
string cacheKey = "members-" + RequestingAgentID.ToString() + "-" + GroupID.ToString();
|
|
||||||
|
|
||||||
//m_log.DebugFormat("[XXX]: GetGroupMembers {0}", cacheKey);
|
|
||||||
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
lock (m_Cache)
|
|
||||||
{
|
|
||||||
if (m_Cache.TryGetValue(cacheKey, out members))
|
|
||||||
{
|
|
||||||
List<ExtendedGroupMembersData> xx = (List<ExtendedGroupMembersData>)members;
|
|
||||||
return xx.ConvertAll<GroupMembersData>(new Converter<ExtendedGroupMembersData, GroupMembersData>(m_ForeignImporter.ConvertGroupMembersData));
|
|
||||||
}
|
|
||||||
|
|
||||||
// not cached
|
|
||||||
if (!m_ActiveRequests.ContainsKey(cacheKey))
|
|
||||||
{
|
|
||||||
m_ActiveRequests.Add(cacheKey, true);
|
|
||||||
firstCall = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (firstCall)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
List<ExtendedGroupMembersData> _members = d();
|
|
||||||
|
|
||||||
if (_members != null && _members.Count > 0)
|
|
||||||
members = _members.ConvertAll<GroupMembersData>(new Converter<ExtendedGroupMembersData, GroupMembersData>(m_ForeignImporter.ConvertGroupMembersData));
|
|
||||||
else
|
|
||||||
members = new List<GroupMembersData>();
|
|
||||||
|
|
||||||
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_ActiveRequests.Remove(cacheKey);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Thread.Sleep(50);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool AddGroupRole(UUID groupID, UUID roleID, string description, string name, ulong powers, string title, BooleanDelegate d)
|
|
||||||
{
|
|
||||||
if (d())
|
|
||||||
{
|
|
||||||
GroupRolesData role = new GroupRolesData();
|
|
||||||
role.Description = description;
|
|
||||||
role.Members = 0;
|
|
||||||
role.Name = name;
|
|
||||||
role.Powers = powers;
|
|
||||||
role.RoleID = roleID;
|
|
||||||
role.Title = title;
|
|
||||||
|
|
||||||
lock (m_Cache)
|
|
||||||
{
|
|
||||||
m_Cache.AddOrUpdate("role-" + roleID.ToString(), role, GROUPS_CACHE_TIMEOUT);
|
|
||||||
|
|
||||||
// also remove this list
|
|
||||||
if (m_Cache.Contains("roles-" + groupID.ToString()))
|
|
||||||
m_Cache.Remove("roles-" + groupID.ToString());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool UpdateGroupRole(UUID groupID, UUID roleID, string name, string description, string title, ulong powers, BooleanDelegate d)
|
|
||||||
{
|
|
||||||
if (d())
|
|
||||||
{
|
|
||||||
object role;
|
|
||||||
lock (m_Cache)
|
|
||||||
if (m_Cache.TryGetValue("role-" + roleID.ToString(), out role))
|
|
||||||
{
|
|
||||||
GroupRolesData r = (GroupRolesData)role;
|
|
||||||
r.Description = description;
|
|
||||||
r.Name = name;
|
|
||||||
r.Powers = powers;
|
|
||||||
r.Title = title;
|
|
||||||
|
|
||||||
m_Cache.Update("role-" + roleID.ToString(), r, GROUPS_CACHE_TIMEOUT);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
lock (m_Cache)
|
|
||||||
{
|
|
||||||
if (m_Cache.Contains("role-" + roleID.ToString()))
|
|
||||||
m_Cache.Remove("role-" + roleID.ToString());
|
|
||||||
|
|
||||||
// also remove these lists, because they will have an outdated role
|
|
||||||
if (m_Cache.Contains("roles-" + groupID.ToString()))
|
|
||||||
m_Cache.Remove("roles-" + groupID.ToString());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RemoveGroupRole(string RequestingAgentID, UUID groupID, UUID roleID, VoidDelegate d)
|
|
||||||
{
|
|
||||||
d();
|
|
||||||
|
|
||||||
lock (m_Cache)
|
|
||||||
{
|
|
||||||
if (m_Cache.Contains("role-" + roleID.ToString()))
|
|
||||||
m_Cache.Remove("role-" + roleID.ToString());
|
|
||||||
|
|
||||||
// also remove the list, because it will have an removed role
|
|
||||||
if (m_Cache.Contains("roles-" + groupID.ToString()))
|
|
||||||
m_Cache.Remove("roles-" + groupID.ToString());
|
|
||||||
|
|
||||||
if (m_Cache.Contains("roles-" + groupID.ToString() + "-" + RequestingAgentID.ToString()))
|
|
||||||
m_Cache.Remove("roles-" + groupID.ToString() + "-" + RequestingAgentID.ToString());
|
|
||||||
|
|
||||||
if (m_Cache.Contains("rolemembers-" + RequestingAgentID.ToString() + "-" + groupID.ToString()))
|
|
||||||
m_Cache.Remove("rolemembers-" + RequestingAgentID.ToString() + "-" + groupID.ToString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<GroupRolesData> GetGroupRoles(string RequestingAgentID, UUID GroupID, GroupRolesListDelegate d)
|
|
||||||
{
|
|
||||||
object roles = null;
|
|
||||||
bool firstCall = false;
|
|
||||||
string cacheKey = "roles-" + GroupID.ToString();
|
|
||||||
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
lock (m_Cache)
|
|
||||||
{
|
|
||||||
if (m_Cache.TryGetValue(cacheKey, out roles))
|
|
||||||
return (List<GroupRolesData>)roles;
|
|
||||||
|
|
||||||
// not cached
|
|
||||||
if (!m_ActiveRequests.ContainsKey(cacheKey))
|
|
||||||
{
|
|
||||||
m_ActiveRequests.Add(cacheKey, true);
|
|
||||||
firstCall = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (firstCall)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
roles = d();
|
|
||||||
if (roles != null)
|
|
||||||
{
|
|
||||||
lock (m_Cache)
|
|
||||||
{
|
|
||||||
m_Cache.AddOrUpdate(cacheKey, roles, GROUPS_CACHE_TIMEOUT);
|
|
||||||
return (List<GroupRolesData>)roles;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
m_ActiveRequests.Remove(cacheKey);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Thread.Sleep(50);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<GroupRoleMembersData> GetGroupRoleMembers(string RequestingAgentID, UUID GroupID, RoleMembersListDelegate d)
|
|
||||||
{
|
|
||||||
object rmembers = null;
|
|
||||||
bool firstCall = false;
|
|
||||||
// we need to key in also on the requester, because different ppl have different view privileges
|
|
||||||
string cacheKey = "rolemembers-" + RequestingAgentID.ToString() + "-" + GroupID.ToString();
|
|
||||||
|
|
||||||
//m_log.DebugFormat("[XXX]: GetGroupRoleMembers {0}", cacheKey);
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
lock (m_Cache)
|
|
||||||
{
|
|
||||||
if (m_Cache.TryGetValue(cacheKey, out rmembers))
|
|
||||||
{
|
|
||||||
List<ExtendedGroupRoleMembersData> xx = (List<ExtendedGroupRoleMembersData>)rmembers;
|
|
||||||
return xx.ConvertAll<GroupRoleMembersData>(m_ForeignImporter.ConvertGroupRoleMembersData);
|
|
||||||
}
|
|
||||||
|
|
||||||
// not cached
|
|
||||||
if (!m_ActiveRequests.ContainsKey(cacheKey))
|
|
||||||
{
|
|
||||||
m_ActiveRequests.Add(cacheKey, true);
|
|
||||||
firstCall = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (firstCall)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
List<ExtendedGroupRoleMembersData> _rmembers = d();
|
|
||||||
|
|
||||||
if (_rmembers != null && _rmembers.Count > 0)
|
|
||||||
rmembers = _rmembers.ConvertAll<GroupRoleMembersData>(new Converter<ExtendedGroupRoleMembersData, GroupRoleMembersData>(m_ForeignImporter.ConvertGroupRoleMembersData));
|
|
||||||
else
|
|
||||||
rmembers = new List<GroupRoleMembersData>();
|
|
||||||
|
|
||||||
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
|
|
||||||
{
|
|
||||||
m_ActiveRequests.Remove(cacheKey);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Thread.Sleep(50);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void AddAgentToGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID, BooleanDelegate d)
|
|
||||||
{
|
|
||||||
if (d())
|
|
||||||
{
|
|
||||||
lock (m_Cache)
|
|
||||||
{
|
|
||||||
// update the cached role
|
|
||||||
string cacheKey = "role-" + RoleID.ToString();
|
|
||||||
object obj;
|
|
||||||
if (m_Cache.TryGetValue(cacheKey, out obj))
|
|
||||||
{
|
|
||||||
GroupRolesData r = (GroupRolesData)obj;
|
|
||||||
r.Members++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// add this agent to the list of role members
|
|
||||||
cacheKey = "rolemembers-" + RequestingAgentID.ToString() + "-" + GroupID.ToString();
|
|
||||||
if (m_Cache.TryGetValue(cacheKey, out obj))
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// This may throw an exception, in which case the agentID is not a UUID but a full ID
|
|
||||||
// In that case, let's just remove the whoe things from the cache
|
|
||||||
UUID id = new UUID(AgentID);
|
|
||||||
List<ExtendedGroupRoleMembersData> xx = (List<ExtendedGroupRoleMembersData>)obj;
|
|
||||||
List<GroupRoleMembersData> rmlist = xx.ConvertAll<GroupRoleMembersData>(m_ForeignImporter.ConvertGroupRoleMembersData);
|
|
||||||
GroupRoleMembersData rm = new GroupRoleMembersData();
|
|
||||||
rm.MemberID = id;
|
|
||||||
rm.RoleID = RoleID;
|
|
||||||
rmlist.Add(rm);
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
m_Cache.Remove(cacheKey);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove the cached info about this agent's roles
|
|
||||||
// because we don't have enough local info about the new role
|
|
||||||
cacheKey = "roles-" + GroupID.ToString() + "-" + AgentID.ToString();
|
|
||||||
if (m_Cache.Contains(cacheKey))
|
|
||||||
m_Cache.Remove(cacheKey);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RemoveAgentFromGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID, BooleanDelegate d)
|
|
||||||
{
|
|
||||||
if (d())
|
|
||||||
{
|
|
||||||
lock (m_Cache)
|
|
||||||
{
|
|
||||||
// update the cached role
|
|
||||||
string cacheKey = "role-" + RoleID.ToString();
|
|
||||||
object obj;
|
|
||||||
if (m_Cache.TryGetValue(cacheKey, out obj))
|
|
||||||
{
|
|
||||||
GroupRolesData r = (GroupRolesData)obj;
|
|
||||||
r.Members--;
|
|
||||||
}
|
|
||||||
|
|
||||||
cacheKey = "roles-" + GroupID.ToString() + "-" + AgentID.ToString();
|
|
||||||
if (m_Cache.Contains(cacheKey))
|
|
||||||
m_Cache.Remove(cacheKey);
|
|
||||||
|
|
||||||
cacheKey = "rolemembers-" + RequestingAgentID.ToString() + "-" + GroupID.ToString();
|
|
||||||
if (m_Cache.Contains(cacheKey))
|
|
||||||
m_Cache.Remove(cacheKey);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<GroupRolesData> GetAgentGroupRoles(string RequestingAgentID, string AgentID, UUID GroupID, GroupRolesListDelegate d)
|
|
||||||
{
|
|
||||||
object roles = null;
|
|
||||||
bool firstCall = false;
|
|
||||||
string cacheKey = "roles-" + GroupID.ToString() + "-" + AgentID.ToString();
|
|
||||||
|
|
||||||
//m_log.DebugFormat("[XXX]: GetAgentGroupRoles {0}", cacheKey);
|
|
||||||
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
lock (m_Cache)
|
|
||||||
{
|
|
||||||
if (m_Cache.TryGetValue(cacheKey, out roles))
|
|
||||||
{
|
|
||||||
//m_log.DebugFormat("[XXX]: GetAgentGroupRoles {0} cached!", cacheKey);
|
|
||||||
return (List<GroupRolesData>)roles;
|
|
||||||
}
|
|
||||||
|
|
||||||
// not cached
|
|
||||||
if (!m_ActiveRequests.ContainsKey(cacheKey))
|
|
||||||
{
|
|
||||||
m_ActiveRequests.Add(cacheKey, true);
|
|
||||||
firstCall = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (firstCall)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
roles = d();
|
|
||||||
lock (m_Cache)
|
|
||||||
{
|
|
||||||
m_Cache.AddOrUpdate(cacheKey, roles, GROUPS_CACHE_TIMEOUT);
|
|
||||||
m_ActiveRequests.Remove(cacheKey);
|
|
||||||
return (List<GroupRolesData>)roles;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
m_ActiveRequests.Remove(cacheKey);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Thread.Sleep(50);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetAgentActiveGroupRole(string AgentID, UUID GroupID, VoidDelegate d)
|
|
||||||
{
|
|
||||||
d();
|
|
||||||
|
|
||||||
lock (m_Cache)
|
|
||||||
{
|
|
||||||
// Invalidate cached info, because it has ActiveRoleID and Powers
|
|
||||||
string cacheKey = "membership-" + AgentID.ToString() + "-" + GroupID.ToString();
|
|
||||||
if (m_Cache.Contains(cacheKey))
|
|
||||||
m_Cache.Remove(cacheKey);
|
|
||||||
|
|
||||||
cacheKey = "memberships-" + AgentID.ToString();
|
|
||||||
if (m_Cache.Contains(cacheKey))
|
|
||||||
m_Cache.Remove(cacheKey);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UpdateMembership(string AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile, VoidDelegate d)
|
|
||||||
{
|
|
||||||
d();
|
|
||||||
|
|
||||||
lock (m_Cache)
|
|
||||||
{
|
|
||||||
string cacheKey = "membership-" + AgentID.ToString() + "-" + GroupID.ToString();
|
|
||||||
if (m_Cache.Contains(cacheKey))
|
|
||||||
m_Cache.Remove(cacheKey);
|
|
||||||
|
|
||||||
cacheKey = "memberships-" + AgentID.ToString();
|
|
||||||
if (m_Cache.Contains(cacheKey))
|
|
||||||
m_Cache.Remove(cacheKey);
|
|
||||||
|
|
||||||
cacheKey = "active-" + AgentID.ToString();
|
|
||||||
object m = null;
|
|
||||||
if (m_Cache.TryGetValue(cacheKey, out m))
|
|
||||||
{
|
|
||||||
GroupMembershipData membership = (GroupMembershipData)m;
|
|
||||||
membership.ListInProfile = ListInProfile;
|
|
||||||
membership.AcceptNotices = AcceptNotices;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool AddGroupNotice(UUID groupID, UUID noticeID, GroupNoticeInfo notice, BooleanDelegate d)
|
|
||||||
{
|
|
||||||
if (d())
|
|
||||||
{
|
|
||||||
lock (m_Cache)
|
|
||||||
{
|
|
||||||
m_Cache.AddOrUpdate("notice-" + noticeID.ToString(), notice, GROUPS_CACHE_TIMEOUT);
|
|
||||||
string cacheKey = "notices-" + groupID.ToString();
|
|
||||||
if (m_Cache.Contains(cacheKey))
|
|
||||||
m_Cache.Remove(cacheKey);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public GroupNoticeInfo GetGroupNotice(UUID noticeID, NoticeDelegate d)
|
|
||||||
{
|
|
||||||
object notice = null;
|
|
||||||
bool firstCall = false;
|
|
||||||
string cacheKey = "notice-" + noticeID.ToString();
|
|
||||||
|
|
||||||
//m_log.DebugFormat("[XXX]: GetAgentGroupRoles {0}", cacheKey);
|
|
||||||
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
lock (m_Cache)
|
|
||||||
{
|
|
||||||
if (m_Cache.TryGetValue(cacheKey, out notice))
|
|
||||||
{
|
|
||||||
return (GroupNoticeInfo)notice;
|
|
||||||
}
|
|
||||||
|
|
||||||
// not cached
|
|
||||||
if (!m_ActiveRequests.ContainsKey(cacheKey))
|
|
||||||
{
|
|
||||||
m_ActiveRequests.Add(cacheKey, true);
|
|
||||||
firstCall = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (firstCall)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
GroupNoticeInfo _notice = d();
|
|
||||||
|
|
||||||
lock (m_Cache)
|
|
||||||
{
|
|
||||||
m_Cache.AddOrUpdate(cacheKey, _notice, GROUPS_CACHE_TIMEOUT);
|
|
||||||
return _notice;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
m_ActiveRequests.Remove(cacheKey);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Thread.Sleep(50);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<ExtendedGroupNoticeData> GetGroupNotices(UUID GroupID, NoticeListDelegate d)
|
|
||||||
{
|
|
||||||
object notices = null;
|
|
||||||
bool firstCall = false;
|
|
||||||
string cacheKey = "notices-" + GroupID.ToString();
|
|
||||||
|
|
||||||
//m_log.DebugFormat("[XXX]: GetGroupNotices {0}", cacheKey);
|
|
||||||
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
lock (m_Cache)
|
|
||||||
{
|
|
||||||
if (m_Cache.TryGetValue(cacheKey, out notices))
|
|
||||||
{
|
|
||||||
//m_log.DebugFormat("[XXX]: GetGroupNotices {0} cached!", cacheKey);
|
|
||||||
return (List<ExtendedGroupNoticeData>)notices;
|
|
||||||
}
|
|
||||||
|
|
||||||
// not cached
|
|
||||||
if (!m_ActiveRequests.ContainsKey(cacheKey))
|
|
||||||
{
|
|
||||||
m_ActiveRequests.Add(cacheKey, true);
|
|
||||||
firstCall = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (firstCall)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
notices = d();
|
|
||||||
|
|
||||||
lock (m_Cache)
|
|
||||||
{
|
|
||||||
m_Cache.AddOrUpdate(cacheKey, notices, GROUPS_CACHE_TIMEOUT);
|
|
||||||
return (List<ExtendedGroupNoticeData>)notices;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
m_ActiveRequests.Remove(cacheKey);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Thread.Sleep(50);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,101 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
* * Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* * Neither the name of the OpenSimulator Project nor the
|
|
||||||
* names of its contributors may be used to endorse or promote products
|
|
||||||
* derived from this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
|
||||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Reflection;
|
|
||||||
using Nini.Config;
|
|
||||||
using OpenSim.Framework;
|
|
||||||
using OpenSim.Data;
|
|
||||||
using OpenSim.Services.Interfaces;
|
|
||||||
using OpenSim.Services.Base;
|
|
||||||
|
|
||||||
namespace OpenSim.Groups
|
|
||||||
{
|
|
||||||
public class GroupsServiceBase : ServiceBase
|
|
||||||
{
|
|
||||||
protected IGroupsData m_Database = null;
|
|
||||||
protected IGridUserData m_GridUserService = null;
|
|
||||||
|
|
||||||
public GroupsServiceBase(IConfigSource config, string cName)
|
|
||||||
: base(config)
|
|
||||||
{
|
|
||||||
string dllName = String.Empty;
|
|
||||||
string connString = String.Empty;
|
|
||||||
string realm = "os_groups";
|
|
||||||
string usersRealm = "GridUser";
|
|
||||||
string configName = (cName == string.Empty) ? "Groups" : cName;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Try reading the [DatabaseService] section, if it exists
|
|
||||||
//
|
|
||||||
IConfig dbConfig = config.Configs["DatabaseService"];
|
|
||||||
if (dbConfig != null)
|
|
||||||
{
|
|
||||||
if (dllName == String.Empty)
|
|
||||||
dllName = dbConfig.GetString("StorageProvider", String.Empty);
|
|
||||||
if (connString == String.Empty)
|
|
||||||
connString = dbConfig.GetString("ConnectionString", String.Empty);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// [Groups] section overrides [DatabaseService], if it exists
|
|
||||||
//
|
|
||||||
IConfig groupsConfig = config.Configs[configName];
|
|
||||||
if (groupsConfig != null)
|
|
||||||
{
|
|
||||||
dllName = groupsConfig.GetString("StorageProvider", dllName);
|
|
||||||
connString = groupsConfig.GetString("ConnectionString", connString);
|
|
||||||
realm = groupsConfig.GetString("Realm", realm);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// We tried, but this doesn't exist. We can't proceed.
|
|
||||||
//
|
|
||||||
if (dllName.Equals(String.Empty))
|
|
||||||
throw new Exception("No StorageProvider configured");
|
|
||||||
|
|
||||||
m_Database = LoadPlugin<IGroupsData>(dllName, new Object[] { connString, realm });
|
|
||||||
if (m_Database == null)
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,361 +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.Reflection;
|
|
||||||
using System.Timers;
|
|
||||||
using log4net;
|
|
||||||
using Nini.Config;
|
|
||||||
|
|
||||||
using OpenMetaverse;
|
|
||||||
using OpenSim.Data;
|
|
||||||
using OpenSim.Framework;
|
|
||||||
using OpenSim.Services.Interfaces;
|
|
||||||
|
|
||||||
namespace OpenSim.Groups
|
|
||||||
{
|
|
||||||
public class HGGroupsService : GroupsService
|
|
||||||
{
|
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
|
||||||
|
|
||||||
private IOfflineIMService m_OfflineIM;
|
|
||||||
private IUserAccountService m_UserAccounts;
|
|
||||||
private string m_HomeURI;
|
|
||||||
|
|
||||||
public HGGroupsService(IConfigSource config, IOfflineIMService im, IUserAccountService users, string homeURI)
|
|
||||||
: base(config, string.Empty)
|
|
||||||
{
|
|
||||||
m_OfflineIM = im;
|
|
||||||
m_UserAccounts = users;
|
|
||||||
m_HomeURI = homeURI;
|
|
||||||
if (!m_HomeURI.EndsWith("/"))
|
|
||||||
m_HomeURI += "/";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#region HG specific operations
|
|
||||||
|
|
||||||
public bool CreateGroupProxy(string RequestingAgentID, string agentID, string accessToken, UUID groupID, string serviceLocation, string name, out string reason)
|
|
||||||
{
|
|
||||||
reason = string.Empty;
|
|
||||||
Uri uri = null;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
uri = new Uri(serviceLocation);
|
|
||||||
}
|
|
||||||
catch (UriFormatException)
|
|
||||||
{
|
|
||||||
reason = "Bad location for group proxy";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if it already exists
|
|
||||||
GroupData grec = m_Database.RetrieveGroup(groupID);
|
|
||||||
if (grec == null ||
|
|
||||||
(grec != null && grec.Data["Location"] != string.Empty && grec.Data["Location"].ToLower() != serviceLocation.ToLower()))
|
|
||||||
{
|
|
||||||
// Create the group
|
|
||||||
grec = new GroupData();
|
|
||||||
grec.GroupID = groupID;
|
|
||||||
grec.Data = new Dictionary<string, string>();
|
|
||||||
grec.Data["Name"] = name + " @ " + uri.Authority;
|
|
||||||
grec.Data["Location"] = serviceLocation;
|
|
||||||
grec.Data["Charter"] = string.Empty;
|
|
||||||
grec.Data["InsigniaID"] = UUID.Zero.ToString();
|
|
||||||
grec.Data["FounderID"] = UUID.Zero.ToString();
|
|
||||||
grec.Data["MembershipFee"] = "0";
|
|
||||||
grec.Data["OpenEnrollment"] = "0";
|
|
||||||
grec.Data["ShowInList"] = "0";
|
|
||||||
grec.Data["AllowPublish"] = "0";
|
|
||||||
grec.Data["MaturePublish"] = "0";
|
|
||||||
grec.Data["OwnerRoleID"] = UUID.Zero.ToString();
|
|
||||||
|
|
||||||
|
|
||||||
if (!m_Database.StoreGroup(grec))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (grec.Data["Location"] == string.Empty)
|
|
||||||
{
|
|
||||||
reason = "Cannot add proxy membership to non-proxy group";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
UUID uid = UUID.Zero;
|
|
||||||
string url = string.Empty, first = string.Empty, last = string.Empty, tmp = string.Empty;
|
|
||||||
Util.ParseUniversalUserIdentifier(RequestingAgentID, out uid, out url, out first, out last, out tmp);
|
|
||||||
string fromName = first + "." + last + "@" + url;
|
|
||||||
|
|
||||||
// Invite to group again
|
|
||||||
InviteToGroup(fromName, groupID, new UUID(agentID), grec.Data["Name"]);
|
|
||||||
|
|
||||||
// Stick the proxy membership in the DB already
|
|
||||||
// we'll delete it if the agent declines the invitation
|
|
||||||
MembershipData membership = new MembershipData();
|
|
||||||
membership.PrincipalID = agentID;
|
|
||||||
membership.GroupID = groupID;
|
|
||||||
membership.Data = new Dictionary<string, string>();
|
|
||||||
membership.Data["SelectedRoleID"] = UUID.Zero.ToString();
|
|
||||||
membership.Data["Contribution"] = "0";
|
|
||||||
membership.Data["ListInProfile"] = "1";
|
|
||||||
membership.Data["AcceptNotices"] = "1";
|
|
||||||
membership.Data["AccessToken"] = accessToken;
|
|
||||||
|
|
||||||
m_Database.StoreMember(membership);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool RemoveAgentFromGroup(string RequestingAgentID, string AgentID, UUID GroupID, string token)
|
|
||||||
{
|
|
||||||
// check the token
|
|
||||||
MembershipData membership = m_Database.RetrieveMember(GroupID, AgentID);
|
|
||||||
if (membership != null)
|
|
||||||
{
|
|
||||||
if (token != string.Empty && token.Equals(membership.Data["AccessToken"]))
|
|
||||||
{
|
|
||||||
return RemoveAgentFromGroup(RequestingAgentID, AgentID, GroupID);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_log.DebugFormat("[Groups.HGGroupsService]: access token {0} did not match stored one {1}", token, membership.Data["AccessToken"]);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_log.DebugFormat("[Groups.HGGroupsService]: membership not found for {0}", AgentID);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ExtendedGroupRecord GetGroupRecord(string RequestingAgentID, UUID GroupID, string groupName, string token)
|
|
||||||
{
|
|
||||||
// check the token
|
|
||||||
if (!VerifyToken(GroupID, RequestingAgentID, token))
|
|
||||||
return null;
|
|
||||||
|
|
||||||
ExtendedGroupRecord grec;
|
|
||||||
if (GroupID == UUID.Zero)
|
|
||||||
grec = GetGroupRecord(RequestingAgentID, groupName);
|
|
||||||
else
|
|
||||||
grec = GetGroupRecord(RequestingAgentID, GroupID);
|
|
||||||
|
|
||||||
if (grec != null)
|
|
||||||
FillFounderUUI(grec);
|
|
||||||
|
|
||||||
return grec;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<ExtendedGroupMembersData> GetGroupMembers(string RequestingAgentID, UUID GroupID, string token)
|
|
||||||
{
|
|
||||||
if (!VerifyToken(GroupID, RequestingAgentID, token))
|
|
||||||
return new List<ExtendedGroupMembersData>();
|
|
||||||
|
|
||||||
List<ExtendedGroupMembersData> members = GetGroupMembers(RequestingAgentID, GroupID);
|
|
||||||
|
|
||||||
// convert UUIDs to UUIs
|
|
||||||
members.ForEach(delegate (ExtendedGroupMembersData m)
|
|
||||||
{
|
|
||||||
if (m.AgentID.ToString().Length == 36) // UUID
|
|
||||||
{
|
|
||||||
UserAccount account = m_UserAccounts.GetUserAccount(UUID.Zero, new UUID(m.AgentID));
|
|
||||||
if (account != null)
|
|
||||||
m.AgentID = Util.UniversalIdentifier(account.PrincipalID, account.FirstName, account.LastName, m_HomeURI);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return members;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<GroupRolesData> GetGroupRoles(string RequestingAgentID, UUID GroupID, string token)
|
|
||||||
{
|
|
||||||
if (!VerifyToken(GroupID, RequestingAgentID, token))
|
|
||||||
return new List<GroupRolesData>();
|
|
||||||
|
|
||||||
return GetGroupRoles(RequestingAgentID, GroupID);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<ExtendedGroupRoleMembersData> GetGroupRoleMembers(string RequestingAgentID, UUID GroupID, string token)
|
|
||||||
{
|
|
||||||
if (!VerifyToken(GroupID, RequestingAgentID, token))
|
|
||||||
return new List<ExtendedGroupRoleMembersData>();
|
|
||||||
|
|
||||||
List<ExtendedGroupRoleMembersData> rolemembers = GetGroupRoleMembers(RequestingAgentID, GroupID);
|
|
||||||
|
|
||||||
// convert UUIDs to UUIs
|
|
||||||
rolemembers.ForEach(delegate(ExtendedGroupRoleMembersData m)
|
|
||||||
{
|
|
||||||
if (m.MemberID.ToString().Length == 36) // UUID
|
|
||||||
{
|
|
||||||
UserAccount account = m_UserAccounts.GetUserAccount(UUID.Zero, new UUID(m.MemberID));
|
|
||||||
if (account != null)
|
|
||||||
m.MemberID = Util.UniversalIdentifier(account.PrincipalID, account.FirstName, account.LastName, m_HomeURI);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return rolemembers;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool AddNotice(string RequestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message,
|
|
||||||
bool hasAttachment, byte attType, string attName, UUID attItemID, string attOwnerID)
|
|
||||||
{
|
|
||||||
// check that the group proxy exists
|
|
||||||
ExtendedGroupRecord grec = GetGroupRecord(RequestingAgentID, groupID);
|
|
||||||
if (grec == null)
|
|
||||||
{
|
|
||||||
m_log.DebugFormat("[Groups.HGGroupsService]: attempt at adding notice to non-existent group proxy");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check that the group is remote
|
|
||||||
if (grec.ServiceLocation == string.Empty)
|
|
||||||
{
|
|
||||||
m_log.DebugFormat("[Groups.HGGroupsService]: attempt at adding notice to local (non-proxy) group");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check that there isn't already a notice with the same ID
|
|
||||||
if (GetGroupNotice(RequestingAgentID, noticeID) != null)
|
|
||||||
{
|
|
||||||
m_log.DebugFormat("[Groups.HGGroupsService]: a notice with the same ID already exists", grec.ServiceLocation);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This has good intentions (security) but it will potentially DDS the origin...
|
|
||||||
// We'll need to send a proof along with the message. Maybe encrypt the message
|
|
||||||
// using key pairs
|
|
||||||
//
|
|
||||||
//// check that the notice actually exists in the origin
|
|
||||||
//GroupsServiceHGConnector c = new GroupsServiceHGConnector(grec.ServiceLocation);
|
|
||||||
//if (!c.VerifyNotice(noticeID, groupID))
|
|
||||||
//{
|
|
||||||
// m_log.DebugFormat("[Groups.HGGroupsService]: notice does not exist at origin {0}", grec.ServiceLocation);
|
|
||||||
// return false;
|
|
||||||
//}
|
|
||||||
|
|
||||||
// ok, we're good!
|
|
||||||
return _AddNotice(groupID, noticeID, fromName, subject, message, hasAttachment, attType, attName, attItemID, attOwnerID);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool VerifyNotice(UUID noticeID, UUID groupID)
|
|
||||||
{
|
|
||||||
GroupNoticeInfo notice = GetGroupNotice(string.Empty, noticeID);
|
|
||||||
|
|
||||||
if (notice == null)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (notice.GroupID != groupID)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
private void InviteToGroup(string fromName, UUID groupID, UUID invitedAgentID, string groupName)
|
|
||||||
{
|
|
||||||
// Todo: Security check, probably also want to send some kind of notification
|
|
||||||
UUID InviteID = UUID.Random();
|
|
||||||
|
|
||||||
if (AddAgentToGroupInvite(InviteID, groupID, invitedAgentID.ToString()))
|
|
||||||
{
|
|
||||||
Guid inviteUUID = InviteID.Guid;
|
|
||||||
|
|
||||||
GridInstantMessage msg = new GridInstantMessage();
|
|
||||||
|
|
||||||
msg.imSessionID = inviteUUID;
|
|
||||||
|
|
||||||
// msg.fromAgentID = agentID.Guid;
|
|
||||||
msg.fromAgentID = groupID.Guid;
|
|
||||||
msg.toAgentID = invitedAgentID.Guid;
|
|
||||||
//msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
|
|
||||||
msg.timestamp = 0;
|
|
||||||
msg.fromAgentName = fromName;
|
|
||||||
msg.message = string.Format("Please confirm your acceptance to join group {0}.", groupName);
|
|
||||||
msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.GroupInvitation;
|
|
||||||
msg.fromGroup = true;
|
|
||||||
msg.offline = (byte)0;
|
|
||||||
msg.ParentEstateID = 0;
|
|
||||||
msg.Position = Vector3.Zero;
|
|
||||||
msg.RegionID = UUID.Zero.Guid;
|
|
||||||
msg.binaryBucket = new byte[20];
|
|
||||||
|
|
||||||
string reason = string.Empty;
|
|
||||||
m_OfflineIM.StoreMessage(msg, out reason);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool AddAgentToGroupInvite(UUID inviteID, UUID groupID, string agentID)
|
|
||||||
{
|
|
||||||
// Check whether the invitee is already a member of the group
|
|
||||||
MembershipData m = m_Database.RetrieveMember(groupID, agentID);
|
|
||||||
if (m != null)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Check whether there are pending invitations and delete them
|
|
||||||
InvitationData invite = m_Database.RetrieveInvitation(groupID, agentID);
|
|
||||||
if (invite != null)
|
|
||||||
m_Database.DeleteInvite(invite.InviteID);
|
|
||||||
|
|
||||||
invite = new InvitationData();
|
|
||||||
invite.InviteID = inviteID;
|
|
||||||
invite.PrincipalID = agentID;
|
|
||||||
invite.GroupID = groupID;
|
|
||||||
invite.RoleID = UUID.Zero;
|
|
||||||
invite.Data = new Dictionary<string, string>();
|
|
||||||
|
|
||||||
return m_Database.StoreInvitation(invite);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void FillFounderUUI(ExtendedGroupRecord grec)
|
|
||||||
{
|
|
||||||
UserAccount account = m_UserAccounts.GetUserAccount(UUID.Zero, grec.FounderID);
|
|
||||||
if (account != null)
|
|
||||||
grec.FounderUUI = Util.UniversalIdentifier(account.PrincipalID, account.FirstName, account.LastName, m_HomeURI);
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool VerifyToken(UUID groupID, string agentID, string token)
|
|
||||||
{
|
|
||||||
// check the token
|
|
||||||
MembershipData membership = m_Database.RetrieveMember(groupID, agentID);
|
|
||||||
if (membership != null)
|
|
||||||
{
|
|
||||||
if (token != string.Empty && token.Equals(membership.Data["AccessToken"]))
|
|
||||||
return true;
|
|
||||||
else
|
|
||||||
m_log.DebugFormat("[Groups.HGGroupsService]: access token {0} did not match stored one {1}", token, membership.Data["AccessToken"]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
m_log.DebugFormat("[Groups.HGGroupsService]: membership not found for {0}", agentID);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,252 +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.Reflection;
|
|
||||||
using log4net;
|
|
||||||
using Mono.Addins;
|
|
||||||
using Nini.Config;
|
|
||||||
using OpenMetaverse;
|
|
||||||
using OpenSim.Framework;
|
|
||||||
using OpenSim.Framework.Servers;
|
|
||||||
using OpenSim.Framework.Client;
|
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
|
||||||
using OpenSim.Region.Framework.Scenes;
|
|
||||||
using OpenSim.Services.Interfaces;
|
|
||||||
|
|
||||||
namespace OpenSim.OfflineIM
|
|
||||||
{
|
|
||||||
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "OfflineIMConnectorModule")]
|
|
||||||
public class OfflineIMRegionModule : ISharedRegionModule, IOfflineIMService
|
|
||||||
{
|
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
|
||||||
|
|
||||||
private bool m_Enabled = false;
|
|
||||||
private List<Scene> m_SceneList = new List<Scene>();
|
|
||||||
IMessageTransferModule m_TransferModule = null;
|
|
||||||
private bool m_ForwardOfflineGroupMessages = true;
|
|
||||||
|
|
||||||
private IOfflineIMService m_OfflineIMService;
|
|
||||||
|
|
||||||
public void Initialise(IConfigSource config)
|
|
||||||
{
|
|
||||||
IConfig cnf = config.Configs["Messaging"];
|
|
||||||
if (cnf == null)
|
|
||||||
return;
|
|
||||||
if (cnf != null && cnf.GetString("OfflineMessageModule", string.Empty) != Name)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_Enabled = true;
|
|
||||||
|
|
||||||
string serviceLocation = cnf.GetString("OfflineMessageURL", string.Empty);
|
|
||||||
if (serviceLocation == string.Empty)
|
|
||||||
m_OfflineIMService = new OfflineIMService(config);
|
|
||||||
else
|
|
||||||
m_OfflineIMService = new OfflineIMServiceRemoteConnector(config);
|
|
||||||
|
|
||||||
m_ForwardOfflineGroupMessages = cnf.GetBoolean("ForwardOfflineGroupMessages", m_ForwardOfflineGroupMessages);
|
|
||||||
m_log.DebugFormat("[OfflineIM.V2]: Offline messages enabled by {0}", Name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void AddRegion(Scene scene)
|
|
||||||
{
|
|
||||||
if (!m_Enabled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
scene.RegisterModuleInterface<IOfflineIMService>(this);
|
|
||||||
m_SceneList.Add(scene);
|
|
||||||
scene.EventManager.OnNewClient += OnNewClient;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RegionLoaded(Scene scene)
|
|
||||||
{
|
|
||||||
if (!m_Enabled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (m_TransferModule == null)
|
|
||||||
{
|
|
||||||
m_TransferModule = scene.RequestModuleInterface<IMessageTransferModule>();
|
|
||||||
if (m_TransferModule == null)
|
|
||||||
{
|
|
||||||
scene.EventManager.OnNewClient -= OnNewClient;
|
|
||||||
|
|
||||||
m_SceneList.Clear();
|
|
||||||
|
|
||||||
m_log.Error("[OfflineIM.V2]: No message transfer module is enabled. Disabling offline messages");
|
|
||||||
}
|
|
||||||
m_TransferModule.OnUndeliveredMessage += UndeliveredMessage;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RemoveRegion(Scene scene)
|
|
||||||
{
|
|
||||||
if (!m_Enabled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_SceneList.Remove(scene);
|
|
||||||
scene.EventManager.OnNewClient -= OnNewClient;
|
|
||||||
m_TransferModule.OnUndeliveredMessage -= UndeliveredMessage;
|
|
||||||
|
|
||||||
scene.ForEachClient(delegate(IClientAPI client)
|
|
||||||
{
|
|
||||||
client.OnRetrieveInstantMessages -= RetrieveInstantMessages;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void PostInitialise()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Name
|
|
||||||
{
|
|
||||||
get { return "Offline Message Module V2"; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public Type ReplaceableInterface
|
|
||||||
{
|
|
||||||
get { return null; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Close()
|
|
||||||
{
|
|
||||||
m_SceneList.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Scene FindScene(UUID agentID)
|
|
||||||
{
|
|
||||||
foreach (Scene s in m_SceneList)
|
|
||||||
{
|
|
||||||
ScenePresence presence = s.GetScenePresence(agentID);
|
|
||||||
if (presence != null && !presence.IsChildAgent)
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private IClientAPI FindClient(UUID agentID)
|
|
||||||
{
|
|
||||||
foreach (Scene s in m_SceneList)
|
|
||||||
{
|
|
||||||
ScenePresence presence = s.GetScenePresence(agentID);
|
|
||||||
if (presence != null && !presence.IsChildAgent)
|
|
||||||
return presence.ControllingClient;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnNewClient(IClientAPI client)
|
|
||||||
{
|
|
||||||
client.OnRetrieveInstantMessages += RetrieveInstantMessages;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void RetrieveInstantMessages(IClientAPI client)
|
|
||||||
{
|
|
||||||
m_log.DebugFormat("[OfflineIM.V2]: Retrieving stored messages for {0}", client.AgentId);
|
|
||||||
|
|
||||||
List<GridInstantMessage> msglist = m_OfflineIMService.GetMessages(client.AgentId);
|
|
||||||
|
|
||||||
if (msglist == null)
|
|
||||||
m_log.DebugFormat("[OfflineIM.V2]: WARNING null message list.");
|
|
||||||
|
|
||||||
foreach (GridInstantMessage im in msglist)
|
|
||||||
{
|
|
||||||
if (im.dialog == (byte)InstantMessageDialog.InventoryOffered)
|
|
||||||
// send it directly or else the item will be given twice
|
|
||||||
client.SendInstantMessage(im);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Send through scene event manager so all modules get a chance
|
|
||||||
// to look at this message before it gets delivered.
|
|
||||||
//
|
|
||||||
// Needed for proper state management for stored group
|
|
||||||
// invitations
|
|
||||||
//
|
|
||||||
Scene s = FindScene(client.AgentId);
|
|
||||||
if (s != null)
|
|
||||||
s.EventManager.TriggerIncomingInstantMessage(im);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UndeliveredMessage(GridInstantMessage im)
|
|
||||||
{
|
|
||||||
if (im.dialog != (byte)InstantMessageDialog.MessageFromObject &&
|
|
||||||
im.dialog != (byte)InstantMessageDialog.MessageFromAgent &&
|
|
||||||
im.dialog != (byte)InstantMessageDialog.GroupNotice &&
|
|
||||||
im.dialog != (byte)InstantMessageDialog.GroupInvitation &&
|
|
||||||
im.dialog != (byte)InstantMessageDialog.InventoryOffered)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!m_ForwardOfflineGroupMessages)
|
|
||||||
{
|
|
||||||
if (im.dialog == (byte)InstantMessageDialog.GroupNotice ||
|
|
||||||
im.dialog == (byte)InstantMessageDialog.GroupInvitation)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
string reason = string.Empty;
|
|
||||||
bool success = m_OfflineIMService.StoreMessage(im, out reason);
|
|
||||||
|
|
||||||
if (im.dialog == (byte)InstantMessageDialog.MessageFromAgent)
|
|
||||||
{
|
|
||||||
IClientAPI client = FindClient(new UUID(im.fromAgentID));
|
|
||||||
if (client == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
client.SendInstantMessage(new GridInstantMessage(
|
|
||||||
null, new UUID(im.toAgentID),
|
|
||||||
"System", new UUID(im.fromAgentID),
|
|
||||||
(byte)InstantMessageDialog.MessageFromAgent,
|
|
||||||
"User is not logged in. " +
|
|
||||||
(success ? "Message saved." : "Message not saved: " + reason),
|
|
||||||
false, new Vector3()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#region IOfflineIM
|
|
||||||
|
|
||||||
public List<GridInstantMessage> GetMessages(UUID principalID)
|
|
||||||
{
|
|
||||||
return m_OfflineIMService.GetMessages(principalID);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool StoreMessage(GridInstantMessage im, out string reason)
|
|
||||||
{
|
|
||||||
return m_OfflineIMService.StoreMessage(im, out reason);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void DeleteMessages(UUID userID)
|
|
||||||
{
|
|
||||||
m_OfflineIMService.DeleteMessages(userID);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,36 +0,0 @@
|
||||||
using System.Reflection;
|
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using Mono.Addins;
|
|
||||||
|
|
||||||
// General Information about an assembly is controlled through the following
|
|
||||||
// set of attributes. Change these attribute values to modify the information
|
|
||||||
// associated with an assembly.
|
|
||||||
[assembly: AssemblyTitle("OpenSim.Addons.OfflineIM")]
|
|
||||||
[assembly: AssemblyDescription("")]
|
|
||||||
[assembly: AssemblyConfiguration("")]
|
|
||||||
[assembly: AssemblyCompany("http://opensimulator.org")]
|
|
||||||
[assembly: AssemblyProduct("OpenSim.Addons.OfflineIM")]
|
|
||||||
[assembly: AssemblyCopyright("Copyright (c) OpenSimulator.org Developers")]
|
|
||||||
[assembly: AssemblyTrademark("")]
|
|
||||||
[assembly: AssemblyCulture("")]
|
|
||||||
|
|
||||||
// Setting ComVisible to false makes the types in this assembly not visible
|
|
||||||
// to COM components. If you need to access a type in this assembly from
|
|
||||||
// COM, set the ComVisible attribute to true on that type.
|
|
||||||
[assembly: ComVisible(false)]
|
|
||||||
|
|
||||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
|
||||||
[assembly: Guid("a16a9905-4393-4872-9fca-4c81bedbd9f2")]
|
|
||||||
|
|
||||||
// Version information for an assembly consists of the following four values:
|
|
||||||
//
|
|
||||||
// Major Version
|
|
||||||
// Minor Version
|
|
||||||
// Build Number
|
|
||||||
// Revision
|
|
||||||
//
|
|
||||||
[assembly: AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)]
|
|
||||||
|
|
||||||
[assembly: Addin("OpenSim.OfflineIM", OpenSim.VersionInfo.VersionNumber)]
|
|
||||||
[assembly: AddinDependency("OpenSim.Region.Framework", OpenSim.VersionInfo.VersionNumber)]
|
|
|
@ -1,171 +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.Reflection;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
using OpenSim.Framework;
|
|
||||||
using OpenSim.Framework.ServiceAuth;
|
|
||||||
using OpenSim.Server.Base;
|
|
||||||
using OpenSim.Services.Interfaces;
|
|
||||||
|
|
||||||
using OpenMetaverse;
|
|
||||||
using log4net;
|
|
||||||
using Nini.Config;
|
|
||||||
|
|
||||||
namespace OpenSim.OfflineIM
|
|
||||||
{
|
|
||||||
public class OfflineIMServiceRemoteConnector : IOfflineIMService
|
|
||||||
{
|
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
|
||||||
|
|
||||||
private string m_ServerURI = string.Empty;
|
|
||||||
private IServiceAuth m_Auth;
|
|
||||||
private object m_Lock = new object();
|
|
||||||
|
|
||||||
public OfflineIMServiceRemoteConnector(string url)
|
|
||||||
{
|
|
||||||
m_ServerURI = url;
|
|
||||||
m_log.DebugFormat("[OfflineIM.V2.RemoteConnector]: Offline IM server at {0}", m_ServerURI);
|
|
||||||
}
|
|
||||||
|
|
||||||
public OfflineIMServiceRemoteConnector(IConfigSource config)
|
|
||||||
{
|
|
||||||
IConfig cnf = config.Configs["Messaging"];
|
|
||||||
if (cnf == null)
|
|
||||||
{
|
|
||||||
m_log.WarnFormat("[OfflineIM.V2.RemoteConnector]: Missing Messaging configuration");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
public List<GridInstantMessage> GetMessages(UUID principalID)
|
|
||||||
{
|
|
||||||
List<GridInstantMessage> ims = new List<GridInstantMessage>();
|
|
||||||
|
|
||||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
|
||||||
sendData["PrincipalID"] = principalID;
|
|
||||||
Dictionary<string, object> ret = MakeRequest("GET", sendData);
|
|
||||||
|
|
||||||
if (ret == null)
|
|
||||||
return ims;
|
|
||||||
|
|
||||||
if (!ret.ContainsKey("RESULT"))
|
|
||||||
return ims;
|
|
||||||
|
|
||||||
string result = ret["RESULT"].ToString();
|
|
||||||
if (result == "NULL" || result.ToLower() == "false")
|
|
||||||
{
|
|
||||||
string reason = ret.ContainsKey("REASON") ? ret["REASON"].ToString() : "Unknown error";
|
|
||||||
m_log.DebugFormat("[OfflineIM.V2.RemoteConnector]: GetMessages for {0} failed: {1}", principalID, reason);
|
|
||||||
return ims;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (object v in ((Dictionary<string, object>)ret["RESULT"]).Values)
|
|
||||||
{
|
|
||||||
GridInstantMessage m = OfflineIMDataUtils.GridInstantMessage((Dictionary<string, object>)v);
|
|
||||||
ims.Add(m);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ims;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool StoreMessage(GridInstantMessage im, out string reason)
|
|
||||||
{
|
|
||||||
reason = string.Empty;
|
|
||||||
Dictionary<string, object> sendData = OfflineIMDataUtils.GridInstantMessage(im);
|
|
||||||
|
|
||||||
Dictionary<string, object> ret = MakeRequest("STORE", sendData);
|
|
||||||
|
|
||||||
if (ret == null)
|
|
||||||
{
|
|
||||||
reason = "Bad response from server";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
string result = ret["RESULT"].ToString();
|
|
||||||
if (result == "NULL" || result.ToLower() == "false")
|
|
||||||
{
|
|
||||||
reason = ret.ContainsKey("REASON") ? ret["REASON"].ToString() : "Unknown error";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void DeleteMessages(UUID userID)
|
|
||||||
{
|
|
||||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
|
||||||
sendData["UserID"] = userID;
|
|
||||||
|
|
||||||
MakeRequest("DELETE", sendData);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
#region Make Request
|
|
||||||
|
|
||||||
private Dictionary<string, object> MakeRequest(string method, Dictionary<string, object> sendData)
|
|
||||||
{
|
|
||||||
sendData["METHOD"] = method;
|
|
||||||
|
|
||||||
string reply = string.Empty;
|
|
||||||
lock (m_Lock)
|
|
||||||
reply = SynchronousRestFormsRequester.MakeRequest("POST",
|
|
||||||
m_ServerURI + "/offlineim",
|
|
||||||
ServerUtils.BuildQueryString(sendData),
|
|
||||||
m_Auth);
|
|
||||||
|
|
||||||
Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(
|
|
||||||
reply);
|
|
||||||
|
|
||||||
return replyData;
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,223 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
* * Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* * Neither the name of the OpenSimulator Project nor the
|
|
||||||
* names of its contributors may be used to endorse or promote products
|
|
||||||
* derived from this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
|
||||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Text;
|
|
||||||
using System.Xml;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using Nini.Config;
|
|
||||||
using OpenSim.Framework;
|
|
||||||
using OpenSim.Server.Base;
|
|
||||||
using OpenSim.Services.Interfaces;
|
|
||||||
using OpenSim.Framework.Servers.HttpServer;
|
|
||||||
using OpenSim.Framework.ServiceAuth;
|
|
||||||
using OpenSim.Server.Handlers.Base;
|
|
||||||
using log4net;
|
|
||||||
using OpenMetaverse;
|
|
||||||
|
|
||||||
namespace OpenSim.OfflineIM
|
|
||||||
{
|
|
||||||
public class OfflineIMServiceRobustConnector : ServiceConnector
|
|
||||||
{
|
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
|
||||||
|
|
||||||
private IOfflineIMService m_OfflineIMService;
|
|
||||||
private string m_ConfigName = "Messaging";
|
|
||||||
|
|
||||||
public OfflineIMServiceRobustConnector(IConfigSource config, IHttpServer server, string configName) :
|
|
||||||
base(config, server, configName)
|
|
||||||
{
|
|
||||||
if (configName != String.Empty)
|
|
||||||
m_ConfigName = configName;
|
|
||||||
|
|
||||||
m_log.DebugFormat("[OfflineIM.V2.RobustConnector]: Starting with config name {0}", m_ConfigName);
|
|
||||||
|
|
||||||
m_OfflineIMService = new OfflineIMService(config);
|
|
||||||
|
|
||||||
IServiceAuth auth = ServiceAuth.Create(config, m_ConfigName);
|
|
||||||
|
|
||||||
server.AddStreamHandler(new OfflineIMServicePostHandler(m_OfflineIMService, auth));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class OfflineIMServicePostHandler : BaseStreamHandler
|
|
||||||
{
|
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
|
||||||
|
|
||||||
private IOfflineIMService m_OfflineIMService;
|
|
||||||
|
|
||||||
public OfflineIMServicePostHandler(IOfflineIMService service, IServiceAuth auth) :
|
|
||||||
base("POST", "/offlineim", auth)
|
|
||||||
{
|
|
||||||
m_OfflineIMService = service;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override byte[] ProcessRequest(string path, Stream requestData,
|
|
||||||
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
|
||||||
{
|
|
||||||
StreamReader sr = new StreamReader(requestData);
|
|
||||||
string body = sr.ReadToEnd();
|
|
||||||
sr.Close();
|
|
||||||
body = body.Trim();
|
|
||||||
|
|
||||||
//m_log.DebugFormat("[XXX]: query String: {0}", body);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Dictionary<string, object> request =
|
|
||||||
ServerUtils.ParseQueryString(body);
|
|
||||||
|
|
||||||
if (!request.ContainsKey("METHOD"))
|
|
||||||
return FailureResult();
|
|
||||||
|
|
||||||
string method = request["METHOD"].ToString();
|
|
||||||
request.Remove("METHOD");
|
|
||||||
|
|
||||||
switch (method)
|
|
||||||
{
|
|
||||||
case "GET":
|
|
||||||
return HandleGet(request);
|
|
||||||
case "STORE":
|
|
||||||
return HandleStore(request);
|
|
||||||
case "DELETE":
|
|
||||||
return HandleDelete(request);
|
|
||||||
}
|
|
||||||
m_log.DebugFormat("[OFFLINE IM HANDLER]: unknown method request: {0}", method);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
m_log.Error(string.Format("[OFFLINE IM HANDLER]: Exception {0} ", e.Message), e);
|
|
||||||
}
|
|
||||||
|
|
||||||
return FailureResult();
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] HandleStore(Dictionary<string, object> request)
|
|
||||||
{
|
|
||||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
|
||||||
|
|
||||||
GridInstantMessage im = OfflineIMDataUtils.GridInstantMessage(request);
|
|
||||||
|
|
||||||
string reason = string.Empty;
|
|
||||||
|
|
||||||
bool success = m_OfflineIMService.StoreMessage(im, out reason);
|
|
||||||
|
|
||||||
result["RESULT"] = success.ToString();
|
|
||||||
if (!success)
|
|
||||||
result["REASON"] = reason;
|
|
||||||
|
|
||||||
string xmlString = ServerUtils.BuildXmlResponse(result);
|
|
||||||
|
|
||||||
//m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
|
|
||||||
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] HandleGet(Dictionary<string, object> request)
|
|
||||||
{
|
|
||||||
Dictionary<string, object> result = new Dictionary<string, object>();
|
|
||||||
|
|
||||||
if (!request.ContainsKey("PrincipalID"))
|
|
||||||
NullResult(result, "Bad network data");
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UUID principalID = new UUID(request["PrincipalID"].ToString());
|
|
||||||
List<GridInstantMessage> ims = m_OfflineIMService.GetMessages(principalID);
|
|
||||||
|
|
||||||
Dictionary<string, object> dict = new Dictionary<string, object>();
|
|
||||||
int i = 0;
|
|
||||||
foreach (GridInstantMessage m in ims)
|
|
||||||
dict["im-" + i++] = OfflineIMDataUtils.GridInstantMessage(m);
|
|
||||||
|
|
||||||
result["RESULT"] = dict;
|
|
||||||
}
|
|
||||||
|
|
||||||
string xmlString = ServerUtils.BuildXmlResponse(result);
|
|
||||||
|
|
||||||
//m_log.DebugFormat("[XXX]: resp string: {0}", 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
|
|
||||||
|
|
||||||
private void NullResult(Dictionary<string, object> result, string reason)
|
|
||||||
{
|
|
||||||
result["RESULT"] = "NULL";
|
|
||||||
result["REASON"] = reason;
|
|
||||||
}
|
|
||||||
|
|
||||||
private byte[] FailureResult()
|
|
||||||
{
|
|
||||||
return BoolResult(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private byte[] SuccessResult()
|
|
||||||
{
|
|
||||||
return BoolResult(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private byte[] BoolResult(bool value)
|
|
||||||
{
|
|
||||||
XmlDocument doc = new XmlDocument();
|
|
||||||
|
|
||||||
XmlNode xmlnode = doc.CreateNode(XmlNodeType.XmlDeclaration,
|
|
||||||
"", "");
|
|
||||||
|
|
||||||
doc.AppendChild(xmlnode);
|
|
||||||
|
|
||||||
XmlElement rootElement = doc.CreateElement("", "ServerResponse",
|
|
||||||
"");
|
|
||||||
|
|
||||||
doc.AppendChild(rootElement);
|
|
||||||
|
|
||||||
XmlElement result = doc.CreateElement("", "RESULT", "");
|
|
||||||
result.AppendChild(doc.CreateTextNode(value.ToString()));
|
|
||||||
|
|
||||||
rootElement.AppendChild(result);
|
|
||||||
|
|
||||||
return Util.DocToBytes(doc);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,134 +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.IO;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Runtime.Serialization;
|
|
||||||
using System.Text;
|
|
||||||
using System.Timers;
|
|
||||||
using System.Xml;
|
|
||||||
using System.Xml.Serialization;
|
|
||||||
using log4net;
|
|
||||||
using Nini.Config;
|
|
||||||
|
|
||||||
using OpenMetaverse;
|
|
||||||
using OpenSim.Data;
|
|
||||||
using OpenSim.Framework;
|
|
||||||
using OpenSim.Services.Interfaces;
|
|
||||||
|
|
||||||
namespace OpenSim.OfflineIM
|
|
||||||
{
|
|
||||||
public class OfflineIMService : OfflineIMServiceBase, IOfflineIMService
|
|
||||||
{
|
|
||||||
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
|
||||||
private const int MAX_IM = 25;
|
|
||||||
|
|
||||||
private XmlSerializer m_serializer;
|
|
||||||
private static bool m_Initialized = false;
|
|
||||||
|
|
||||||
public OfflineIMService(IConfigSource config)
|
|
||||||
: base(config)
|
|
||||||
{
|
|
||||||
m_serializer = new XmlSerializer(typeof(GridInstantMessage));
|
|
||||||
if (!m_Initialized)
|
|
||||||
{
|
|
||||||
m_Database.DeleteOld();
|
|
||||||
m_Initialized = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<GridInstantMessage> GetMessages(UUID principalID)
|
|
||||||
{
|
|
||||||
List<GridInstantMessage> ims = new List<GridInstantMessage>();
|
|
||||||
|
|
||||||
OfflineIMData[] messages = m_Database.Get("PrincipalID", principalID.ToString());
|
|
||||||
|
|
||||||
if (messages == null || (messages != null && messages.Length == 0))
|
|
||||||
return ims;
|
|
||||||
|
|
||||||
foreach (OfflineIMData m in messages)
|
|
||||||
{
|
|
||||||
using (MemoryStream mstream = new MemoryStream(Encoding.UTF8.GetBytes(m.Data["Message"])))
|
|
||||||
{
|
|
||||||
GridInstantMessage im = (GridInstantMessage)m_serializer.Deserialize(mstream);
|
|
||||||
ims.Add(im);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Then, delete them
|
|
||||||
m_Database.Delete("PrincipalID", principalID.ToString());
|
|
||||||
|
|
||||||
return ims;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool StoreMessage(GridInstantMessage im, out string reason)
|
|
||||||
{
|
|
||||||
reason = string.Empty;
|
|
||||||
|
|
||||||
// Check limits
|
|
||||||
UUID principalID = new UUID(im.toAgentID);
|
|
||||||
long count = m_Database.GetCount("PrincipalID", principalID.ToString());
|
|
||||||
if (count >= MAX_IM)
|
|
||||||
{
|
|
||||||
reason = "Number of offline IMs has maxed out";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
string imXml;
|
|
||||||
using (MemoryStream mstream = new MemoryStream())
|
|
||||||
{
|
|
||||||
XmlWriterSettings settings = new XmlWriterSettings();
|
|
||||||
settings.Encoding = Util.UTF8NoBomEncoding;
|
|
||||||
|
|
||||||
using (XmlWriter writer = XmlWriter.Create(mstream, settings))
|
|
||||||
{
|
|
||||||
m_serializer.Serialize(writer, im);
|
|
||||||
writer.Flush();
|
|
||||||
imXml = Util.UTF8NoBomEncoding.GetString(mstream.ToArray());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
OfflineIMData data = new OfflineIMData();
|
|
||||||
data.PrincipalID = principalID;
|
|
||||||
data.FromID = new UUID(im.fromAgentID);
|
|
||||||
data.Data = new Dictionary<string, string>();
|
|
||||||
data.Data["Message"] = imXml;
|
|
||||||
|
|
||||||
return m_Database.Store(data);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void DeleteMessages(UUID userID)
|
|
||||||
{
|
|
||||||
m_Database.Delete("PrincipalID", userID.ToString());
|
|
||||||
m_Database.Delete("FromID", userID.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,83 +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.Reflection;
|
|
||||||
using Nini.Config;
|
|
||||||
using OpenSim.Framework;
|
|
||||||
using OpenSim.Data;
|
|
||||||
using OpenSim.Services.Interfaces;
|
|
||||||
using OpenSim.Services.Base;
|
|
||||||
|
|
||||||
namespace OpenSim.OfflineIM
|
|
||||||
{
|
|
||||||
public class OfflineIMServiceBase : ServiceBase
|
|
||||||
{
|
|
||||||
protected IOfflineIMData m_Database = null;
|
|
||||||
|
|
||||||
public OfflineIMServiceBase(IConfigSource config)
|
|
||||||
: base(config)
|
|
||||||
{
|
|
||||||
string dllName = String.Empty;
|
|
||||||
string connString = String.Empty;
|
|
||||||
string realm = "im_offline";
|
|
||||||
|
|
||||||
//
|
|
||||||
// Try reading the [DatabaseService] section, if it exists
|
|
||||||
//
|
|
||||||
IConfig dbConfig = config.Configs["DatabaseService"];
|
|
||||||
if (dbConfig != null)
|
|
||||||
{
|
|
||||||
if (dllName == String.Empty)
|
|
||||||
dllName = dbConfig.GetString("StorageProvider", String.Empty);
|
|
||||||
if (connString == String.Empty)
|
|
||||||
connString = dbConfig.GetString("ConnectionString", String.Empty);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// [Messaging] section overrides [DatabaseService], if it exists
|
|
||||||
//
|
|
||||||
IConfig imConfig = config.Configs["Messaging"];
|
|
||||||
if (imConfig != null)
|
|
||||||
{
|
|
||||||
dllName = imConfig.GetString("StorageProvider", dllName);
|
|
||||||
connString = imConfig.GetString("ConnectionString", connString);
|
|
||||||
realm = imConfig.GetString("Realm", realm);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// We tried, but this doesn't exist. We can't proceed.
|
|
||||||
//
|
|
||||||
if (dllName.Equals(String.Empty))
|
|
||||||
throw new Exception("No StorageProvider configured");
|
|
||||||
|
|
||||||
m_Database = LoadPlugin<IOfflineIMData>(dllName, new Object[] { connString, realm });
|
|
||||||
if (m_Database == null)
|
|
||||||
throw new Exception("Could not find a storage interface in the given module " + dllName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,38 +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 Nini.Config;
|
|
||||||
using OpenSim.Framework;
|
|
||||||
|
|
||||||
namespace OpenSim.ApplicationPlugins.LoadRegions
|
|
||||||
{
|
|
||||||
public interface IRegionLoader
|
|
||||||
{
|
|
||||||
void SetIniConfigSource(IConfigSource configSource);
|
|
||||||
RegionInfo[] LoadRegions();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,208 +1,108 @@
|
||||||
/*
|
/*
|
||||||
* 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.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
* * Redistributions of source code must retain the above copyright
|
* * Redistributions of source code must retain the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer.
|
* notice, this list of conditions and the following disclaimer.
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
* * Neither the name of the OpenSimulator Project nor the
|
* * Neither the name of the OpenSim Project nor the
|
||||||
* names of its contributors may be used to endorse or promote products
|
* names of its contributors may be used to endorse or promote products
|
||||||
* derived from this software without specific prior written permission.
|
* derived from this software without specific prior written permission.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
* 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
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Threading;
|
|
||||||
using log4net;
|
|
||||||
using OpenMetaverse;
|
|
||||||
using OpenSim.Framework;
|
|
||||||
using OpenSim.Region.CoreModules.Agent.AssetTransaction;
|
|
||||||
using OpenSim.Region.CoreModules.Avatar.InstantMessage;
|
|
||||||
using OpenSim.Region.CoreModules.Scripting.DynamicTexture;
|
|
||||||
using OpenSim.Region.CoreModules.Scripting.LoadImageURL;
|
|
||||||
using OpenSim.Region.CoreModules.Scripting.XMLRPC;
|
|
||||||
using OpenSim.Services.Interfaces;
|
|
||||||
using Mono.Addins;
|
using Mono.Addins;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Framework.Console;
|
||||||
|
using OpenSim.Framework.RegionLoader.Filesystem;
|
||||||
|
using OpenSim.Framework.RegionLoader.Web;
|
||||||
|
|
||||||
|
[assembly : Addin]
|
||||||
|
[assembly : AddinDependency("OpenSim", "0.5")]
|
||||||
|
|
||||||
namespace OpenSim.ApplicationPlugins.LoadRegions
|
namespace OpenSim.ApplicationPlugins.LoadRegions
|
||||||
{
|
{
|
||||||
[Extension(Path="/OpenSim/Startup", Id="LoadRegions", NodeName="Plugin")]
|
[Extension("/OpenSim/Startup")]
|
||||||
public class LoadRegionsPlugin : IApplicationPlugin, IRegionCreator
|
public class LoadRegionsPlugin : IApplicationPlugin
|
||||||
{
|
{
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
public event NewRegionCreated OnNewRegionCreated;
|
public void Initialise(OpenSimMain openSim)
|
||||||
private NewRegionCreated m_newRegionCreatedHandler;
|
|
||||||
|
|
||||||
#region IApplicationPlugin Members
|
|
||||||
|
|
||||||
// TODO: required by IPlugin, but likely not at all right
|
|
||||||
private string m_name = "LoadRegionsPlugin";
|
|
||||||
private string m_version = "0.0";
|
|
||||||
|
|
||||||
public string Version
|
|
||||||
{
|
{
|
||||||
get { return m_version; }
|
m_log.Info("[LOADREGIONS]: Load Regions addin being initialised");
|
||||||
}
|
|
||||||
|
|
||||||
public string Name
|
|
||||||
{
|
|
||||||
get { return m_name; }
|
|
||||||
}
|
|
||||||
|
|
||||||
protected OpenSimBase m_openSim;
|
|
||||||
|
|
||||||
public void Initialise()
|
|
||||||
{
|
|
||||||
m_log.Error("[LOAD REGIONS PLUGIN]: " + Name + " cannot be default-initialized!");
|
|
||||||
throw new PluginNotInitialisedException(Name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Initialise(OpenSimBase openSim)
|
|
||||||
{
|
|
||||||
m_openSim = openSim;
|
|
||||||
m_openSim.ApplicationRegistry.RegisterInterface<IRegionCreator>(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void PostInitialise()
|
|
||||||
{
|
|
||||||
//m_log.Info("[LOADREGIONS]: Load Regions addin being initialised");
|
|
||||||
|
|
||||||
IRegionLoader regionLoader;
|
IRegionLoader regionLoader;
|
||||||
if (m_openSim.ConfigSource.Source.Configs["Startup"].GetString("region_info_source", "filesystem") == "filesystem")
|
if (openSim.ConfigSource.Configs["Startup"].GetString("region_info_source", "filesystem") == "filesystem")
|
||||||
{
|
{
|
||||||
m_log.Info("[LOAD REGIONS PLUGIN]: Loading region configurations from filesystem");
|
m_log.Info("[LOADREGIONS]: Loading Region Info from filesystem");
|
||||||
regionLoader = new RegionLoaderFileSystem();
|
regionLoader = new RegionLoaderFileSystem();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_log.Info("[LOAD REGIONS PLUGIN]: Loading region configurations from web");
|
m_log.Info("[LOADREGIONSPLUGIN]: Loading Region Info from web");
|
||||||
regionLoader = new RegionLoaderWebServer();
|
regionLoader = new RegionLoaderWebServer();
|
||||||
}
|
}
|
||||||
|
|
||||||
regionLoader.SetIniConfigSource(m_openSim.ConfigSource.Source);
|
regionLoader.SetIniConfigSource(openSim.ConfigSource);
|
||||||
RegionInfo[] regionsToLoad = regionLoader.LoadRegions();
|
RegionInfo[] regionsToLoad = regionLoader.LoadRegions();
|
||||||
|
|
||||||
m_log.Info("[LOAD REGIONS PLUGIN]: Loading specific shared modules...");
|
openSim.ModuleLoader.LoadDefaultSharedModules();
|
||||||
//m_log.Info("[LOAD REGIONS PLUGIN]: DynamicTextureModule...");
|
|
||||||
//m_openSim.ModuleLoader.LoadDefaultSharedModule(new DynamicTextureModule());
|
|
||||||
//m_log.Info("[LOAD REGIONS PLUGIN]: LoadImageURLModule...");
|
|
||||||
//m_openSim.ModuleLoader.LoadDefaultSharedModule(new LoadImageURLModule());
|
|
||||||
//m_log.Info("[LOAD REGIONS PLUGIN]: XMLRPCModule...");
|
|
||||||
//m_openSim.ModuleLoader.LoadDefaultSharedModule(new XMLRPCModule());
|
|
||||||
// m_log.Info("[LOADREGIONSPLUGIN]: AssetTransactionModule...");
|
|
||||||
// m_openSim.ModuleLoader.LoadDefaultSharedModule(new AssetTransactionModule());
|
|
||||||
m_log.Info("[LOAD REGIONS PLUGIN]: Done.");
|
|
||||||
|
|
||||||
if (!CheckRegionsForSanity(regionsToLoad))
|
|
||||||
{
|
|
||||||
m_log.Error("[LOAD REGIONS PLUGIN]: Halting startup due to conflicts in region configurations");
|
|
||||||
Environment.Exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
List<IScene> createdScenes = new List<IScene>();
|
|
||||||
|
|
||||||
for (int i = 0; i < regionsToLoad.Length; i++)
|
for (int i = 0; i < regionsToLoad.Length; i++)
|
||||||
{
|
{
|
||||||
IScene scene;
|
m_log.Debug("[LOADREGIONS]: Creating Region: " + regionsToLoad[i].RegionName + " (ThreadID: " + System.Threading.Thread.CurrentThread.ManagedThreadId.ToString() + ")");
|
||||||
m_log.Debug("[LOAD REGIONS PLUGIN]: Creating Region: " + regionsToLoad[i].RegionName + " (ThreadID: " +
|
openSim.CreateRegion(regionsToLoad[i]);
|
||||||
Thread.CurrentThread.ManagedThreadId.ToString() +
|
|
||||||
")");
|
|
||||||
|
|
||||||
bool changed = m_openSim.PopulateRegionEstateInfo(regionsToLoad[i]);
|
|
||||||
|
|
||||||
m_openSim.CreateRegion(regionsToLoad[i], true, out scene);
|
|
||||||
createdScenes.Add(scene);
|
|
||||||
|
|
||||||
if (changed)
|
|
||||||
m_openSim.EstateDataService.StoreEstateSettings(regionsToLoad[i].EstateSettings);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (IScene scene in createdScenes)
|
openSim.ModuleLoader.PostInitialise();
|
||||||
{
|
openSim.ModuleLoader.ClearCache();
|
||||||
scene.Start();
|
}
|
||||||
|
|
||||||
m_newRegionCreatedHandler = OnNewRegionCreated;
|
public void LoadRegionFromConfig(OpenSimMain openSim, ulong regionhandle)
|
||||||
if (m_newRegionCreatedHandler != null)
|
{
|
||||||
|
m_log.Info("[LOADREGIONS]: Load Regions addin being initialised");
|
||||||
|
|
||||||
|
IRegionLoader regionLoader;
|
||||||
|
if (openSim.ConfigSource.Configs["Startup"].GetString("region_info_source", "filesystem") == "filesystem")
|
||||||
|
{
|
||||||
|
m_log.Info("[LOADREGIONS]: Loading Region Info from filesystem");
|
||||||
|
regionLoader = new RegionLoaderFileSystem();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_log.Info("[LOADREGIONS]: Loading Region Info from web");
|
||||||
|
regionLoader = new RegionLoaderWebServer();
|
||||||
|
}
|
||||||
|
|
||||||
|
regionLoader.SetIniConfigSource(openSim.ConfigSource);
|
||||||
|
RegionInfo[] regionsToLoad = regionLoader.LoadRegions();
|
||||||
|
for (int i = 0; i < regionsToLoad.Length; i++)
|
||||||
|
{
|
||||||
|
if (regionhandle == regionsToLoad[i].RegionHandle)
|
||||||
{
|
{
|
||||||
m_newRegionCreatedHandler(scene);
|
m_log.Debug("[LOADREGIONS]: Creating Region: " + regionsToLoad[i].RegionName + " (ThreadID: " + System.Threading.Thread.CurrentThread.ManagedThreadId.ToString() + ")");
|
||||||
|
openSim.CreateRegion(regionsToLoad[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Close()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Check that region configuration information makes sense.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="regions"></param>
|
|
||||||
/// <returns>True if we're sane, false if we're insane</returns>
|
|
||||||
private bool CheckRegionsForSanity(RegionInfo[] regions)
|
|
||||||
{
|
|
||||||
if (regions.Length == 0)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
foreach (RegionInfo region in regions)
|
|
||||||
{
|
|
||||||
if (region.RegionID == UUID.Zero)
|
|
||||||
{
|
|
||||||
m_log.ErrorFormat(
|
|
||||||
"[LOAD REGIONS PLUGIN]: Region {0} has invalid UUID {1}",
|
|
||||||
region.RegionName, region.RegionID);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < regions.Length - 1; i++)
|
|
||||||
{
|
|
||||||
for (int j = i + 1; j < regions.Length; j++)
|
|
||||||
{
|
|
||||||
if (regions[i].RegionID == regions[j].RegionID)
|
|
||||||
{
|
|
||||||
m_log.ErrorFormat(
|
|
||||||
"[LOAD REGIONS PLUGIN]: Regions {0} and {1} have the same UUID {2}",
|
|
||||||
regions[i].RegionName, regions[j].RegionName, regions[i].RegionID);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else if (
|
|
||||||
regions[i].RegionLocX == regions[j].RegionLocX && regions[i].RegionLocY == regions[j].RegionLocY)
|
|
||||||
{
|
|
||||||
m_log.ErrorFormat(
|
|
||||||
"[LOAD REGIONS PLUGIN]: Regions {0} and {1} have the same grid location ({2}, {3})",
|
|
||||||
regions[i].RegionName, regions[j].RegionName, regions[i].RegionLocX, regions[i].RegionLocY);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else if (regions[i].InternalEndPoint.Port == regions[j].InternalEndPoint.Port)
|
|
||||||
{
|
|
||||||
m_log.ErrorFormat(
|
|
||||||
"[LOAD REGIONS PLUGIN]: Regions {0} and {1} have the same internal IP port {2}",
|
|
||||||
regions[i].RegionName, regions[j].RegionName, regions[i].InternalEndPoint.Port);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,49 +1,49 @@
|
||||||
/*
|
/*
|
||||||
* 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.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
* * Redistributions of source code must retain the above copyright
|
* * Redistributions of source code must retain the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer.
|
* notice, this list of conditions and the following disclaimer.
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
* * Neither the name of the OpenSimulator Project nor the
|
* * Neither the name of the OpenSim Project nor the
|
||||||
* names of its contributors may be used to endorse or promote products
|
* names of its contributors may be used to endorse or promote products
|
||||||
* derived from this software without specific prior written permission.
|
* derived from this software without specific prior written permission.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
* 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
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
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("")]
|
||||||
[assembly : AssemblyProduct("OpenSim")]
|
[assembly : AssemblyProduct("OpenSim.Addin")]
|
||||||
[assembly : AssemblyCopyright("Copyright © OpenSimulator.org Developers 2007-2009")]
|
[assembly : AssemblyCopyright("Copyright © OpenSimulator.org Developers 2007-2008")]
|
||||||
[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)]
|
||||||
|
@ -55,14 +55,13 @@ 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
|
||||||
//
|
//
|
||||||
// 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("1.0.*")]
|
||||||
|
|
||||||
[assembly : AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)]
|
[assembly : AssemblyVersion("1.0.0.0")]
|
||||||
|
[assembly : AssemblyFileVersion("1.0.0.0")]
|
||||||
[assembly: Addin("OpenSim.ApplicationPlugins.LoadRegions", OpenSim.VersionInfo.VersionNumber)]
|
|
||||||
[assembly: AddinDependency("OpenSim", OpenSim.VersionInfo.VersionNumber)]
|
|
||||||
|
|
|
@ -1,117 +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 log4net;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Reflection;
|
|
||||||
using Nini.Config;
|
|
||||||
using OpenSim.Framework;
|
|
||||||
|
|
||||||
namespace OpenSim.ApplicationPlugins.LoadRegions
|
|
||||||
{
|
|
||||||
public class RegionLoaderFileSystem : IRegionLoader
|
|
||||||
{
|
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
|
||||||
|
|
||||||
private IConfigSource m_configSource;
|
|
||||||
|
|
||||||
public void SetIniConfigSource(IConfigSource configSource)
|
|
||||||
{
|
|
||||||
m_configSource = configSource;
|
|
||||||
}
|
|
||||||
|
|
||||||
public RegionInfo[] LoadRegions()
|
|
||||||
{
|
|
||||||
string regionConfigPath = Path.Combine(Util.configDir(), "Regions");
|
|
||||||
bool allowRegionless = false;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
IConfig startupConfig = (IConfig)m_configSource.Configs["Startup"];
|
|
||||||
regionConfigPath = startupConfig.GetString("regionload_regionsdir", regionConfigPath).Trim();
|
|
||||||
allowRegionless = startupConfig.GetBoolean("allow_regionless", false);
|
|
||||||
}
|
|
||||||
catch (Exception)
|
|
||||||
{
|
|
||||||
// No INI setting recorded.
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Directory.Exists(regionConfigPath))
|
|
||||||
{
|
|
||||||
Directory.CreateDirectory(regionConfigPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
string[] configFiles = Directory.GetFiles(regionConfigPath, "*.xml");
|
|
||||||
string[] iniFiles = Directory.GetFiles(regionConfigPath, "*.ini");
|
|
||||||
|
|
||||||
// Create an empty Regions.ini if there are no existing config files.
|
|
||||||
if (!allowRegionless && configFiles.Length == 0 && iniFiles.Length == 0)
|
|
||||||
{
|
|
||||||
new RegionInfo("DEFAULT REGION CONFIG", Path.Combine(regionConfigPath, "Regions.ini"), false, m_configSource);
|
|
||||||
iniFiles = Directory.GetFiles(regionConfigPath, "*.ini");
|
|
||||||
}
|
|
||||||
|
|
||||||
m_log.InfoFormat("[REGION LOADER FILE SYSTEM]: Loading config files from {0}", regionConfigPath);
|
|
||||||
|
|
||||||
List<RegionInfo> regionInfos = new List<RegionInfo>();
|
|
||||||
|
|
||||||
int i = 0;
|
|
||||||
foreach (string file in iniFiles)
|
|
||||||
{
|
|
||||||
m_log.InfoFormat("[REGION LOADER FILE SYSTEM]: Loading config file {0}", file);
|
|
||||||
|
|
||||||
IConfigSource source = new IniConfigSource(file);
|
|
||||||
|
|
||||||
foreach (IConfig config in source.Configs)
|
|
||||||
{
|
|
||||||
RegionInfo regionInfo = new RegionInfo("REGION CONFIG #" + (i + 1), file, false, m_configSource, config.Name);
|
|
||||||
regionInfos.Add(regionInfo);
|
|
||||||
|
|
||||||
m_log.InfoFormat("[REGION LOADER FILE SYSTEM]: Loaded config for region {0}", regionInfo.RegionName);
|
|
||||||
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (string file in configFiles)
|
|
||||||
{
|
|
||||||
m_log.InfoFormat("[REGION LOADER FILE SYSTEM]: Loading config file {0}", file);
|
|
||||||
|
|
||||||
RegionInfo regionInfo = new RegionInfo("REGION CONFIG #" + (i + 1), file, false, m_configSource);
|
|
||||||
regionInfos.Add(regionInfo);
|
|
||||||
|
|
||||||
m_log.InfoFormat("[REGION LOADER FILE SYSTEM]: Loaded config for region {0}", regionInfo.RegionName);
|
|
||||||
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return regionInfos.ToArray();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,143 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
* * Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* * Neither the name of the OpenSimulator Project nor the
|
|
||||||
* names of its contributors may be used to endorse or promote products
|
|
||||||
* derived from this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
|
||||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.IO;
|
|
||||||
using System.Net;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Xml;
|
|
||||||
using log4net;
|
|
||||||
using Nini.Config;
|
|
||||||
using OpenSim.Framework;
|
|
||||||
|
|
||||||
namespace OpenSim.ApplicationPlugins.LoadRegions
|
|
||||||
{
|
|
||||||
public class RegionLoaderWebServer : IRegionLoader
|
|
||||||
{
|
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
|
||||||
|
|
||||||
private IConfigSource m_configSource;
|
|
||||||
|
|
||||||
public void SetIniConfigSource(IConfigSource configSource)
|
|
||||||
{
|
|
||||||
m_configSource = configSource;
|
|
||||||
}
|
|
||||||
|
|
||||||
public RegionInfo[] LoadRegions()
|
|
||||||
{
|
|
||||||
int tries = 3;
|
|
||||||
int wait = 2000;
|
|
||||||
|
|
||||||
if (m_configSource == null)
|
|
||||||
{
|
|
||||||
m_log.Error("[WEBLOADER]: Unable to load configuration source!");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
IConfig startupConfig = (IConfig)m_configSource.Configs["Startup"];
|
|
||||||
string url = startupConfig.GetString("regionload_webserver_url", String.Empty).Trim();
|
|
||||||
bool allowRegionless = startupConfig.GetBoolean("allow_regionless", false);
|
|
||||||
|
|
||||||
if (url == String.Empty)
|
|
||||||
{
|
|
||||||
m_log.Error("[WEBLOADER]: Unable to load webserver URL - URL was empty.");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
while (tries > 0)
|
|
||||||
{
|
|
||||||
RegionInfo[] regionInfos = new RegionInfo[] { };
|
|
||||||
int regionCount = 0;
|
|
||||||
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
|
|
||||||
webRequest.Timeout = 30000; //30 Second Timeout
|
|
||||||
m_log.DebugFormat("[WEBLOADER]: Sending download request to {0}", url);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();
|
|
||||||
m_log.Debug("[WEBLOADER]: Downloading region information...");
|
|
||||||
StreamReader reader = new StreamReader(webResponse.GetResponseStream());
|
|
||||||
string xmlSource = String.Empty;
|
|
||||||
string tempStr = reader.ReadLine();
|
|
||||||
while (tempStr != null)
|
|
||||||
{
|
|
||||||
xmlSource = xmlSource + tempStr;
|
|
||||||
tempStr = reader.ReadLine();
|
|
||||||
}
|
|
||||||
m_log.Debug("[WEBLOADER]: Done downloading region information from server. Total Bytes: " +
|
|
||||||
xmlSource.Length);
|
|
||||||
XmlDocument xmlDoc = new XmlDocument();
|
|
||||||
xmlDoc.LoadXml(xmlSource);
|
|
||||||
if (xmlDoc.FirstChild.Name == "Nini")
|
|
||||||
{
|
|
||||||
regionCount = xmlDoc.FirstChild.ChildNodes.Count;
|
|
||||||
|
|
||||||
if (regionCount > 0)
|
|
||||||
{
|
|
||||||
regionInfos = new RegionInfo[regionCount];
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < xmlDoc.FirstChild.ChildNodes.Count; i++)
|
|
||||||
{
|
|
||||||
m_log.Debug(xmlDoc.FirstChild.ChildNodes[i].OuterXml);
|
|
||||||
regionInfos[i] =
|
|
||||||
new RegionInfo("REGION CONFIG #" + (i + 1), xmlDoc.FirstChild.ChildNodes[i], false, m_configSource);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (WebException ex)
|
|
||||||
{
|
|
||||||
if (((HttpWebResponse)ex.Response).StatusCode == HttpStatusCode.NotFound)
|
|
||||||
{
|
|
||||||
if (!allowRegionless)
|
|
||||||
throw ex;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
throw ex;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (regionCount > 0 || allowRegionless)
|
|
||||||
return regionInfos;
|
|
||||||
|
|
||||||
m_log.Debug("[WEBLOADER]: Request yielded no regions.");
|
|
||||||
tries--;
|
|
||||||
if (tries > 0)
|
|
||||||
{
|
|
||||||
m_log.Debug("[WEBLOADER]: Retrying");
|
|
||||||
System.Threading.Thread.Sleep(wait);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_log.Error("[WEBLOADER]: No region configs were available.");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
using System.Reflection;
|
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using Mono.Addins;
|
|
||||||
|
|
||||||
// General Information about an assembly is controlled through the following
|
|
||||||
// set of attributes. Change these attribute values to modify the information
|
|
||||||
// associated with an assembly.
|
|
||||||
[assembly: AssemblyTitle("OpenSim.ApplicationPlugins.RegionModulesController")]
|
|
||||||
[assembly: AssemblyDescription("")]
|
|
||||||
[assembly: AssemblyConfiguration("")]
|
|
||||||
[assembly: AssemblyCompany("http://opensimulator.org")]
|
|
||||||
[assembly: AssemblyProduct("OpenSim")]
|
|
||||||
[assembly: AssemblyCopyright("OpenSimulator developers")]
|
|
||||||
[assembly: AssemblyTrademark("")]
|
|
||||||
[assembly: AssemblyCulture("")]
|
|
||||||
|
|
||||||
// Setting ComVisible to false makes the types in this assembly not visible
|
|
||||||
// to COM components. If you need to access a type in this assembly from
|
|
||||||
// COM, set the ComVisible attribute to true on that type.
|
|
||||||
[assembly: ComVisible(false)]
|
|
||||||
|
|
||||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
|
||||||
[assembly: Guid("c023816d-194e-40c1-9195-a0f281d4ac5d")]
|
|
||||||
|
|
||||||
// Version information for an assembly consists of the following four values:
|
|
||||||
//
|
|
||||||
// Major Version
|
|
||||||
// Minor Version
|
|
||||||
// Build Number
|
|
||||||
// Revision
|
|
||||||
//
|
|
||||||
[assembly: AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)]
|
|
||||||
|
|
||||||
[assembly: Addin("OpenSim.ApplicationPlugins.RegionModulesController", OpenSim.VersionInfo.VersionNumber)]
|
|
||||||
[assembly: AddinDependency("OpenSim", OpenSim.VersionInfo.VersionNumber)]
|
|
|
@ -1,535 +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.Reflection;
|
|
||||||
using log4net;
|
|
||||||
using Mono.Addins;
|
|
||||||
using Nini.Config;
|
|
||||||
using OpenSim;
|
|
||||||
using OpenSim.Framework;
|
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
|
||||||
using OpenSim.Region.Framework.Scenes;
|
|
||||||
|
|
||||||
namespace OpenSim.ApplicationPlugins.RegionModulesController
|
|
||||||
{
|
|
||||||
[Extension(Path = "/OpenSim/Startup", Id = "LoadRegions", NodeName = "Plugin")]
|
|
||||||
public class RegionModulesControllerPlugin : IRegionModulesController,
|
|
||||||
IApplicationPlugin
|
|
||||||
{
|
|
||||||
// Logger
|
|
||||||
private static readonly ILog m_log =
|
|
||||||
LogManager.GetLogger(
|
|
||||||
MethodBase.GetCurrentMethod().DeclaringType);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Controls whether we load modules from Mono.Addins.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>For debug purposes. Defaults to true.</remarks>
|
|
||||||
public bool LoadModulesFromAddins { get; set; }
|
|
||||||
|
|
||||||
// Config access
|
|
||||||
private OpenSimBase m_openSim;
|
|
||||||
|
|
||||||
// Our name
|
|
||||||
private string m_name;
|
|
||||||
|
|
||||||
// Internal lists to collect information about modules present
|
|
||||||
private List<TypeExtensionNode> m_nonSharedModules =
|
|
||||||
new List<TypeExtensionNode>();
|
|
||||||
private List<TypeExtensionNode> m_sharedModules =
|
|
||||||
new List<TypeExtensionNode>();
|
|
||||||
|
|
||||||
// List of shared module instances, for adding to Scenes
|
|
||||||
private List<ISharedRegionModule> m_sharedInstances =
|
|
||||||
new List<ISharedRegionModule>();
|
|
||||||
|
|
||||||
public RegionModulesControllerPlugin()
|
|
||||||
{
|
|
||||||
LoadModulesFromAddins = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
#region IApplicationPlugin implementation
|
|
||||||
|
|
||||||
public void Initialise (OpenSimBase openSim)
|
|
||||||
{
|
|
||||||
m_openSim = openSim;
|
|
||||||
m_openSim.ApplicationRegistry.RegisterInterface<IRegionModulesController>(this);
|
|
||||||
m_log.DebugFormat("[REGIONMODULES]: Initializing...");
|
|
||||||
|
|
||||||
if (!LoadModulesFromAddins)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Who we are
|
|
||||||
string id = AddinManager.CurrentAddin.Id;
|
|
||||||
|
|
||||||
// Make friendly name
|
|
||||||
int pos = id.LastIndexOf(".");
|
|
||||||
if (pos == -1)
|
|
||||||
m_name = id;
|
|
||||||
else
|
|
||||||
m_name = id.Substring(pos + 1);
|
|
||||||
|
|
||||||
// The [Modules] section in the ini file
|
|
||||||
IConfig modulesConfig =
|
|
||||||
m_openSim.ConfigSource.Source.Configs["Modules"];
|
|
||||||
if (modulesConfig == null)
|
|
||||||
modulesConfig = m_openSim.ConfigSource.Source.AddConfig("Modules");
|
|
||||||
|
|
||||||
Dictionary<RuntimeAddin, IList<int>> loadedModules = new Dictionary<RuntimeAddin, IList<int>>();
|
|
||||||
|
|
||||||
// Scan modules and load all that aren't disabled
|
|
||||||
foreach (TypeExtensionNode node in AddinManager.GetExtensionNodes("/OpenSim/RegionModules"))
|
|
||||||
AddNode(node, modulesConfig, loadedModules);
|
|
||||||
|
|
||||||
foreach (KeyValuePair<RuntimeAddin, IList<int>> loadedModuleData in loadedModules)
|
|
||||||
{
|
|
||||||
m_log.InfoFormat(
|
|
||||||
"[REGIONMODULES]: From plugin {0}, (version {1}), loaded {2} modules, {3} shared, {4} non-shared {5} unknown",
|
|
||||||
loadedModuleData.Key.Id,
|
|
||||||
loadedModuleData.Key.Version,
|
|
||||||
loadedModuleData.Value[0] + loadedModuleData.Value[1] + loadedModuleData.Value[2],
|
|
||||||
loadedModuleData.Value[0], loadedModuleData.Value[1], loadedModuleData.Value[2]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load and init the module. We try a constructor with a port
|
|
||||||
// if a port was given, fall back to one without if there is
|
|
||||||
// no port or the more specific constructor fails.
|
|
||||||
// This will be removed, so that any module capable of using a port
|
|
||||||
// must provide a constructor with a port in the future.
|
|
||||||
// For now, we do this so migration is easy.
|
|
||||||
//
|
|
||||||
foreach (TypeExtensionNode node in m_sharedModules)
|
|
||||||
{
|
|
||||||
Object[] ctorArgs = new Object[] { (uint)0 };
|
|
||||||
|
|
||||||
// Read the config again
|
|
||||||
string moduleString =
|
|
||||||
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
|
|
||||||
if (moduleString != String.Empty)
|
|
||||||
{
|
|
||||||
// Get the port number from the string
|
|
||||||
string[] moduleParts = moduleString.Split(new char[] { '/' },
|
|
||||||
2);
|
|
||||||
if (moduleParts.Length > 1)
|
|
||||||
ctorArgs[0] = Convert.ToUInt32(moduleParts[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try loading and initilaizing the module, using the
|
|
||||||
// port if appropriate
|
|
||||||
ISharedRegionModule module = null;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
module = (ISharedRegionModule)Activator.CreateInstance(
|
|
||||||
node.Type, ctorArgs);
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
module = (ISharedRegionModule)Activator.CreateInstance(
|
|
||||||
node.Type);
|
|
||||||
}
|
|
||||||
|
|
||||||
// OK, we're up and running
|
|
||||||
m_sharedInstances.Add(module);
|
|
||||||
module.Initialise(m_openSim.ConfigSource.Source);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void PostInitialise ()
|
|
||||||
{
|
|
||||||
m_log.DebugFormat("[REGIONMODULES]: PostInitializing...");
|
|
||||||
|
|
||||||
// Immediately run PostInitialise on shared modules
|
|
||||||
foreach (ISharedRegionModule module in m_sharedInstances)
|
|
||||||
{
|
|
||||||
module.PostInitialise();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region IPlugin implementation
|
|
||||||
|
|
||||||
private void AddNode(
|
|
||||||
TypeExtensionNode node, IConfig modulesConfig, Dictionary<RuntimeAddin, IList<int>> loadedModules)
|
|
||||||
{
|
|
||||||
IList<int> loadedModuleData;
|
|
||||||
|
|
||||||
if (!loadedModules.ContainsKey(node.Addin))
|
|
||||||
loadedModules.Add(node.Addin, new List<int> { 0, 0, 0 });
|
|
||||||
|
|
||||||
loadedModuleData = loadedModules[node.Addin];
|
|
||||||
|
|
||||||
if (node.Type.GetInterface(typeof(ISharedRegionModule).ToString()) != null)
|
|
||||||
{
|
|
||||||
if (CheckModuleEnabled(node, modulesConfig))
|
|
||||||
{
|
|
||||||
m_log.DebugFormat("[REGIONMODULES]: Found shared region module {0}, class {1}", node.Id, node.Type);
|
|
||||||
m_sharedModules.Add(node);
|
|
||||||
loadedModuleData[0]++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (node.Type.GetInterface(typeof(INonSharedRegionModule).ToString()) != null)
|
|
||||||
{
|
|
||||||
if (CheckModuleEnabled(node, modulesConfig))
|
|
||||||
{
|
|
||||||
m_log.DebugFormat("[REGIONMODULES]: Found non-shared region module {0}, class {1}", node.Id, node.Type);
|
|
||||||
m_nonSharedModules.Add(node);
|
|
||||||
loadedModuleData[1]++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_log.WarnFormat("[REGIONMODULES]: Found unknown type of module {0}, class {1}", node.Id, node.Type);
|
|
||||||
loadedModuleData[2]++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// We don't do that here
|
|
||||||
//
|
|
||||||
public void Initialise ()
|
|
||||||
{
|
|
||||||
throw new System.NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region IDisposable implementation
|
|
||||||
|
|
||||||
// Cleanup
|
|
||||||
//
|
|
||||||
public void Dispose ()
|
|
||||||
{
|
|
||||||
// We expect that all regions have been removed already
|
|
||||||
while (m_sharedInstances.Count > 0)
|
|
||||||
{
|
|
||||||
m_sharedInstances[0].Close();
|
|
||||||
m_sharedInstances.RemoveAt(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_sharedModules.Clear();
|
|
||||||
m_nonSharedModules.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
public string Version
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return AddinManager.CurrentAddin.Version;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Name
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return m_name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#region Region Module interfacesController implementation
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Check that the given module is no disabled in the [Modules] section of the config files.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="node"></param>
|
|
||||||
/// <param name="modulesConfig">The config section</param>
|
|
||||||
/// <returns>true if the module is enabled, false if it is disabled</returns>
|
|
||||||
protected bool CheckModuleEnabled(TypeExtensionNode node, IConfig modulesConfig)
|
|
||||||
{
|
|
||||||
// Get the config string
|
|
||||||
string moduleString =
|
|
||||||
modulesConfig.GetString("Setup_" + node.Id, String.Empty);
|
|
||||||
|
|
||||||
// We have a selector
|
|
||||||
if (moduleString != String.Empty)
|
|
||||||
{
|
|
||||||
// Allow disabling modules even if they don't have
|
|
||||||
// support for it
|
|
||||||
if (moduleString == "disabled")
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Split off port, if present
|
|
||||||
string[] moduleParts = moduleString.Split(new char[] { '/' }, 2);
|
|
||||||
// Format is [port/][class]
|
|
||||||
string className = moduleParts[0];
|
|
||||||
if (moduleParts.Length > 1)
|
|
||||||
className = moduleParts[1];
|
|
||||||
|
|
||||||
// Match the class name if given
|
|
||||||
if (className != String.Empty &&
|
|
||||||
node.Type.ToString() != className)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The root of all evil.
|
|
||||||
// This is where we handle adding the modules to scenes when they
|
|
||||||
// load. This means that here we deal with replaceable interfaces,
|
|
||||||
// nonshared modules, etc.
|
|
||||||
//
|
|
||||||
public void AddRegionToModules (Scene scene)
|
|
||||||
{
|
|
||||||
Dictionary<Type, ISharedRegionModule> deferredSharedModules =
|
|
||||||
new Dictionary<Type, ISharedRegionModule>();
|
|
||||||
Dictionary<Type, INonSharedRegionModule> deferredNonSharedModules =
|
|
||||||
new Dictionary<Type, INonSharedRegionModule>();
|
|
||||||
|
|
||||||
// We need this to see if a module has already been loaded and
|
|
||||||
// has defined a replaceable interface. It's a generic call,
|
|
||||||
// so this can't be used directly. It will be used later
|
|
||||||
Type s = scene.GetType();
|
|
||||||
MethodInfo mi = s.GetMethod("RequestModuleInterface");
|
|
||||||
|
|
||||||
// This will hold the shared modules we actually load
|
|
||||||
List<ISharedRegionModule> sharedlist =
|
|
||||||
new List<ISharedRegionModule>();
|
|
||||||
|
|
||||||
// Iterate over the shared modules that have been loaded
|
|
||||||
// Add them to the new Scene
|
|
||||||
foreach (ISharedRegionModule module in m_sharedInstances)
|
|
||||||
{
|
|
||||||
// Here is where we check if a replaceable interface
|
|
||||||
// is defined. If it is, the module is checked against
|
|
||||||
// the interfaces already defined. If the interface is
|
|
||||||
// defined, we simply skip the module. Else, if the module
|
|
||||||
// defines a replaceable interface, we add it to the deferred
|
|
||||||
// list.
|
|
||||||
Type replaceableInterface = module.ReplaceableInterface;
|
|
||||||
if (replaceableInterface != null)
|
|
||||||
{
|
|
||||||
MethodInfo mii = mi.MakeGenericMethod(replaceableInterface);
|
|
||||||
|
|
||||||
if (mii.Invoke(scene, new object[0]) != null)
|
|
||||||
{
|
|
||||||
m_log.DebugFormat("[REGIONMODULE]: Not loading {0} because another module has registered {1}", module.Name, replaceableInterface.ToString());
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
deferredSharedModules[replaceableInterface] = module;
|
|
||||||
m_log.DebugFormat("[REGIONMODULE]: Deferred load of {0}", module.Name);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_log.DebugFormat("[REGIONMODULE]: Adding scene {0} to shared module {1}",
|
|
||||||
scene.RegionInfo.RegionName, module.Name);
|
|
||||||
|
|
||||||
module.AddRegion(scene);
|
|
||||||
scene.AddRegionModule(module.Name, module);
|
|
||||||
|
|
||||||
sharedlist.Add(module);
|
|
||||||
}
|
|
||||||
|
|
||||||
IConfig modulesConfig =
|
|
||||||
m_openSim.ConfigSource.Source.Configs["Modules"];
|
|
||||||
|
|
||||||
// Scan for, and load, nonshared modules
|
|
||||||
List<INonSharedRegionModule> list = new List<INonSharedRegionModule>();
|
|
||||||
foreach (TypeExtensionNode node in m_nonSharedModules)
|
|
||||||
{
|
|
||||||
Object[] ctorArgs = new Object[] {0};
|
|
||||||
|
|
||||||
// Read the config
|
|
||||||
string moduleString =
|
|
||||||
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
|
|
||||||
if (moduleString != String.Empty)
|
|
||||||
{
|
|
||||||
// Get the port number from the string
|
|
||||||
string[] moduleParts = moduleString.Split(new char[] {'/'},
|
|
||||||
2);
|
|
||||||
if (moduleParts.Length > 1)
|
|
||||||
ctorArgs[0] = Convert.ToUInt32(moduleParts[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Actually load it
|
|
||||||
INonSharedRegionModule module = null;
|
|
||||||
|
|
||||||
Type[] ctorParamTypes = new Type[ctorArgs.Length];
|
|
||||||
for (int i = 0; i < ctorParamTypes.Length; i++)
|
|
||||||
ctorParamTypes[i] = ctorArgs[i].GetType();
|
|
||||||
|
|
||||||
if (node.Type.GetConstructor(ctorParamTypes) != null)
|
|
||||||
module = (INonSharedRegionModule)Activator.CreateInstance(node.Type, ctorArgs);
|
|
||||||
else
|
|
||||||
module = (INonSharedRegionModule)Activator.CreateInstance(node.Type);
|
|
||||||
|
|
||||||
// Check for replaceable interfaces
|
|
||||||
Type replaceableInterface = module.ReplaceableInterface;
|
|
||||||
if (replaceableInterface != null)
|
|
||||||
{
|
|
||||||
MethodInfo mii = mi.MakeGenericMethod(replaceableInterface);
|
|
||||||
|
|
||||||
if (mii.Invoke(scene, new object[0]) != null)
|
|
||||||
{
|
|
||||||
m_log.DebugFormat("[REGIONMODULE]: Not loading {0} because another module has registered {1}", module.Name, replaceableInterface.ToString());
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
deferredNonSharedModules[replaceableInterface] = module;
|
|
||||||
m_log.DebugFormat("[REGIONMODULE]: Deferred load of {0}", module.Name);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_log.DebugFormat("[REGIONMODULE]: Adding scene {0} to non-shared module {1}",
|
|
||||||
scene.RegionInfo.RegionName, module.Name);
|
|
||||||
|
|
||||||
// Initialise the module
|
|
||||||
module.Initialise(m_openSim.ConfigSource.Source);
|
|
||||||
|
|
||||||
list.Add(module);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now add the modules that we found to the scene. If a module
|
|
||||||
// wishes to override a replaceable interface, it needs to
|
|
||||||
// register it in Initialise, so that the deferred module
|
|
||||||
// won't load.
|
|
||||||
foreach (INonSharedRegionModule module in list)
|
|
||||||
{
|
|
||||||
module.AddRegion(scene);
|
|
||||||
scene.AddRegionModule(module.Name, module);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now all modules without a replaceable base interface are loaded
|
|
||||||
// Replaceable modules have either been skipped, or omitted.
|
|
||||||
// Now scan the deferred modules here
|
|
||||||
foreach (ISharedRegionModule module in deferredSharedModules.Values)
|
|
||||||
{
|
|
||||||
// Determine if the interface has been replaced
|
|
||||||
Type replaceableInterface = module.ReplaceableInterface;
|
|
||||||
MethodInfo mii = mi.MakeGenericMethod(replaceableInterface);
|
|
||||||
|
|
||||||
if (mii.Invoke(scene, new object[0]) != null)
|
|
||||||
{
|
|
||||||
m_log.DebugFormat("[REGIONMODULE]: Not loading {0} because another module has registered {1}", module.Name, replaceableInterface.ToString());
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_log.DebugFormat("[REGIONMODULE]: Adding scene {0} to shared module {1} (deferred)",
|
|
||||||
scene.RegionInfo.RegionName, module.Name);
|
|
||||||
|
|
||||||
// Not replaced, load the module
|
|
||||||
module.AddRegion(scene);
|
|
||||||
scene.AddRegionModule(module.Name, module);
|
|
||||||
|
|
||||||
sharedlist.Add(module);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Same thing for nonshared modules, load them unless overridden
|
|
||||||
List<INonSharedRegionModule> deferredlist =
|
|
||||||
new List<INonSharedRegionModule>();
|
|
||||||
|
|
||||||
foreach (INonSharedRegionModule module in deferredNonSharedModules.Values)
|
|
||||||
{
|
|
||||||
// Check interface override
|
|
||||||
Type replaceableInterface = module.ReplaceableInterface;
|
|
||||||
if (replaceableInterface != null)
|
|
||||||
{
|
|
||||||
MethodInfo mii = mi.MakeGenericMethod(replaceableInterface);
|
|
||||||
|
|
||||||
if (mii.Invoke(scene, new object[0]) != null)
|
|
||||||
{
|
|
||||||
m_log.DebugFormat("[REGIONMODULE]: Not loading {0} because another module has registered {1}", module.Name, replaceableInterface.ToString());
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_log.DebugFormat("[REGIONMODULE]: Adding scene {0} to non-shared module {1} (deferred)",
|
|
||||||
scene.RegionInfo.RegionName, module.Name);
|
|
||||||
|
|
||||||
module.Initialise(m_openSim.ConfigSource.Source);
|
|
||||||
|
|
||||||
list.Add(module);
|
|
||||||
deferredlist.Add(module);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Finally, load valid deferred modules
|
|
||||||
foreach (INonSharedRegionModule module in deferredlist)
|
|
||||||
{
|
|
||||||
module.AddRegion(scene);
|
|
||||||
scene.AddRegionModule(module.Name, module);
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is needed for all module types. Modules will register
|
|
||||||
// Interfaces with scene in AddScene, and will also need a means
|
|
||||||
// to access interfaces registered by other modules. Without
|
|
||||||
// this extra method, a module attempting to use another modules's
|
|
||||||
// interface would be successful only depending on load order,
|
|
||||||
// which can't be depended upon, or modules would need to resort
|
|
||||||
// to ugly kludges to attempt to request interfaces when needed
|
|
||||||
// and unneccessary caching logic repeated in all modules.
|
|
||||||
// The extra function stub is just that much cleaner
|
|
||||||
//
|
|
||||||
foreach (ISharedRegionModule module in sharedlist)
|
|
||||||
{
|
|
||||||
module.RegionLoaded(scene);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (INonSharedRegionModule module in list)
|
|
||||||
{
|
|
||||||
module.RegionLoaded(scene);
|
|
||||||
}
|
|
||||||
|
|
||||||
scene.AllModulesLoaded();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RemoveRegionFromModules (Scene scene)
|
|
||||||
{
|
|
||||||
foreach (IRegionModuleBase module in scene.RegionModules.Values)
|
|
||||||
{
|
|
||||||
m_log.DebugFormat("[REGIONMODULE]: Removing scene {0} from module {1}",
|
|
||||||
scene.RegionInfo.RegionName, module.Name);
|
|
||||||
module.RemoveRegion(scene);
|
|
||||||
if (module is INonSharedRegionModule)
|
|
||||||
{
|
|
||||||
// as we were the only user, this instance has to die
|
|
||||||
module.Close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
scene.RegionModules.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
using System.Reflection;
|
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using Mono.Addins;
|
|
||||||
|
|
||||||
// General Information about an assembly is controlled through the following
|
|
||||||
// set of attributes. Change these attribute values to modify the information
|
|
||||||
// associated with an assembly.
|
|
||||||
[assembly: AssemblyTitle("OpenSim.ApplicationPlugins.RemoteController")]
|
|
||||||
[assembly: AssemblyDescription("")]
|
|
||||||
[assembly: AssemblyConfiguration("")]
|
|
||||||
[assembly: AssemblyCompany("http://opensimulator.org")]
|
|
||||||
[assembly: AssemblyProduct("OpenSim")]
|
|
||||||
[assembly: AssemblyCopyright("Copyright OpenSimulator developers © 2012")]
|
|
||||||
[assembly: AssemblyTrademark("")]
|
|
||||||
[assembly: AssemblyCulture("")]
|
|
||||||
|
|
||||||
// Setting ComVisible to false makes the types in this assembly not visible
|
|
||||||
// to COM components. If you need to access a type in this assembly from
|
|
||||||
// COM, set the ComVisible attribute to true on that type.
|
|
||||||
[assembly: ComVisible(false)]
|
|
||||||
|
|
||||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
|
||||||
[assembly: Guid("efec6e69-fc4a-4e21-86e6-4a261c12d4db")]
|
|
||||||
|
|
||||||
// Version information for an assembly consists of the following four values:
|
|
||||||
//
|
|
||||||
// Major Version
|
|
||||||
// Minor Version
|
|
||||||
// Build Number
|
|
||||||
// Revision
|
|
||||||
//
|
|
||||||
[assembly: AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)]
|
|
||||||
|
|
||||||
[assembly: Addin("OpenSim.ApplicationPlugins.RemoteController", OpenSim.VersionInfo.VersionNumber)]
|
|
||||||
[assembly: AddinDependency("OpenSim", OpenSim.VersionInfo.VersionNumber)]
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,326 +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.Collections.Concurrent;
|
|
||||||
using System.IO;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Threading;
|
|
||||||
using log4net;
|
|
||||||
using Nini.Config;
|
|
||||||
using OpenMetaverse;
|
|
||||||
using OpenSim.Framework.Servers;
|
|
||||||
using OpenSim.Framework.Servers.HttpServer;
|
|
||||||
using OpenSim.Services.Interfaces;
|
|
||||||
|
|
||||||
// using OpenSim.Region.Framework.Interfaces;
|
|
||||||
|
|
||||||
namespace OpenSim.Framework.Capabilities
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// XXX Probably not a particularly nice way of allow us to get the scene presence from the scene (chiefly so that
|
|
||||||
/// we can popup a message on the user's client if the inventory service has permanently failed). But I didn't want
|
|
||||||
/// to just pass the whole Scene into CAPS.
|
|
||||||
/// </summary>
|
|
||||||
public delegate IClientAPI GetClientDelegate(UUID agentID);
|
|
||||||
|
|
||||||
public class Caps : IDisposable
|
|
||||||
{
|
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
|
||||||
|
|
||||||
private string m_httpListenerHostName;
|
|
||||||
private uint m_httpListenPort;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// This is the uuid portion of every CAPS path. It is used to make capability urls private to the requester.
|
|
||||||
/// </summary>
|
|
||||||
private string m_capsObjectPath;
|
|
||||||
public string CapsObjectPath { get { return m_capsObjectPath; } }
|
|
||||||
|
|
||||||
private CapsHandlers m_capsHandlers;
|
|
||||||
|
|
||||||
private ConcurrentDictionary<string, PollServiceEventArgs> m_pollServiceHandlers
|
|
||||||
= new ConcurrentDictionary<string, PollServiceEventArgs>();
|
|
||||||
|
|
||||||
private Dictionary<string, string> m_externalCapsHandlers = new Dictionary<string, string>();
|
|
||||||
|
|
||||||
private IHttpServer m_httpListener;
|
|
||||||
private UUID m_agentID;
|
|
||||||
private string m_regionName;
|
|
||||||
private ManualResetEvent m_capsActive = new ManualResetEvent(false);
|
|
||||||
|
|
||||||
public UUID AgentID
|
|
||||||
{
|
|
||||||
get { return m_agentID; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public string RegionName
|
|
||||||
{
|
|
||||||
get { return m_regionName; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public string HostName
|
|
||||||
{
|
|
||||||
get { return m_httpListenerHostName; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public uint Port
|
|
||||||
{
|
|
||||||
get { return m_httpListenPort; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public IHttpServer HttpListener
|
|
||||||
{
|
|
||||||
get { return m_httpListener; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool SSLCaps
|
|
||||||
{
|
|
||||||
get { return m_httpListener.UseSSL; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public string SSLCommonName
|
|
||||||
{
|
|
||||||
get { return m_httpListener.SSLCommonName; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public CapsHandlers CapsHandlers
|
|
||||||
{
|
|
||||||
get { return m_capsHandlers; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public Dictionary<string, string> 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,
|
|
||||||
UUID agent, string regionName)
|
|
||||||
{
|
|
||||||
m_capsObjectPath = capsPath;
|
|
||||||
m_httpListener = httpServer;
|
|
||||||
m_httpListenerHostName = httpListen;
|
|
||||||
|
|
||||||
m_httpListenPort = httpPort;
|
|
||||||
|
|
||||||
if (httpServer != null && httpServer.UseSSL)
|
|
||||||
{
|
|
||||||
m_httpListenPort = httpServer.SSLPort;
|
|
||||||
httpListen = httpServer.SSLCommonName;
|
|
||||||
httpPort = httpServer.SSLPort;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_agentID = agent;
|
|
||||||
m_capsHandlers = new CapsHandlers(httpServer, httpListen, httpPort);
|
|
||||||
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>
|
|
||||||
/// Register a handler. This allows modules to register handlers.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="capName"></param>
|
|
||||||
/// <param name="handler"></param>
|
|
||||||
public void RegisterHandler(string capName, IRequestHandler handler)
|
|
||||||
{
|
|
||||||
//m_log.DebugFormat("[CAPS]: Registering handler for \"{0}\": path {1}", capName, handler.Path);
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
// m_log.DebugFormat(
|
|
||||||
// "[CAPS]: Registering handler with name {0}, url {1} for {2}",
|
|
||||||
// capName, pollServiceHandler.Url, m_agentID, m_regionName);
|
|
||||||
|
|
||||||
if(!m_pollServiceHandlers.TryAdd(capName, pollServiceHandler))
|
|
||||||
{
|
|
||||||
m_log.ErrorFormat(
|
|
||||||
"[CAPS]: Handler with name {0} already registered (ulr {1}, agent {2}, region {3}",
|
|
||||||
capName, pollServiceHandler.Url, m_agentID, m_regionName);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_httpListener.AddPollServiceHTTPHandler(pollServiceHandler);
|
|
||||||
|
|
||||||
// uint port = (MainServer.Instance == null) ? 0 : MainServer.Instance.Port;
|
|
||||||
// string protocol = "http";
|
|
||||||
// string hostName = m_httpListenerHostName;
|
|
||||||
//
|
|
||||||
// if (MainServer.Instance.UseSSL)
|
|
||||||
// {
|
|
||||||
// hostName = MainServer.Instance.SSLCommonName;
|
|
||||||
// port = MainServer.Instance.SSLPort;
|
|
||||||
// protocol = "https";
|
|
||||||
// }
|
|
||||||
|
|
||||||
// RegisterHandler(
|
|
||||||
// capName, String.Format("{0}://{1}:{2}{3}", protocol, hostName, port, pollServiceHandler.Url));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Register an external handler. The service for this capability is somewhere else
|
|
||||||
/// given by the URL.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="capsName"></param>
|
|
||||||
/// <param name="url"></param>
|
|
||||||
public void RegisterHandler(string capsName, string url)
|
|
||||||
{
|
|
||||||
m_externalCapsHandlers.Add(capsName, url);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Remove all CAPS service handlers.
|
|
||||||
/// </summary>
|
|
||||||
public void DeregisterHandlers()
|
|
||||||
{
|
|
||||||
foreach (string capsName in m_capsHandlers.Caps)
|
|
||||||
{
|
|
||||||
m_capsHandlers.Remove(capsName);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (PollServiceEventArgs handler in m_pollServiceHandlers.Values)
|
|
||||||
{
|
|
||||||
m_httpListener.RemovePollServiceHTTPHandler(handler.Url);
|
|
||||||
}
|
|
||||||
m_pollServiceHandlers.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool TryGetPollHandler(string name, out PollServiceEventArgs pollHandler)
|
|
||||||
{
|
|
||||||
return m_pollServiceHandlers.TryGetValue(name, out pollHandler);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Dictionary<string, PollServiceEventArgs> GetPollHandlers()
|
|
||||||
{
|
|
||||||
return new Dictionary<string, PollServiceEventArgs>(m_pollServiceHandlers);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Return an LLSD-serializable Hashtable describing the
|
|
||||||
/// capabilities and their handler details.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="excludeSeed">If true, then exclude the seed cap.</param>
|
|
||||||
public Hashtable GetCapsDetails(bool excludeSeed, List<string> requestedCaps)
|
|
||||||
{
|
|
||||||
Hashtable caps = CapsHandlers.GetCapsDetails(excludeSeed, requestedCaps);
|
|
||||||
|
|
||||||
lock (m_pollServiceHandlers)
|
|
||||||
{
|
|
||||||
foreach (KeyValuePair <string, PollServiceEventArgs> kvp in m_pollServiceHandlers)
|
|
||||||
{
|
|
||||||
if (!requestedCaps.Contains(kvp.Key))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
string hostName = m_httpListenerHostName;
|
|
||||||
uint port = (MainServer.Instance == null) ? 0 : MainServer.Instance.Port;
|
|
||||||
string protocol = "http";
|
|
||||||
|
|
||||||
if (MainServer.Instance.UseSSL)
|
|
||||||
{
|
|
||||||
hostName = MainServer.Instance.SSLCommonName;
|
|
||||||
port = MainServer.Instance.SSLPort;
|
|
||||||
protocol = "https";
|
|
||||||
}
|
|
||||||
caps[kvp.Key] = string.Format("{0}://{1}:{2}{3}", protocol, hostName, port, kvp.Value.Url);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add the external too
|
|
||||||
foreach (KeyValuePair<string, string> kvp in ExternalCapsHandlers)
|
|
||||||
{
|
|
||||||
if (!requestedCaps.Contains(kvp.Key))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
caps[kvp.Key] = kvp.Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,224 +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;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Collections.Concurrent;
|
|
||||||
using OpenSim.Framework.Servers;
|
|
||||||
using OpenSim.Framework.Servers.HttpServer;
|
|
||||||
|
|
||||||
namespace OpenSim.Framework.Capabilities
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// CapsHandlers is a cap handler container but also takes
|
|
||||||
/// care of adding and removing cap handlers to and from the
|
|
||||||
/// supplied BaseHttpServer.
|
|
||||||
/// </summary>
|
|
||||||
public class CapsHandlers
|
|
||||||
{
|
|
||||||
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 string m_httpListenerHostName;
|
|
||||||
private uint m_httpListenerPort;
|
|
||||||
private bool m_useSSL = 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)
|
|
||||||
{
|
|
||||||
m_httpListener = httpListener;
|
|
||||||
m_httpListenerHostName = httpListenerHostname;
|
|
||||||
m_httpListenerPort = httpListenerPort;
|
|
||||||
if (httpListener != null && httpListener.UseSSL)
|
|
||||||
m_useSSL = true;
|
|
||||||
else
|
|
||||||
m_useSSL = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Remove the cap handler for a capability.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="capsName">name of the capability of the cap
|
|
||||||
/// handler to be removed</param>
|
|
||||||
public void Remove(string capsName)
|
|
||||||
{
|
|
||||||
lock (m_capsHandlers)
|
|
||||||
{
|
|
||||||
if(m_capsHandlers.ContainsKey(capsName))
|
|
||||||
{
|
|
||||||
m_httpListener.RemoveStreamHandler("POST", m_capsHandlers[capsName].Path);
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
lock (m_capsHandlers)
|
|
||||||
if (m_capsHandlers.ContainsKey(cap))
|
|
||||||
return true;
|
|
||||||
return m_capsSimpleHandlers.ContainsKey(cap);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The indexer allows us to treat the CapsHandlers object
|
|
||||||
/// in an intuitive dictionary like way.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// The indexer will throw an exception when you try to
|
|
||||||
/// retrieve a cap handler for a cap that is not contained in
|
|
||||||
/// CapsHandlers.
|
|
||||||
/// </remarks>
|
|
||||||
public IRequestHandler this[string idx]
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
lock (m_capsHandlers)
|
|
||||||
return m_capsHandlers[idx];
|
|
||||||
}
|
|
||||||
|
|
||||||
set
|
|
||||||
{
|
|
||||||
lock (m_capsHandlers)
|
|
||||||
{
|
|
||||||
if (m_capsHandlers.ContainsKey(idx))
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (null == value) return;
|
|
||||||
|
|
||||||
m_capsHandlers[idx] = value;
|
|
||||||
m_httpListener.AddStreamHandler(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Return the list of cap names for which this CapsHandlers
|
|
||||||
/// object contains cap handlers.
|
|
||||||
/// </summary>
|
|
||||||
public string[] Caps
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
lock (m_capsHandlers)
|
|
||||||
{
|
|
||||||
string[] __keys = new string[m_capsHandlers.Keys.Count + m_capsSimpleHandlers.Keys.Count];
|
|
||||||
m_capsHandlers.Keys.CopyTo(__keys, 0);
|
|
||||||
m_capsSimpleHandlers.Keys.CopyTo(__keys, m_capsHandlers.Keys.Count);
|
|
||||||
return __keys;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Return an LLSD-serializable Hashtable describing the
|
|
||||||
/// capabilities and their handler details.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="excludeSeed">If true, then exclude the seed cap.</param>
|
|
||||||
public Hashtable GetCapsDetails(bool excludeSeed, List<string> requestedCaps)
|
|
||||||
{
|
|
||||||
Hashtable caps = new Hashtable();
|
|
||||||
|
|
||||||
string protocol = m_useSSL ? "https://" : "http://";
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
for(int i = 0; i < requestedCaps.Count; ++i)
|
|
||||||
{
|
|
||||||
string capsName = requestedCaps[i];
|
|
||||||
if (excludeSeed && "SEED" == capsName)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (m_capsSimpleHandlers.TryGetValue(capsName, out ISimpleStreamHandler shdr))
|
|
||||||
{
|
|
||||||
caps[capsName] = baseUrl + shdr.Path;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (m_capsHandlers.TryGetValue(capsName, out IRequestHandler chdr))
|
|
||||||
{
|
|
||||||
caps[capsName] = baseUrl + chdr.Path;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return caps;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns a copy of the dictionary of all the HTTP cap handlers
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>
|
|
||||||
/// The dictionary copy. The key is the capability name, the value is the HTTP handler.
|
|
||||||
/// </returns>
|
|
||||||
public Dictionary<string, IRequestHandler> GetCapsHandlers()
|
|
||||||
{
|
|
||||||
lock (m_capsHandlers)
|
|
||||||
return new Dictionary<string, IRequestHandler>(m_capsHandlers);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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,85 +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 Nini.Config;
|
|
||||||
using OpenSim.Server.Base;
|
|
||||||
using OpenSim.Services.Interfaces;
|
|
||||||
using OpenSim.Framework;
|
|
||||||
using OpenSim.Framework.Servers.HttpServer;
|
|
||||||
using OpenSim.Server.Handlers.Base;
|
|
||||||
using OpenMetaverse;
|
|
||||||
using OpenMetaverse.StructuredData;
|
|
||||||
|
|
||||||
|
|
||||||
namespace OpenSim.Capabilities.Handlers
|
|
||||||
{
|
|
||||||
public class FetchInvDescServerConnector : ServiceConnector
|
|
||||||
{
|
|
||||||
private IInventoryService m_InventoryService;
|
|
||||||
private ILibraryService m_LibraryService;
|
|
||||||
private string m_ConfigName = "CapsService";
|
|
||||||
|
|
||||||
public FetchInvDescServerConnector(IConfigSource config, IHttpServer server, string configName) :
|
|
||||||
base(config, server, configName)
|
|
||||||
{
|
|
||||||
if (configName != String.Empty)
|
|
||||||
m_ConfigName = configName;
|
|
||||||
|
|
||||||
IConfig serverConfig = config.Configs[m_ConfigName];
|
|
||||||
if (serverConfig == null)
|
|
||||||
throw new Exception(String.Format("No section '{0}' in config file", m_ConfigName));
|
|
||||||
|
|
||||||
string invService = serverConfig.GetString("InventoryService", String.Empty);
|
|
||||||
|
|
||||||
if (invService == String.Empty)
|
|
||||||
throw new Exception("No InventoryService in config file");
|
|
||||||
|
|
||||||
Object[] args = new Object[] { config };
|
|
||||||
m_InventoryService =
|
|
||||||
ServerUtils.LoadPlugin<IInventoryService>(invService, args);
|
|
||||||
|
|
||||||
if (m_InventoryService == null)
|
|
||||||
throw new Exception(String.Format("Failed to load InventoryService from {0}; config is {1}", invService, m_ConfigName));
|
|
||||||
|
|
||||||
string libService = serverConfig.GetString("LibraryService", String.Empty);
|
|
||||||
m_LibraryService =
|
|
||||||
ServerUtils.LoadPlugin<ILibraryService>(libService, args);
|
|
||||||
|
|
||||||
ExpiringKey<UUID> m_badRequests = new ExpiringKey<UUID>(30000);
|
|
||||||
|
|
||||||
FetchInvDescHandler webFetchHandler = new FetchInvDescHandler(m_InventoryService, m_LibraryService, null);
|
|
||||||
ISimpleStreamHandler reqHandler
|
|
||||||
= new SimpleStreamHandler("/CAPS/WebFetchInvDesc/", delegate(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
|
||||||
{
|
|
||||||
webFetchHandler.FetchInventoryDescendentsRequest(httpRequest, httpResponse, m_badRequests);
|
|
||||||
});
|
|
||||||
|
|
||||||
server.AddSimpleStreamHandler(reqHandler);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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,71 +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 Nini.Config;
|
|
||||||
using OpenSim.Server.Base;
|
|
||||||
using OpenSim.Services.Interfaces;
|
|
||||||
using OpenSim.Framework.Servers.HttpServer;
|
|
||||||
using OpenSim.Server.Handlers.Base;
|
|
||||||
using OpenMetaverse;
|
|
||||||
|
|
||||||
namespace OpenSim.Capabilities.Handlers
|
|
||||||
{
|
|
||||||
public class FetchInventory2ServerConnector : ServiceConnector
|
|
||||||
{
|
|
||||||
private IInventoryService m_InventoryService;
|
|
||||||
private string m_ConfigName = "CapsService";
|
|
||||||
|
|
||||||
public FetchInventory2ServerConnector(IConfigSource config, IHttpServer server, string configName)
|
|
||||||
: base(config, server, configName)
|
|
||||||
{
|
|
||||||
if (configName != String.Empty)
|
|
||||||
m_ConfigName = configName;
|
|
||||||
|
|
||||||
IConfig serverConfig = config.Configs[m_ConfigName];
|
|
||||||
if (serverConfig == null)
|
|
||||||
throw new Exception(String.Format("No section '{0}' in config file", m_ConfigName));
|
|
||||||
|
|
||||||
string invService = serverConfig.GetString("InventoryService", String.Empty);
|
|
||||||
|
|
||||||
if (invService == String.Empty)
|
|
||||||
throw new Exception("No InventoryService in config file");
|
|
||||||
|
|
||||||
Object[] args = new Object[] { config };
|
|
||||||
m_InventoryService = ServerUtils.LoadPlugin<IInventoryService>(invService, args);
|
|
||||||
|
|
||||||
if (m_InventoryService == null)
|
|
||||||
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);
|
|
||||||
IRequestHandler reqHandler
|
|
||||||
= new RestStreamHandler(
|
|
||||||
"POST", "/CAPS/FetchInventory/", fiHandler.FetchInventoryRequest, "FetchInventory", null);
|
|
||||||
server.AddStreamHandler(reqHandler);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,155 +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.Reflection;
|
|
||||||
using System.IO;
|
|
||||||
using System.Web;
|
|
||||||
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 GetMeshHandler
|
|
||||||
{
|
|
||||||
private static readonly ILog m_log =
|
|
||||||
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
|
||||||
|
|
||||||
private IAssetService m_assetService;
|
|
||||||
|
|
||||||
public const string DefaultFormat = "vnd.ll.mesh";
|
|
||||||
|
|
||||||
public GetMeshHandler(IAssetService assService)
|
|
||||||
{
|
|
||||||
m_assetService = assService;
|
|
||||||
}
|
|
||||||
public Hashtable Handle(Hashtable request)
|
|
||||||
{
|
|
||||||
return ProcessGetMesh(request, UUID.Zero, null); ;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Hashtable ProcessGetMesh(Hashtable request, UUID AgentId, Caps cap)
|
|
||||||
{
|
|
||||||
Hashtable responsedata = new Hashtable();
|
|
||||||
if (m_assetService == null)
|
|
||||||
{
|
|
||||||
responsedata["int_response_code"] = (int)System.Net.HttpStatusCode.ServiceUnavailable;
|
|
||||||
responsedata["str_response_string"] = "The asset service is unavailable";
|
|
||||||
responsedata["keepalive"] = false;
|
|
||||||
return responsedata;
|
|
||||||
}
|
|
||||||
|
|
||||||
responsedata["int_response_code"] = (int)System.Net.HttpStatusCode.BadRequest;
|
|
||||||
responsedata["content_type"] = "text/plain";
|
|
||||||
responsedata["int_bytes"] = 0;
|
|
||||||
|
|
||||||
string meshStr = string.Empty;
|
|
||||||
if (request.ContainsKey("mesh_id"))
|
|
||||||
meshStr = request["mesh_id"].ToString();
|
|
||||||
|
|
||||||
if (String.IsNullOrEmpty(meshStr))
|
|
||||||
return responsedata;
|
|
||||||
|
|
||||||
UUID meshID = UUID.Zero;
|
|
||||||
if(!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;
|
|
||||||
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.";
|
|
||||||
return responsedata;
|
|
||||||
}
|
|
||||||
|
|
||||||
end = Utils.Clamp(end, 0, mesh.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);
|
|
||||||
Hashtable headers = new Hashtable();
|
|
||||||
headers["Content-Range"] = String.Format("bytes {0}-{1}/{2}", start, end, mesh.Data.Length);
|
|
||||||
responsedata["headers"] = headers;
|
|
||||||
responsedata["int_response_code"] = (int)System.Net.HttpStatusCode.PartialContent;
|
|
||||||
|
|
||||||
byte[] d = new byte[len];
|
|
||||||
Array.Copy(mesh.Data, start, d, 0, len);
|
|
||||||
responsedata["bin_response_data"] = d;
|
|
||||||
responsedata["int_bytes"] = len;
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,78 +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 Nini.Config;
|
|
||||||
using OpenMetaverse;
|
|
||||||
using OpenSim.Framework.Servers.HttpServer;
|
|
||||||
using OpenSim.Server.Base;
|
|
||||||
using OpenSim.Server.Handlers.Base;
|
|
||||||
using OpenSim.Services.Interfaces;
|
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace OpenSim.Capabilities.Handlers
|
|
||||||
{
|
|
||||||
public class GetMeshServerConnector : ServiceConnector
|
|
||||||
{
|
|
||||||
private IAssetService m_AssetService;
|
|
||||||
private string m_ConfigName = "CapsService";
|
|
||||||
|
|
||||||
public GetMeshServerConnector(IConfigSource config, IHttpServer server, string configName) :
|
|
||||||
base(config, server, configName)
|
|
||||||
{
|
|
||||||
if (configName != String.Empty)
|
|
||||||
m_ConfigName = configName;
|
|
||||||
|
|
||||||
IConfig serverConfig = config.Configs[m_ConfigName];
|
|
||||||
if (serverConfig == null)
|
|
||||||
throw new Exception(String.Format("No section '{0}' in config file", m_ConfigName));
|
|
||||||
|
|
||||||
string assetService = serverConfig.GetString("AssetService", String.Empty);
|
|
||||||
|
|
||||||
if (assetService == String.Empty)
|
|
||||||
throw new Exception("No AssetService in config file");
|
|
||||||
|
|
||||||
Object[] args = new Object[] { config };
|
|
||||||
m_AssetService =
|
|
||||||
ServerUtils.LoadPlugin<IAssetService>(assetService, args);
|
|
||||||
|
|
||||||
if (m_AssetService == null)
|
|
||||||
throw new Exception(String.Format("Failed to load AssetService from {0}; config is {1}", assetService, m_ConfigName));
|
|
||||||
|
|
||||||
string rurl = serverConfig.GetString("GetMeshRedirectURL");
|
|
||||||
|
|
||||||
GetMeshHandler gmeshHandler = new GetMeshHandler(m_AssetService);
|
|
||||||
IRequestHandler reqHandler
|
|
||||||
= new RestHTTPHandler(
|
|
||||||
"GET",
|
|
||||||
"/" + UUID.Random(),
|
|
||||||
httpMethod => gmeshHandler.ProcessGetMesh(httpMethod, UUID.Zero, null),
|
|
||||||
"GetMesh",
|
|
||||||
null);
|
|
||||||
server.AddStreamHandler(reqHandler); ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,365 +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.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 GetTextureHandler
|
|
||||||
{
|
|
||||||
private static readonly ILog m_log =
|
|
||||||
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
|
||||||
|
|
||||||
private IAssetService m_assetService;
|
|
||||||
|
|
||||||
public const string DefaultFormat = "x-j2c";
|
|
||||||
|
|
||||||
public GetTextureHandler(IAssetService assService)
|
|
||||||
{
|
|
||||||
m_assetService = assService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Hashtable Handle(Hashtable request)
|
|
||||||
{
|
|
||||||
Hashtable ret = new Hashtable();
|
|
||||||
ret["int_response_code"] = (int)System.Net.HttpStatusCode.NotFound;
|
|
||||||
ret["content_type"] = "text/plain";
|
|
||||||
ret["int_bytes"] = 0;
|
|
||||||
string textureStr = (string)request["texture_id"];
|
|
||||||
string format = (string)request["format"];
|
|
||||||
|
|
||||||
//m_log.DebugFormat("[GETTEXTURE]: called {0}", textureStr);
|
|
||||||
|
|
||||||
if (m_assetService == null)
|
|
||||||
{
|
|
||||||
m_log.Error("[GETTEXTURE]: Cannot fetch texture " + textureStr + " without an asset service");
|
|
||||||
}
|
|
||||||
|
|
||||||
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 = new string[1] { DefaultFormat }; // default
|
|
||||||
if (((Hashtable)request["headers"])["Accept"] != null)
|
|
||||||
formats = WebUtil.GetPreferredImageTypes((string)((Hashtable)request["headers"])["Accept"]);
|
|
||||||
if (formats.Length == 0)
|
|
||||||
formats = new string[1] { DefaultFormat }; // default
|
|
||||||
|
|
||||||
}
|
|
||||||
// OK, we have an array with preferred formats, possibly with only one entry
|
|
||||||
bool foundtexture = false;
|
|
||||||
foreach (string f in formats)
|
|
||||||
{
|
|
||||||
foundtexture = FetchTexture(request, ret, textureID, f);
|
|
||||||
if (foundtexture)
|
|
||||||
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
|
|
||||||
{
|
|
||||||
m_log.Warn("[GETTEXTURE]: Failed to parse a texture_id from GetTexture request: " + (string)request["uri"]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// m_log.DebugFormat(
|
|
||||||
// "[GETTEXTURE]: For texture {0} sending back response {1}, data length {2}",
|
|
||||||
// textureID, httpResponse.StatusCode, httpResponse.ContentLength);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <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(Hashtable request, Hashtable response, UUID textureID, string format)
|
|
||||||
{
|
|
||||||
// m_log.DebugFormat("[GETTEXTURE]: {0} with requested format {1}", textureID, format);
|
|
||||||
AssetBase texture;
|
|
||||||
|
|
||||||
string fullID = textureID.ToString();
|
|
||||||
if (format != DefaultFormat)
|
|
||||||
fullID = fullID + "-" + format;
|
|
||||||
|
|
||||||
// try the cache
|
|
||||||
texture = m_assetService.GetCached(fullID);
|
|
||||||
|
|
||||||
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)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if (format == DefaultFormat)
|
|
||||||
{
|
|
||||||
WriteTextureData(request, response, 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(request, response, newTexture, format);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else // it was on the cache
|
|
||||||
{
|
|
||||||
//m_log.DebugFormat("[GETTEXTURE]: texture was in the cache");
|
|
||||||
WriteTextureData(request, response, texture, format);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//response = new Hashtable();
|
|
||||||
|
|
||||||
|
|
||||||
//WriteTextureData(request,response,null,format);
|
|
||||||
// not found
|
|
||||||
//m_log.Warn("[GETTEXTURE]: Texture " + textureID + " not found");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void WriteTextureData(Hashtable request, Hashtable response, AssetBase texture, string format)
|
|
||||||
{
|
|
||||||
Hashtable headers = new Hashtable();
|
|
||||||
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
|
|
||||||
{
|
|
||||||
// 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 >= 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;
|
|
||||||
// viewers don't seem to handle RequestedRangeNotSatisfiable and keep retrying with same parameters
|
|
||||||
response["int_response_code"] = (int)System.Net.HttpStatusCode.NotFound;
|
|
||||||
}
|
|
||||||
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);
|
|
||||||
|
|
||||||
response["content-type"] = texture.Metadata.ContentType;
|
|
||||||
response["int_response_code"] = (int)System.Net.HttpStatusCode.PartialContent;
|
|
||||||
headers["Content-Range"] = String.Format("bytes {0}-{1}/{2}", start, end, texture.Data.Length);
|
|
||||||
|
|
||||||
byte[] d = new byte[len];
|
|
||||||
Array.Copy(texture.Data, start, d, 0, len);
|
|
||||||
response["bin_response_data"] = d;
|
|
||||||
response["int_bytes"] = len;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_log.Warn("[GETTEXTURE]: Malformed Range header: " + range);
|
|
||||||
response["int_response_code"] = (int)System.Net.HttpStatusCode.BadRequest;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else // JP2's or other formats
|
|
||||||
{
|
|
||||||
// Full content request
|
|
||||||
response["int_response_code"] = (int)System.Net.HttpStatusCode.OK;
|
|
||||||
if (format == DefaultFormat)
|
|
||||||
response["content_type"] = texture.Metadata.ContentType;
|
|
||||||
else
|
|
||||||
response["content_type"] = "image/" + format;
|
|
||||||
|
|
||||||
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)
|
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,73 +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 Nini.Config;
|
|
||||||
using OpenSim.Server.Base;
|
|
||||||
using OpenSim.Services.Interfaces;
|
|
||||||
using OpenSim.Framework.Servers.HttpServer;
|
|
||||||
using OpenSim.Server.Handlers.Base;
|
|
||||||
using OpenMetaverse;
|
|
||||||
|
|
||||||
|
|
||||||
namespace OpenSim.Capabilities.Handlers
|
|
||||||
{
|
|
||||||
public class GetTextureServerConnector : ServiceConnector
|
|
||||||
{
|
|
||||||
private IAssetService m_AssetService;
|
|
||||||
private string m_ConfigName = "CapsService";
|
|
||||||
|
|
||||||
public GetTextureServerConnector(IConfigSource config, IHttpServer server, string configName) :
|
|
||||||
base(config, server, configName)
|
|
||||||
{
|
|
||||||
if (configName != String.Empty)
|
|
||||||
m_ConfigName = configName;
|
|
||||||
|
|
||||||
IConfig serverConfig = config.Configs[m_ConfigName];
|
|
||||||
if (serverConfig == null)
|
|
||||||
throw new Exception(String.Format("No section '{0}' in config file", m_ConfigName));
|
|
||||||
|
|
||||||
string assetService = serverConfig.GetString("AssetService", String.Empty);
|
|
||||||
|
|
||||||
if (assetService == String.Empty)
|
|
||||||
throw new Exception("No AssetService in config file");
|
|
||||||
|
|
||||||
Object[] args = new Object[] { config };
|
|
||||||
m_AssetService =
|
|
||||||
ServerUtils.LoadPlugin<IAssetService>(assetService, args);
|
|
||||||
|
|
||||||
if (m_AssetService == null)
|
|
||||||
throw new Exception(String.Format("Failed to load AssetService from {0}; config is {1}", assetService, m_ConfigName));
|
|
||||||
|
|
||||||
string rurl = serverConfig.GetString("GetTextureRedirectURL");
|
|
||||||
;
|
|
||||||
server.AddStreamHandler(
|
|
||||||
new GetTextureRobustHandler("/CAPS/GetTexture", m_AssetService, "GetTexture", null, rurl));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,64 +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.Net;
|
|
||||||
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.Tests.Common;
|
|
||||||
|
|
||||||
/*
|
|
||||||
namespace OpenSim.Capabilities.Handlers.GetTexture.Tests
|
|
||||||
{
|
|
||||||
[TestFixture]
|
|
||||||
public class GetTextureHandlerTests : OpenSimTestCase
|
|
||||||
{
|
|
||||||
[Test]
|
|
||||||
public void TestTextureNotFound()
|
|
||||||
{
|
|
||||||
TestHelpers.InMethod();
|
|
||||||
|
|
||||||
// Overkill - we only really need the asset service, not a whole scene.
|
|
||||||
Scene scene = new SceneHelpers().SetupScene();
|
|
||||||
|
|
||||||
GetTextureHandler handler = new GetTextureHandler("/gettexture", scene.AssetService, "TestGetTexture", null, null);
|
|
||||||
TestOSHttpRequest req = new TestOSHttpRequest();
|
|
||||||
TestOSHttpResponse resp = new TestOSHttpResponse();
|
|
||||||
req.Url = new Uri("http://localhost/?texture_id=00000000-0000-1111-9999-000000000012");
|
|
||||||
handler.Handle(null, null, req, resp);
|
|
||||||
Assert.That(resp.StatusCode, Is.EqualTo((int)System.Net.HttpStatusCode.NotFound));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
|
@ -1,33 +0,0 @@
|
||||||
using System.Reflection;
|
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
// General Information about an assembly is controlled through the following
|
|
||||||
// set of attributes. Change these attribute values to modify the information
|
|
||||||
// associated with an assembly.
|
|
||||||
[assembly: AssemblyTitle("OpenSim.Capabilities.Handlers")]
|
|
||||||
[assembly: AssemblyDescription("")]
|
|
||||||
[assembly: AssemblyConfiguration("")]
|
|
||||||
[assembly: AssemblyCompany("http://opensimulator.org")]
|
|
||||||
[assembly: AssemblyProduct("OpenSim")]
|
|
||||||
[assembly: AssemblyCopyright("OpenSimulator developers")]
|
|
||||||
[assembly: AssemblyTrademark("")]
|
|
||||||
[assembly: AssemblyCulture("")]
|
|
||||||
|
|
||||||
// Setting ComVisible to false makes the types in this assembly not visible
|
|
||||||
// to COM components. If you need to access a type in this assembly from
|
|
||||||
// COM, set the ComVisible attribute to true on that type.
|
|
||||||
[assembly: ComVisible(false)]
|
|
||||||
|
|
||||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
|
||||||
[assembly: Guid("32350823-e1df-45e3-b7fa-0a58b4372433")]
|
|
||||||
|
|
||||||
// Version information for an assembly consists of the following four values:
|
|
||||||
//
|
|
||||||
// Major Version
|
|
||||||
// Minor Version
|
|
||||||
// Build Number
|
|
||||||
// Revision
|
|
||||||
//
|
|
||||||
[assembly: AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)]
|
|
||||||
|
|
|
@ -1,41 +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;
|
|
||||||
|
|
||||||
namespace OpenSim.Framework.Capabilities
|
|
||||||
{
|
|
||||||
[LLSDType("ARRAY")]
|
|
||||||
public class OSDArray
|
|
||||||
{
|
|
||||||
public ArrayList Array = new ArrayList();
|
|
||||||
|
|
||||||
public OSDArray()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,52 +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 OpenMetaverse;
|
|
||||||
|
|
||||||
namespace OpenSim.Framework.Capabilities
|
|
||||||
{
|
|
||||||
|
|
||||||
[LLSDType("MAP")]
|
|
||||||
public class LLSDAssetUploadComplete
|
|
||||||
{
|
|
||||||
public string new_asset = String.Empty;
|
|
||||||
public UUID new_inventory_item = UUID.Zero;
|
|
||||||
// public UUID new_texture_folder_id = UUID.Zero;
|
|
||||||
public string state = String.Empty;
|
|
||||||
public LLSDAssetUploadError error = null;
|
|
||||||
//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()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,59 +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 OpenMetaverse;
|
|
||||||
|
|
||||||
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]
|
|
||||||
public class LLSDAssetUploadRequest
|
|
||||||
{
|
|
||||||
public string asset_type = String.Empty;
|
|
||||||
public string description = String.Empty;
|
|
||||||
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 name = String.Empty;
|
|
||||||
public LLSDAssetResource asset_resources = new LLSDAssetResource();
|
|
||||||
public LLSDAssetUploadRequest()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,87 +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 OpenMetaverse;
|
|
||||||
|
|
||||||
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]
|
|
||||||
public class LLSDAssetUploadResponse
|
|
||||||
{
|
|
||||||
public string uploader = String.Empty;
|
|
||||||
public string state = String.Empty;
|
|
||||||
public int upload_price = 0;
|
|
||||||
public LLSDAssetUploadResponseData data = null;
|
|
||||||
public LLSDAssetUploadError error = null;
|
|
||||||
public LLSDAssetUploadResponse()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
[OSDMap]
|
|
||||||
public class LLSDNewFileAngentInventoryVariablePriceReplyResponse
|
|
||||||
{
|
|
||||||
public int resource_cost;
|
|
||||||
public string state;
|
|
||||||
public int upload_price;
|
|
||||||
public string rsvp;
|
|
||||||
|
|
||||||
public LLSDNewFileAngentInventoryVariablePriceReplyResponse()
|
|
||||||
{
|
|
||||||
state = "confirm_upload";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,51 +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 OpenMetaverse;
|
|
||||||
|
|
||||||
namespace OpenSim.Framework.Capabilities
|
|
||||||
{
|
|
||||||
[OSDMap]
|
|
||||||
public class LLSDAvatarPicker
|
|
||||||
{
|
|
||||||
public string next_page_url;
|
|
||||||
// an array of LLSDPerson
|
|
||||||
public OSDArray agents = new OSDArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
[OSDMap]
|
|
||||||
public class LLSDPerson
|
|
||||||
{
|
|
||||||
public string username;
|
|
||||||
public string display_name;
|
|
||||||
//'display_name_next_update':d"1970-01-01T00:00:00Z"
|
|
||||||
public string legacy_first_name;
|
|
||||||
public string legacy_last_name;
|
|
||||||
public UUID id;
|
|
||||||
public bool is_display_name_default;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,40 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace OpenSim.Framework.Capabilities
|
|
||||||
{
|
|
||||||
[LLSDType("MAP")]
|
|
||||||
public class LLSDCapEvent
|
|
||||||
{
|
|
||||||
public int id = 0;
|
|
||||||
public OSDArray events = new OSDArray();
|
|
||||||
|
|
||||||
public LLSDCapEvent()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,37 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace OpenSim.Framework.Capabilities
|
|
||||||
{
|
|
||||||
[LLSDType("MAP")]
|
|
||||||
public class LLSDEmpty
|
|
||||||
{
|
|
||||||
public LLSDEmpty()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,204 +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.IO;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Xml;
|
|
||||||
using OpenMetaverse;
|
|
||||||
|
|
||||||
namespace OpenSim.Framework.Capabilities
|
|
||||||
{
|
|
||||||
public class LLSDHelpers
|
|
||||||
{
|
|
||||||
// private static readonly log4net.ILog m_log
|
|
||||||
// = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
|
||||||
|
|
||||||
public static string SerialiseLLSDReply(object obj)
|
|
||||||
{
|
|
||||||
using(StringWriter sw = new StringWriter())
|
|
||||||
using(XmlTextWriter writer = new XmlTextWriter(sw))
|
|
||||||
{
|
|
||||||
writer.Formatting = Formatting.None;
|
|
||||||
writer.WriteStartElement(String.Empty, "llsd", String.Empty);
|
|
||||||
SerializeOSDType(writer, obj);
|
|
||||||
writer.WriteEndElement();
|
|
||||||
writer.Flush();
|
|
||||||
//m_log.DebugFormat("[LLSD Helpers]: Generated serialized LLSD reply {0}", 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)
|
|
||||||
{
|
|
||||||
Type myType = obj.GetType();
|
|
||||||
LLSDType[] llsdattributes = (LLSDType[]) myType.GetCustomAttributes(typeof (LLSDType), false);
|
|
||||||
if (llsdattributes.Length > 0)
|
|
||||||
{
|
|
||||||
switch (llsdattributes[0].ObjectType)
|
|
||||||
{
|
|
||||||
case "MAP":
|
|
||||||
writer.WriteStartElement(String.Empty, "map", String.Empty);
|
|
||||||
FieldInfo[] fields = myType.GetFields();
|
|
||||||
for (int i = 0; i < fields.Length; i++)
|
|
||||||
{
|
|
||||||
if (fields[i] != null && fields[i].GetValue(obj) != null)
|
|
||||||
{
|
|
||||||
object fieldValue = fields[i].GetValue(obj);
|
|
||||||
LLSDType[] fieldAttributes =
|
|
||||||
(LLSDType[]) fieldValue.GetType().GetCustomAttributes(typeof (LLSDType), false);
|
|
||||||
if (fieldAttributes.Length > 0)
|
|
||||||
{
|
|
||||||
writer.WriteStartElement(String.Empty, "key", String.Empty);
|
|
||||||
string fieldName = fields[i].Name;
|
|
||||||
fieldName = fieldName.Replace("___", "-");
|
|
||||||
writer.WriteString(fieldName);
|
|
||||||
writer.WriteEndElement();
|
|
||||||
SerializeOSDType(writer, fieldValue);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
writer.WriteStartElement(String.Empty, "key", String.Empty);
|
|
||||||
string fieldName = fields[i].Name;
|
|
||||||
fieldName = fieldName.Replace("___", "-");
|
|
||||||
writer.WriteString(fieldName);
|
|
||||||
writer.WriteEndElement();
|
|
||||||
LLSD.LLSDWriteOne(writer, fieldValue);
|
|
||||||
// OpenMetaverse.StructuredData.LLSDParser.SerializeXmlElement(
|
|
||||||
// writer, OpenMetaverse.StructuredData.OSD.FromObject(fieldValue));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// TODO from ADAM: There is a nullref being caused by fields[i] being null
|
|
||||||
// on some computers. Unsure what is causing this, but would appreciate
|
|
||||||
// if sdague could take a look at this.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
writer.WriteEndElement();
|
|
||||||
break;
|
|
||||||
case "ARRAY":
|
|
||||||
// OSDArray arrayObject = obj as OSDArray;
|
|
||||||
// ArrayList a = arrayObject.Array;
|
|
||||||
ArrayList a = (ArrayList) obj.GetType().GetField("Array").GetValue(obj);
|
|
||||||
if (a != null)
|
|
||||||
{
|
|
||||||
writer.WriteStartElement(String.Empty, "array", String.Empty);
|
|
||||||
foreach (object item in a)
|
|
||||||
{
|
|
||||||
SerializeOSDType(writer, item);
|
|
||||||
}
|
|
||||||
writer.WriteEndElement();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LLSD.LLSDWriteOne(writer, obj);
|
|
||||||
//OpenMetaverse.StructuredData.LLSDParser.SerializeXmlElement(
|
|
||||||
// writer, OpenMetaverse.StructuredData.OSD.FromObject(obj));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static object DeserialiseOSDMap(Hashtable llsd, object obj)
|
|
||||||
{
|
|
||||||
Type myType = obj.GetType();
|
|
||||||
LLSDType[] llsdattributes = (LLSDType[]) myType.GetCustomAttributes(typeof (LLSDType), false);
|
|
||||||
if (llsdattributes.Length > 0)
|
|
||||||
{
|
|
||||||
switch (llsdattributes[0].ObjectType)
|
|
||||||
{
|
|
||||||
case "MAP":
|
|
||||||
IDictionaryEnumerator enumerator = llsd.GetEnumerator();
|
|
||||||
while (enumerator.MoveNext())
|
|
||||||
{
|
|
||||||
string keyName = (string)enumerator.Key;
|
|
||||||
keyName = keyName.Replace("-","_");
|
|
||||||
FieldInfo field = myType.GetField(keyName);
|
|
||||||
if (field != null)
|
|
||||||
{
|
|
||||||
// if (enumerator.Value is OpenMetaverse.StructuredData.OSDMap)
|
|
||||||
if (enumerator.Value is Hashtable)
|
|
||||||
{
|
|
||||||
object fieldValue = field.GetValue(obj);
|
|
||||||
DeserialiseOSDMap((Hashtable) enumerator.Value, fieldValue);
|
|
||||||
// DeserialiseOSDMap((OpenMetaverse.StructuredData.OSDMap) enumerator.Value, fieldValue);
|
|
||||||
}
|
|
||||||
else if (enumerator.Value is ArrayList)
|
|
||||||
{
|
|
||||||
object fieldValue = field.GetValue(obj);
|
|
||||||
fieldValue.GetType().GetField("Array").SetValue(fieldValue, enumerator.Value);
|
|
||||||
//TODO
|
|
||||||
// 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.
|
|
||||||
}
|
|
||||||
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
|
|
||||||
{
|
|
||||||
field.SetValue(obj, enumerator.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,42 +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 OpenMetaverse;
|
|
||||||
|
|
||||||
namespace OpenSim.Framework.Capabilities
|
|
||||||
{
|
|
||||||
[OSDMap]
|
|
||||||
public class LLSDInventoryFolder
|
|
||||||
{
|
|
||||||
public UUID folder_id;
|
|
||||||
public UUID parent_id;
|
|
||||||
public string name;
|
|
||||||
public int type;
|
|
||||||
public int preferred_type;
|
|
||||||
public int version;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,105 +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 OpenMetaverse;
|
|
||||||
|
|
||||||
namespace OpenSim.Framework.Capabilities
|
|
||||||
{
|
|
||||||
[OSDMap]
|
|
||||||
public class LLSDInventoryItem
|
|
||||||
{
|
|
||||||
public UUID parent_id;
|
|
||||||
|
|
||||||
public UUID asset_id;
|
|
||||||
public UUID item_id;
|
|
||||||
public LLSDPermissions permissions;
|
|
||||||
public int type;
|
|
||||||
public int inv_type;
|
|
||||||
public int flags;
|
|
||||||
|
|
||||||
public LLSDSaleInfo sale_info;
|
|
||||||
public string name;
|
|
||||||
public string desc;
|
|
||||||
public int created_at;
|
|
||||||
}
|
|
||||||
|
|
||||||
[OSDMap]
|
|
||||||
public class LLSDPermissions
|
|
||||||
{
|
|
||||||
public UUID creator_id;
|
|
||||||
public UUID owner_id;
|
|
||||||
public UUID group_id;
|
|
||||||
public int base_mask;
|
|
||||||
public int owner_mask;
|
|
||||||
public int group_mask;
|
|
||||||
public int everyone_mask;
|
|
||||||
public int next_owner_mask;
|
|
||||||
public bool is_owner_group;
|
|
||||||
}
|
|
||||||
|
|
||||||
[OSDMap]
|
|
||||||
public class LLSDSaleInfo
|
|
||||||
{
|
|
||||||
public int sale_price;
|
|
||||||
public int sale_type;
|
|
||||||
}
|
|
||||||
|
|
||||||
[OSDMap]
|
|
||||||
public class LLSDInventoryDescendents
|
|
||||||
{
|
|
||||||
public OSDArray folders = new OSDArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
[OSDMap]
|
|
||||||
public class LLSDFetchInventoryDescendents
|
|
||||||
{
|
|
||||||
public UUID folder_id;
|
|
||||||
public UUID owner_id;
|
|
||||||
public int sort_order;
|
|
||||||
public bool fetch_folders;
|
|
||||||
public bool fetch_items;
|
|
||||||
}
|
|
||||||
|
|
||||||
[OSDMap]
|
|
||||||
public class LLSDInventoryFolderContents
|
|
||||||
{
|
|
||||||
public UUID agent_id;
|
|
||||||
public int descendents;
|
|
||||||
public UUID folder_id;
|
|
||||||
public OSDArray categories = new OSDArray();
|
|
||||||
public OSDArray items = new OSDArray();
|
|
||||||
public UUID owner_id;
|
|
||||||
public int version;
|
|
||||||
}
|
|
||||||
|
|
||||||
[OSDMap]
|
|
||||||
public class LLSDFetchInventory
|
|
||||||
{
|
|
||||||
public UUID agent_id;
|
|
||||||
public OSDArray items = new OSDArray();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,45 +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 OpenMetaverse;
|
|
||||||
|
|
||||||
namespace OpenSim.Framework.Capabilities
|
|
||||||
{
|
|
||||||
[LLSDType("MAP")]
|
|
||||||
public class OSDMapLayer
|
|
||||||
{
|
|
||||||
public int Left = 0;
|
|
||||||
public int Right = 0;
|
|
||||||
public int Top = 0;
|
|
||||||
public int Bottom = 0;
|
|
||||||
public UUID ImageID = UUID.Zero;
|
|
||||||
|
|
||||||
public OSDMapLayer()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,40 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace OpenSim.Framework.Capabilities
|
|
||||||
{
|
|
||||||
[LLSDType("MAP")]
|
|
||||||
public class LLSDMapLayerResponse
|
|
||||||
{
|
|
||||||
public LLSDMapRequest AgentData = new LLSDMapRequest();
|
|
||||||
public OSDArray LayerData = new OSDArray();
|
|
||||||
|
|
||||||
public LLSDMapLayerResponse()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,39 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace OpenSim.Framework.Capabilities
|
|
||||||
{
|
|
||||||
[LLSDType("MAP")]
|
|
||||||
public class LLSDMapRequest
|
|
||||||
{
|
|
||||||
public int Flags = 0;
|
|
||||||
|
|
||||||
public LLSDMapRequest()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,31 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace OpenSim.Framework.Capabilities
|
|
||||||
{
|
|
||||||
public delegate TResponse LLSDMethod<TRequest, TResponse>(TRequest request);
|
|
||||||
}
|
|
|
@ -1,31 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace OpenSim.Framework.Capabilities
|
|
||||||
{
|
|
||||||
public delegate TResponse LLSDMethodString<TRequest, TResponse>(TRequest request, string path);
|
|
||||||
}
|
|
|
@ -1,75 +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;
|
|
||||||
using System.IO;
|
|
||||||
using System.Text;
|
|
||||||
using OpenSim.Framework.Servers;
|
|
||||||
using OpenSim.Framework.Servers.HttpServer;
|
|
||||||
|
|
||||||
namespace OpenSim.Framework.Capabilities
|
|
||||||
{
|
|
||||||
public class LLSDStreamhandler<TRequest, TResponse> : BaseStreamHandler
|
|
||||||
where TRequest : new()
|
|
||||||
{
|
|
||||||
private LLSDMethod<TRequest, TResponse> m_method;
|
|
||||||
|
|
||||||
public LLSDStreamhandler(string httpMethod, string path, LLSDMethod<TRequest, TResponse> method)
|
|
||||||
: this(httpMethod, path, method, null, null) {}
|
|
||||||
|
|
||||||
public LLSDStreamhandler(
|
|
||||||
string httpMethod, string path, LLSDMethod<TRequest, TResponse> method, string name, string description)
|
|
||||||
: base(httpMethod, path, name, description)
|
|
||||||
{
|
|
||||||
m_method = method;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override byte[] ProcessRequest(string path, Stream request,
|
|
||||||
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
|
||||||
{
|
|
||||||
//Encoding encoding = Util.UTF8;
|
|
||||||
//StreamReader streamReader = new StreamReader(request, false);
|
|
||||||
|
|
||||||
//string requestBody = streamReader.ReadToEnd();
|
|
||||||
//streamReader.Close();
|
|
||||||
|
|
||||||
// OpenMetaverse.StructuredData.OSDMap hash = (OpenMetaverse.StructuredData.OSDMap)
|
|
||||||
// OpenMetaverse.StructuredData.LLSDParser.DeserializeXml(new XmlTextReader(request));
|
|
||||||
|
|
||||||
Hashtable hash = (Hashtable) LLSD.LLSDDeserialize(request);
|
|
||||||
if(hash == null)
|
|
||||||
return new byte[0];
|
|
||||||
|
|
||||||
TRequest llsdRequest = new TRequest();
|
|
||||||
LLSDHelpers.DeserialiseOSDMap(hash, llsdRequest);
|
|
||||||
|
|
||||||
TResponse response = m_method(llsdRequest);
|
|
||||||
|
|
||||||
return Util.UTF8NoBomEncoding.GetBytes(LLSDHelpers.SerialiseLLSDReply(response));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,50 +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 OpenMetaverse;
|
|
||||||
|
|
||||||
namespace OpenSim.Framework.Capabilities
|
|
||||||
{
|
|
||||||
[OSDMap]
|
|
||||||
public class LLSDTaskInventoryUploadComplete
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The task inventory item that was updated
|
|
||||||
/// </summary>
|
|
||||||
public UUID item_id;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The task that was updated
|
|
||||||
/// </summary>
|
|
||||||
public UUID task_id;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// State of the upload. So far have only even seen this set to "complete"
|
|
||||||
/// </summary>
|
|
||||||
public string state;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,54 +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 OpenMetaverse;
|
|
||||||
using System;
|
|
||||||
using System.Collections;
|
|
||||||
|
|
||||||
namespace OpenSim.Framework.Capabilities
|
|
||||||
{
|
|
||||||
[OSDMap]
|
|
||||||
public class LLSDTaskScriptUploadComplete
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The task inventory item that was updated
|
|
||||||
/// </summary>
|
|
||||||
public UUID new_asset;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Was it compiled?
|
|
||||||
/// </summary>
|
|
||||||
public bool compiled;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// State of the upload. So far have only even seen this set to "complete"
|
|
||||||
/// </summary>
|
|
||||||
public string state;
|
|
||||||
|
|
||||||
public OSDArray errors;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,40 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace OpenSim.Framework.Capabilities
|
|
||||||
{
|
|
||||||
[LLSDType("MAP")]
|
|
||||||
public class LLSDTest
|
|
||||||
{
|
|
||||||
public int Test1 = 20;
|
|
||||||
public int Test2 = 10;
|
|
||||||
|
|
||||||
public LLSDTest()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,55 +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;
|
|
||||||
|
|
||||||
namespace OpenSim.Framework.Capabilities
|
|
||||||
{
|
|
||||||
[AttributeUsage(AttributeTargets.Class)]
|
|
||||||
public class LLSDType : Attribute
|
|
||||||
{
|
|
||||||
protected string myType;
|
|
||||||
|
|
||||||
public LLSDType(string type)
|
|
||||||
{
|
|
||||||
myType = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string ObjectType
|
|
||||||
{
|
|
||||||
get { return myType; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Class)]
|
|
||||||
public class OSDMap : LLSDType
|
|
||||||
{
|
|
||||||
public OSDMap() : base("MAP")
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,33 +0,0 @@
|
||||||
using System.Reflection;
|
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
// General Information about an assembly is controlled through the following
|
|
||||||
// set of attributes. Change these attribute values to modify the information
|
|
||||||
// associated with an assembly.
|
|
||||||
[assembly: AssemblyTitle("OpenSim.Capabilities")]
|
|
||||||
[assembly: AssemblyDescription("")]
|
|
||||||
[assembly: AssemblyConfiguration("")]
|
|
||||||
[assembly: AssemblyCompany("http://opensimulator.org")]
|
|
||||||
[assembly: AssemblyProduct("OpenSim")]
|
|
||||||
[assembly: AssemblyCopyright("OpenSimulator developers")]
|
|
||||||
[assembly: AssemblyTrademark("")]
|
|
||||||
[assembly: AssemblyCulture("")]
|
|
||||||
|
|
||||||
// Setting ComVisible to false makes the types in this assembly not visible
|
|
||||||
// to COM components. If you need to access a type in this assembly from
|
|
||||||
// COM, set the ComVisible attribute to true on that type.
|
|
||||||
[assembly: ComVisible(false)]
|
|
||||||
|
|
||||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
|
||||||
[assembly: Guid("7d1a55b1-8fab-42ff-9c83-066a9cc34d76")]
|
|
||||||
|
|
||||||
// Version information for an assembly consists of the following four values:
|
|
||||||
//
|
|
||||||
// Major Version
|
|
||||||
// Minor Version
|
|
||||||
// Build Number
|
|
||||||
// Revision
|
|
||||||
//
|
|
||||||
[assembly: AssemblyVersion("0.7.6.*")]
|
|
||||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
|
|
@ -1,225 +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 Nini.Config;
|
|
||||||
using log4net;
|
|
||||||
using System.Reflection;
|
|
||||||
using System;
|
|
||||||
using System.IO;
|
|
||||||
using System.Xml;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using OpenSim.Server.Base;
|
|
||||||
using OpenSim.Framework;
|
|
||||||
using OpenSim.Framework.Console;
|
|
||||||
using OpenMetaverse;
|
|
||||||
|
|
||||||
namespace OpenSim.ConsoleClient
|
|
||||||
{
|
|
||||||
public class OpenSimConsoleClient
|
|
||||||
{
|
|
||||||
protected static ServicesServerBase m_Server = null;
|
|
||||||
private static string m_Host;
|
|
||||||
private static int m_Port;
|
|
||||||
private static string m_User;
|
|
||||||
private static string m_Pass;
|
|
||||||
private static UUID m_SessionID;
|
|
||||||
|
|
||||||
static int Main(string[] args)
|
|
||||||
{
|
|
||||||
m_Server = new ServicesServerBase("Client", args);
|
|
||||||
|
|
||||||
IConfig serverConfig = m_Server.Config.Configs["Startup"];
|
|
||||||
if (serverConfig == null)
|
|
||||||
{
|
|
||||||
System.Console.WriteLine("Startup config section missing in .ini file");
|
|
||||||
throw new Exception("Configuration error");
|
|
||||||
}
|
|
||||||
|
|
||||||
ArgvConfigSource argvConfig = new ArgvConfigSource(args);
|
|
||||||
|
|
||||||
argvConfig.AddSwitch("Startup", "host", "h");
|
|
||||||
argvConfig.AddSwitch("Startup", "port", "p");
|
|
||||||
argvConfig.AddSwitch("Startup", "user", "u");
|
|
||||||
argvConfig.AddSwitch("Startup", "pass", "P");
|
|
||||||
|
|
||||||
m_Server.Config.Merge(argvConfig);
|
|
||||||
|
|
||||||
m_User = serverConfig.GetString("user", "Test");
|
|
||||||
m_Host = serverConfig.GetString("host", "localhost");
|
|
||||||
m_Port = serverConfig.GetInt("port", 8003);
|
|
||||||
m_Pass = serverConfig.GetString("pass", "secret");
|
|
||||||
|
|
||||||
Requester.MakeRequest("http://"+m_Host+":"+m_Port.ToString()+"/StartSession/", String.Format("USER={0}&PASS={1}", m_User, m_Pass), LoginReply);
|
|
||||||
|
|
||||||
string pidFile = serverConfig.GetString("PIDFile", String.Empty);
|
|
||||||
|
|
||||||
while (m_Server.Running)
|
|
||||||
{
|
|
||||||
System.Threading.Thread.Sleep(500);
|
|
||||||
MainConsole.Instance.Prompt();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pidFile != String.Empty)
|
|
||||||
File.Delete(pidFile);
|
|
||||||
|
|
||||||
Environment.Exit(0);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void SendCommand(string module, string[] cmd)
|
|
||||||
{
|
|
||||||
string sendCmd = "";
|
|
||||||
string[] cmdlist = new string[cmd.Length - 1];
|
|
||||||
|
|
||||||
sendCmd = cmd[0];
|
|
||||||
|
|
||||||
if (cmd.Length > 1)
|
|
||||||
{
|
|
||||||
Array.Copy(cmd, 1, cmdlist, 0, cmd.Length - 1);
|
|
||||||
sendCmd += " \"" + String.Join("\" \"", cmdlist) + "\"";
|
|
||||||
}
|
|
||||||
|
|
||||||
Requester.MakeRequest("http://"+m_Host+":"+m_Port.ToString()+"/SessionCommand/", String.Format("ID={0}&COMMAND={1}", m_SessionID, sendCmd), CommandReply);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void LoginReply(string requestUrl, string requestData, string replyData)
|
|
||||||
{
|
|
||||||
XmlDocument doc = new XmlDocument();
|
|
||||||
|
|
||||||
doc.LoadXml(replyData);
|
|
||||||
|
|
||||||
XmlNodeList rootL = doc.GetElementsByTagName("ConsoleSession");
|
|
||||||
if (rootL.Count != 1)
|
|
||||||
{
|
|
||||||
MainConsole.Instance.Output("Connection data info was not valid");
|
|
||||||
Environment.Exit(1);
|
|
||||||
}
|
|
||||||
XmlElement rootNode = (XmlElement)rootL[0];
|
|
||||||
|
|
||||||
if (rootNode == null)
|
|
||||||
{
|
|
||||||
MainConsole.Instance.Output("Connection data info was not valid");
|
|
||||||
Environment.Exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
XmlNodeList helpNodeL = rootNode.GetElementsByTagName("HelpTree");
|
|
||||||
if (helpNodeL.Count != 1)
|
|
||||||
{
|
|
||||||
MainConsole.Instance.Output("Connection data info was not valid");
|
|
||||||
Environment.Exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
XmlElement helpNode = (XmlElement)helpNodeL[0];
|
|
||||||
if (helpNode == null)
|
|
||||||
{
|
|
||||||
MainConsole.Instance.Output("Connection data info was not valid");
|
|
||||||
Environment.Exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
XmlNodeList sessionL = rootNode.GetElementsByTagName("SessionID");
|
|
||||||
if (sessionL.Count != 1)
|
|
||||||
{
|
|
||||||
MainConsole.Instance.Output("Connection data info was not valid");
|
|
||||||
Environment.Exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
XmlElement sessionNode = (XmlElement)sessionL[0];
|
|
||||||
if (sessionNode == null)
|
|
||||||
{
|
|
||||||
MainConsole.Instance.Output("Connection data info was not valid");
|
|
||||||
Environment.Exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!UUID.TryParse(sessionNode.InnerText, out m_SessionID))
|
|
||||||
{
|
|
||||||
MainConsole.Instance.Output("Connection data info was not valid");
|
|
||||||
Environment.Exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
MainConsole.Instance.Commands.FromXml(helpNode, SendCommand);
|
|
||||||
|
|
||||||
Requester.MakeRequest("http://"+m_Host+":"+m_Port.ToString()+"/ReadResponses/"+m_SessionID.ToString()+"/", String.Empty, ReadResponses);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void ReadResponses(string requestUrl, string requestData, string replyData)
|
|
||||||
{
|
|
||||||
XmlDocument doc = new XmlDocument();
|
|
||||||
|
|
||||||
doc.LoadXml(replyData);
|
|
||||||
|
|
||||||
XmlNodeList rootNodeL = doc.GetElementsByTagName("ConsoleSession");
|
|
||||||
if (rootNodeL.Count != 1 || rootNodeL[0] == null)
|
|
||||||
{
|
|
||||||
Requester.MakeRequest(requestUrl, requestData, ReadResponses);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<string> lines = new List<string>();
|
|
||||||
|
|
||||||
foreach (XmlNode part in rootNodeL[0].ChildNodes)
|
|
||||||
{
|
|
||||||
if (part.Name != "Line")
|
|
||||||
continue;
|
|
||||||
|
|
||||||
lines.Add(part.InnerText);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cut down scrollback to 100 lines (4 screens)
|
|
||||||
// for the command line client
|
|
||||||
//
|
|
||||||
while (lines.Count > 100)
|
|
||||||
lines.RemoveAt(0);
|
|
||||||
|
|
||||||
string prompt = String.Empty;
|
|
||||||
|
|
||||||
foreach (string l in lines)
|
|
||||||
{
|
|
||||||
string[] parts = l.Split(new char[] {':'}, 3);
|
|
||||||
if (parts.Length != 3)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (parts[2].StartsWith("+++") || parts[2].StartsWith("-++"))
|
|
||||||
prompt = parts[2];
|
|
||||||
else
|
|
||||||
MainConsole.Instance.Output(parts[2].Trim(), parts[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Requester.MakeRequest(requestUrl, requestData, ReadResponses);
|
|
||||||
|
|
||||||
if (prompt.StartsWith("+++"))
|
|
||||||
MainConsole.Instance.ReadLine(prompt.Substring(3), true, true);
|
|
||||||
else if (prompt.StartsWith("-++"))
|
|
||||||
SendCommand(String.Empty, new string[] { MainConsole.Instance.ReadLine(prompt.Substring(3), false, true) });
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void CommandReply(string requestUrl, string requestData, string replyData)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,33 +0,0 @@
|
||||||
using System.Reflection;
|
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
// General Information about an assembly is controlled through the following
|
|
||||||
// set of attributes. Change these attribute values to modify the information
|
|
||||||
// associated with an assembly.
|
|
||||||
[assembly: AssemblyTitle("OpenSim.ConsoleClient")]
|
|
||||||
[assembly: AssemblyDescription("")]
|
|
||||||
[assembly: AssemblyConfiguration("")]
|
|
||||||
[assembly: AssemblyCompany("http://opensimulator.org")]
|
|
||||||
[assembly: AssemblyProduct("OpenSim")]
|
|
||||||
[assembly: AssemblyCopyright("OpenSimulator developers")]
|
|
||||||
[assembly: AssemblyTrademark("")]
|
|
||||||
[assembly: AssemblyCulture("")]
|
|
||||||
|
|
||||||
// Setting ComVisible to false makes the types in this assembly not visible
|
|
||||||
// to COM components. If you need to access a type in this assembly from
|
|
||||||
// COM, set the ComVisible attribute to true on that type.
|
|
||||||
[assembly: ComVisible(false)]
|
|
||||||
|
|
||||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
|
||||||
[assembly: Guid("8945df94-2e5e-475b-88fa-35a7cdde6fd7")]
|
|
||||||
|
|
||||||
// Version information for an assembly consists of the following four values:
|
|
||||||
//
|
|
||||||
// Major Version
|
|
||||||
// Minor Version
|
|
||||||
// Build Number
|
|
||||||
// Revision
|
|
||||||
//
|
|
||||||
[assembly: AssemblyVersion("0.7.6.*")]
|
|
||||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
|
|
@ -1,85 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
* * Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* * Neither the name of the OpenSimulator Project nor the
|
|
||||||
* names of its contributors may be used to endorse or promote products
|
|
||||||
* derived from this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
|
||||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.IO;
|
|
||||||
using System.Net;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Text;
|
|
||||||
using System.Xml;
|
|
||||||
using System.Xml.Serialization;
|
|
||||||
using log4net;
|
|
||||||
|
|
||||||
namespace OpenSim.ConsoleClient
|
|
||||||
{
|
|
||||||
public delegate void ReplyDelegate(string requestUrl, string requestData, string replyData);
|
|
||||||
|
|
||||||
public class Requester
|
|
||||||
{
|
|
||||||
public static void MakeRequest(string requestUrl, string data,
|
|
||||||
ReplyDelegate action)
|
|
||||||
{
|
|
||||||
WebRequest request = WebRequest.Create(requestUrl);
|
|
||||||
|
|
||||||
request.Method = "POST";
|
|
||||||
|
|
||||||
request.ContentType = "application/x-www-form-urlencoded";
|
|
||||||
|
|
||||||
byte[] buffer = Encoding.ASCII.GetBytes(data);
|
|
||||||
int length = (int) buffer.Length;
|
|
||||||
request.ContentLength = length;
|
|
||||||
|
|
||||||
request.BeginGetRequestStream(delegate(IAsyncResult res)
|
|
||||||
{
|
|
||||||
Stream requestStream = request.EndGetRequestStream(res);
|
|
||||||
|
|
||||||
requestStream.Write(buffer, 0, length);
|
|
||||||
|
|
||||||
request.BeginGetResponse(delegate(IAsyncResult ar)
|
|
||||||
{
|
|
||||||
string reply = String.Empty;
|
|
||||||
|
|
||||||
using (WebResponse response = request.EndGetResponse(ar))
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
using (Stream s = response.GetResponseStream())
|
|
||||||
using (StreamReader r = new StreamReader(s))
|
|
||||||
reply = r.ReadToEnd();
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (System.InvalidOperationException)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
action(requestUrl, data, reply);
|
|
||||||
}, null);
|
|
||||||
}, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,52 +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.Text;
|
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using OpenMetaverse;
|
|
||||||
using OpenSim.Framework;
|
|
||||||
|
|
||||||
namespace OpenSim.Data
|
|
||||||
{
|
|
||||||
public abstract class AssetDataBase : IAssetDataPlugin
|
|
||||||
{
|
|
||||||
public abstract AssetBase GetAsset(UUID uuid);
|
|
||||||
public abstract bool StoreAsset(AssetBase asset);
|
|
||||||
public abstract bool[] AssetsExist(UUID[] uuids);
|
|
||||||
|
|
||||||
public abstract List<AssetMetadata> FetchAssetMetadataSet(int start, int count);
|
|
||||||
|
|
||||||
public abstract string Version { get; }
|
|
||||||
public abstract string Name { get; }
|
|
||||||
public abstract void Initialise(string connect);
|
|
||||||
public abstract void Initialise();
|
|
||||||
public abstract void Dispose();
|
|
||||||
public abstract bool Delete(string id);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,72 +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.Text;
|
|
||||||
using OpenMetaverse;
|
|
||||||
|
|
||||||
namespace OpenSim.Data
|
|
||||||
{
|
|
||||||
|
|
||||||
public static class DBGuid
|
|
||||||
{
|
|
||||||
/// <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
|
|
||||||
/// now
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="id"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static UUID FromDB(object id)
|
|
||||||
{
|
|
||||||
if ((id == null) || (id == DBNull.Value))
|
|
||||||
return UUID.Zero;
|
|
||||||
|
|
||||||
Type idtype = id.GetType();
|
|
||||||
|
|
||||||
if (idtype == typeof(Guid))
|
|
||||||
return new UUID((Guid)id);
|
|
||||||
|
|
||||||
if (id.GetType() == typeof(string))
|
|
||||||
{
|
|
||||||
Guid gg;
|
|
||||||
if (Guid.TryParse((string)id, out gg))
|
|
||||||
return new UUID(gg);
|
|
||||||
return UUID.Zero;
|
|
||||||
}
|
|
||||||
|
|
||||||
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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,46 +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 OpenMetaverse;
|
|
||||||
using OpenSim.Framework;
|
|
||||||
|
|
||||||
namespace OpenSim.Data
|
|
||||||
{
|
|
||||||
public class AgentPreferencesData
|
|
||||||
{
|
|
||||||
public Dictionary<string, string> Data;
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface IAgentPreferencesData
|
|
||||||
{
|
|
||||||
bool Store(AgentPreferencesData data);
|
|
||||||
AgentPreferencesData GetPrefs(UUID agentID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,43 +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 interface IAssetDataPlugin : IPlugin
|
|
||||||
{
|
|
||||||
AssetBase GetAsset(UUID uuid);
|
|
||||||
bool StoreAsset(AssetBase asset);
|
|
||||||
bool[] AssetsExist(UUID[] uuids);
|
|
||||||
List<AssetMetadata> FetchAssetMetadataSet(int start, int count);
|
|
||||||
void Initialise(string connect);
|
|
||||||
bool Delete(string id);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,56 +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 OpenMetaverse;
|
|
||||||
using OpenSim.Framework;
|
|
||||||
|
|
||||||
namespace OpenSim.Data
|
|
||||||
{
|
|
||||||
public class AuthenticationData
|
|
||||||
{
|
|
||||||
public UUID PrincipalID;
|
|
||||||
public Dictionary<string, object> Data;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// An interface for connecting to the authentication datastore
|
|
||||||
/// </summary>
|
|
||||||
public interface IAuthenticationData
|
|
||||||
{
|
|
||||||
AuthenticationData Get(UUID principalID);
|
|
||||||
|
|
||||||
bool Store(AuthenticationData data);
|
|
||||||
|
|
||||||
bool SetDataItem(UUID principalID, string item, string value);
|
|
||||||
|
|
||||||
bool SetToken(UUID principalID, string token, int lifetime);
|
|
||||||
|
|
||||||
bool CheckToken(UUID principalID, string token, int lifetime);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,49 +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 OpenMetaverse;
|
|
||||||
using OpenSim.Framework;
|
|
||||||
|
|
||||||
namespace OpenSim.Data
|
|
||||||
{
|
|
||||||
// This MUST be a ref type!
|
|
||||||
public class AvatarBaseData
|
|
||||||
{
|
|
||||||
public UUID PrincipalID;
|
|
||||||
public Dictionary<string, string> Data;
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface IAvatarData
|
|
||||||
{
|
|
||||||
AvatarBaseData[] Get(string field, string val);
|
|
||||||
bool Store(AvatarBaseData data);
|
|
||||||
bool Delete(UUID principalID, string name);
|
|
||||||
bool Delete(string field, string val);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,120 +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 interface IEstateDataStore
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Initialise the data store.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="connectstring"></param>
|
|
||||||
void Initialise(string connectstring);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Load estate settings for a region.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="regionID"></param>
|
|
||||||
/// <param name="create">If true, then an estate is created if one is not found.</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
EstateSettings LoadEstateSettings(UUID regionID, bool create);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Load estate settings for an estate ID.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="estateID"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
EstateSettings LoadEstateSettings(int estateID);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Create a new estate.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>
|
|
||||||
/// A <see cref="EstateSettings"/>
|
|
||||||
/// </returns>
|
|
||||||
EstateSettings CreateNewEstate();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Load/Get all estate settings.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>An empty list if no estates were found.</returns>
|
|
||||||
List<EstateSettings> LoadEstateSettingsAll();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Store estate settings.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// This is also called by EstateSettings.Save()</remarks>
|
|
||||||
/// <param name="es"></param>
|
|
||||||
void StoreEstateSettings(EstateSettings es);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get estate IDs.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="search">Name of estate to search for. This is the exact name, no parttern matching is done.</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
List<int> GetEstates(string search);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get the IDs of all estates owned by the given user.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>An empty list if no estates were found.</returns>
|
|
||||||
List<int> GetEstatesByOwner(UUID ownerID);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get the IDs of all estates.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>An empty list if no estates were found.</returns>
|
|
||||||
List<int> GetEstatesAll();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Link a region to an estate.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="regionID"></param>
|
|
||||||
/// <param name="estateID"></param>
|
|
||||||
/// <returns>true if the link succeeded, false otherwise</returns>
|
|
||||||
bool LinkRegion(UUID regionID, int estateID);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get the UUIDs of all the regions in an estate.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="estateID"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
List<UUID> GetRegions(int estateID);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Delete an estate
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="estateID"></param>
|
|
||||||
/// <returns>true if the delete succeeded, false otherwise</returns>
|
|
||||||
bool DeleteEstate(int estateID);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,53 +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 OpenMetaverse;
|
|
||||||
using OpenSim.Framework;
|
|
||||||
|
|
||||||
namespace OpenSim.Data
|
|
||||||
{
|
|
||||||
public class FriendsData
|
|
||||||
{
|
|
||||||
public string PrincipalID;
|
|
||||||
public string Friend;
|
|
||||||
public Dictionary<string, string> Data;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// An interface for connecting to the friends datastore
|
|
||||||
/// </summary>
|
|
||||||
public interface IFriendsData
|
|
||||||
{
|
|
||||||
bool Store(FriendsData data);
|
|
||||||
bool Delete(UUID ownerID, string friend);
|
|
||||||
bool Delete(string ownerID, string friend);
|
|
||||||
FriendsData[] GetFriends(UUID principalID);
|
|
||||||
FriendsData[] GetFriends(string principalID);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,56 +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 OpenMetaverse;
|
|
||||||
using OpenSim.Framework;
|
|
||||||
|
|
||||||
namespace OpenSim.Data
|
|
||||||
{
|
|
||||||
// This MUST be a ref type!
|
|
||||||
public class GridUserData
|
|
||||||
{
|
|
||||||
public string UserID;
|
|
||||||
public Dictionary<string, string> Data;
|
|
||||||
|
|
||||||
public GridUserData()
|
|
||||||
{
|
|
||||||
Data = new Dictionary<string, string>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// An interface for connecting to the user grid datastore
|
|
||||||
/// </summary>
|
|
||||||
public interface IGridUserData
|
|
||||||
{
|
|
||||||
GridUserData Get(string userID);
|
|
||||||
GridUserData[] GetAll(string query);
|
|
||||||
bool Store(GridUserData data);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,144 +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 OpenSim.Data;
|
|
||||||
using OpenMetaverse;
|
|
||||||
|
|
||||||
namespace OpenSim.Data
|
|
||||||
{
|
|
||||||
public class GroupData
|
|
||||||
{
|
|
||||||
public UUID GroupID;
|
|
||||||
public Dictionary<string, string> Data;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class MembershipData
|
|
||||||
{
|
|
||||||
public UUID GroupID;
|
|
||||||
public string PrincipalID;
|
|
||||||
public Dictionary<string, string> Data;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class RoleData
|
|
||||||
{
|
|
||||||
public UUID GroupID;
|
|
||||||
public UUID RoleID;
|
|
||||||
public Dictionary<string, string> Data;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class RoleMembershipData
|
|
||||||
{
|
|
||||||
public UUID GroupID;
|
|
||||||
public UUID RoleID;
|
|
||||||
public string PrincipalID;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class PrincipalData
|
|
||||||
{
|
|
||||||
public string PrincipalID;
|
|
||||||
public UUID ActiveGroupID;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class InvitationData
|
|
||||||
{
|
|
||||||
public UUID InviteID;
|
|
||||||
public UUID GroupID;
|
|
||||||
public UUID RoleID;
|
|
||||||
public string PrincipalID;
|
|
||||||
public Dictionary<string, string> Data;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class NoticeData
|
|
||||||
{
|
|
||||||
public UUID GroupID;
|
|
||||||
public UUID NoticeID;
|
|
||||||
public Dictionary<string, string> Data;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public interface IGroupsData
|
|
||||||
{
|
|
||||||
// groups table
|
|
||||||
bool StoreGroup(GroupData data);
|
|
||||||
GroupData RetrieveGroup(UUID groupID);
|
|
||||||
GroupData RetrieveGroup(string name);
|
|
||||||
GroupData[] RetrieveGroups(string pattern);
|
|
||||||
bool DeleteGroup(UUID groupID);
|
|
||||||
int GroupsCount();
|
|
||||||
|
|
||||||
// membership table
|
|
||||||
MembershipData RetrieveMember(UUID groupID, string pricipalID);
|
|
||||||
MembershipData[] RetrieveMembers(UUID groupID);
|
|
||||||
MembershipData[] RetrieveMemberships(string pricipalID);
|
|
||||||
bool StoreMember(MembershipData data);
|
|
||||||
bool DeleteMember(UUID groupID, string pricipalID);
|
|
||||||
int MemberCount(UUID groupID);
|
|
||||||
|
|
||||||
// roles table
|
|
||||||
bool StoreRole(RoleData data);
|
|
||||||
RoleData RetrieveRole(UUID groupID, UUID roleID);
|
|
||||||
RoleData[] RetrieveRoles(UUID groupID);
|
|
||||||
bool DeleteRole(UUID groupID, UUID roleID);
|
|
||||||
int RoleCount(UUID groupID);
|
|
||||||
|
|
||||||
// rolememberhip table
|
|
||||||
RoleMembershipData[] RetrieveRolesMembers(UUID groupID);
|
|
||||||
RoleMembershipData[] RetrieveRoleMembers(UUID groupID, UUID roleID);
|
|
||||||
RoleMembershipData[] RetrieveMemberRoles(UUID groupID, string principalID);
|
|
||||||
RoleMembershipData RetrieveRoleMember(UUID groupID, UUID roleID, string principalID);
|
|
||||||
int RoleMemberCount(UUID groupID, UUID roleID);
|
|
||||||
bool StoreRoleMember(RoleMembershipData data);
|
|
||||||
bool DeleteRoleMember(RoleMembershipData data);
|
|
||||||
bool DeleteMemberAllRoles(UUID groupID, string principalID);
|
|
||||||
|
|
||||||
// principals table
|
|
||||||
bool StorePrincipal(PrincipalData data);
|
|
||||||
PrincipalData RetrievePrincipal(string principalID);
|
|
||||||
bool DeletePrincipal(string principalID);
|
|
||||||
|
|
||||||
// invites table
|
|
||||||
bool StoreInvitation(InvitationData data);
|
|
||||||
InvitationData RetrieveInvitation(UUID inviteID);
|
|
||||||
InvitationData RetrieveInvitation(UUID groupID, string principalID);
|
|
||||||
bool DeleteInvite(UUID inviteID);
|
|
||||||
void DeleteOldInvites();
|
|
||||||
|
|
||||||
// notices table
|
|
||||||
bool StoreNotice(NoticeData data);
|
|
||||||
NoticeData RetrieveNotice(UUID noticeID);
|
|
||||||
NoticeData[] RetrieveNotices(UUID groupID);
|
|
||||||
bool DeleteNotice(UUID noticeID);
|
|
||||||
void DeleteOldNotices();
|
|
||||||
|
|
||||||
// combinations
|
|
||||||
MembershipData RetrievePrincipalGroupMembership(string principalID, UUID groupID);
|
|
||||||
MembershipData[] RetrievePrincipalGroupMemberships(string principalID);
|
|
||||||
|
|
||||||
// Misc
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,59 +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 OpenMetaverse;
|
|
||||||
using OpenSim.Framework;
|
|
||||||
|
|
||||||
namespace OpenSim.Data
|
|
||||||
{
|
|
||||||
// This MUST be a ref type!
|
|
||||||
public class HGTravelingData
|
|
||||||
{
|
|
||||||
public UUID SessionID;
|
|
||||||
public UUID UserID;
|
|
||||||
public Dictionary<string, string> Data;
|
|
||||||
|
|
||||||
public HGTravelingData()
|
|
||||||
{
|
|
||||||
Data = new Dictionary<string, string>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// An interface for connecting to the user grid datastore
|
|
||||||
/// </summary>
|
|
||||||
public interface IHGTravelingData
|
|
||||||
{
|
|
||||||
HGTravelingData Get(UUID sessionID);
|
|
||||||
HGTravelingData[] GetSessions(UUID userID);
|
|
||||||
bool Store(HGTravelingData data);
|
|
||||||
bool Delete(UUID sessionID);
|
|
||||||
void DeleteOld();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,158 +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
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// An interface for accessing inventory data from a storage server
|
|
||||||
/// </summary>
|
|
||||||
public interface IInventoryDataPlugin : IPlugin
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Initialises the interface
|
|
||||||
/// </summary>
|
|
||||||
void Initialise(string connect);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns all descendent folders of this folder. Does not return the parent folder itself.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="parentID">The folder to get subfolders for</param>
|
|
||||||
/// <returns>A list of inventory folders</returns>
|
|
||||||
List<InventoryFolderBase> getFolderHierarchy(UUID parentID);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns a list of inventory items contained within the specified folder
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="folderID">The UUID of the target folder</param>
|
|
||||||
/// <returns>A List of InventoryItemBase items</returns>
|
|
||||||
List<InventoryItemBase> getInventoryInFolder(UUID folderID);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns a list of the root folders within a users inventory
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="user">The user whos inventory is to be searched</param>
|
|
||||||
/// <returns>A list of folder objects</returns>
|
|
||||||
List<InventoryFolderBase> getUserRootFolders(UUID user);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns the users inventory root folder.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="user">The UUID of the user who is having inventory being returned</param>
|
|
||||||
/// <returns>Root inventory folder, null if no root inventory folder was found</returns>
|
|
||||||
InventoryFolderBase getUserRootFolder(UUID user);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns a list of inventory folders contained in the folder 'parentID'
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="parentID">The folder to get subfolders for</param>
|
|
||||||
/// <returns>A list of inventory folders</returns>
|
|
||||||
List<InventoryFolderBase> getInventoryFolders(UUID parentID);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns an inventory item by its UUID
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="item">The UUID of the item to be returned</param>
|
|
||||||
/// <returns>A class containing item information</returns>
|
|
||||||
InventoryItemBase getInventoryItem(UUID item);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns a specified inventory folder by its UUID
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="folder">The UUID of the folder to be returned</param>
|
|
||||||
/// <returns>A class containing folder information</returns>
|
|
||||||
InventoryFolderBase getInventoryFolder(UUID folder);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Creates a new inventory item based on item
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="item">The item to be created</param>
|
|
||||||
void addInventoryItem(InventoryItemBase item);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Updates an inventory item with item (updates based on ID)
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="item">The updated item</param>
|
|
||||||
void updateInventoryItem(InventoryItemBase item);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="item"></param>
|
|
||||||
void deleteInventoryItem(UUID item);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="item"></param>
|
|
||||||
InventoryItemBase queryInventoryItem(UUID item);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="item"></param>
|
|
||||||
InventoryFolderBase queryInventoryFolder(UUID folder);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Adds a new folder specified by folder
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="folder">The inventory folder</param>
|
|
||||||
void addInventoryFolder(InventoryFolderBase folder);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Updates a folder based on its ID with folder
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="folder">The inventory folder</param>
|
|
||||||
void updateInventoryFolder(InventoryFolderBase folder);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Updates a folder based on its ID with folder
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="folder">The inventory folder</param>
|
|
||||||
void moveInventoryFolder(InventoryFolderBase folder);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Deletes a folder. Thie will delete both the folder itself and its contents (items and descendent folders)
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="folder">The id of the folder</param>
|
|
||||||
void deleteInventoryFolder(UUID folder);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns all activated gesture-items in the inventory of the specified avatar.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="avatarID">
|
|
||||||
/// The <see cref="UUID"/> of the avatar
|
|
||||||
/// </param>
|
|
||||||
/// <returns>
|
|
||||||
/// The list of gestures (<see cref="InventoryItemBase"/>s)
|
|
||||||
/// </returns>
|
|
||||||
List<InventoryItemBase> fetchActiveGestures(UUID avatarID);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,44 +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 OpenMetaverse;
|
|
||||||
using OpenSim.Framework;
|
|
||||||
|
|
||||||
namespace OpenSim.Data
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// An interface for connecting to the Mute List datastore
|
|
||||||
/// </summary>
|
|
||||||
public interface IMuteListData
|
|
||||||
{
|
|
||||||
bool Store(MuteData data);
|
|
||||||
MuteData[] Get(UUID agentID);
|
|
||||||
bool Delete(UUID agentID, UUID muteID, string muteName);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,50 +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 OpenSim.Data;
|
|
||||||
using OpenMetaverse;
|
|
||||||
|
|
||||||
namespace OpenSim.Data
|
|
||||||
{
|
|
||||||
public class OfflineIMData
|
|
||||||
{
|
|
||||||
public UUID PrincipalID;
|
|
||||||
public UUID FromID;
|
|
||||||
public Dictionary<string, string> Data;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public interface IOfflineIMData
|
|
||||||
{
|
|
||||||
OfflineIMData[] Get(string field, string val);
|
|
||||||
long GetCount(string field, string key);
|
|
||||||
bool Store(OfflineIMData data);
|
|
||||||
bool Delete(string field, string val);
|
|
||||||
void DeleteOld();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,58 +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 OpenMetaverse;
|
|
||||||
using OpenSim.Framework;
|
|
||||||
|
|
||||||
namespace OpenSim.Data
|
|
||||||
{
|
|
||||||
// This MUST be a ref type!
|
|
||||||
public class PresenceData
|
|
||||||
{
|
|
||||||
public string UserID;
|
|
||||||
public UUID RegionID;
|
|
||||||
public UUID SessionID;
|
|
||||||
public Dictionary<string, string> Data;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// An interface for connecting to the presence datastore
|
|
||||||
/// </summary>
|
|
||||||
public interface IPresenceData
|
|
||||||
{
|
|
||||||
bool Store(PresenceData data);
|
|
||||||
|
|
||||||
PresenceData Get(UUID sessionID);
|
|
||||||
void LogoutRegionAgents(UUID regionID);
|
|
||||||
bool ReportAgent(UUID sessionID, UUID regionID);
|
|
||||||
PresenceData[] Get(string field, string data);
|
|
||||||
bool Delete(string field, string val);
|
|
||||||
bool VerifyAgent(UUID agentId, UUID secureSessionID);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,58 +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 OpenMetaverse;
|
|
||||||
using OpenMetaverse.StructuredData;
|
|
||||||
using OpenSim.Framework;
|
|
||||||
|
|
||||||
namespace OpenSim.Data
|
|
||||||
{
|
|
||||||
|
|
||||||
public interface IProfilesData
|
|
||||||
{
|
|
||||||
OSDArray GetClassifiedRecords(UUID creatorId);
|
|
||||||
bool UpdateClassifiedRecord(UserClassifiedAdd ad, ref string result);
|
|
||||||
bool DeleteClassifiedRecord(UUID recordId);
|
|
||||||
OSDArray GetAvatarPicks(UUID avatarId);
|
|
||||||
UserProfilePick GetPickInfo(UUID avatarId, UUID pickId);
|
|
||||||
bool UpdatePicksRecord(UserProfilePick pick);
|
|
||||||
bool DeletePicksRecord(UUID pickId);
|
|
||||||
bool GetAvatarNotes(ref UserProfileNotes note);
|
|
||||||
bool UpdateAvatarNotes(ref UserProfileNotes note, ref string result);
|
|
||||||
bool GetAvatarProperties(ref UserProfileProperties props, ref string result);
|
|
||||||
bool UpdateAvatarProperties(ref UserProfileProperties props, ref string result);
|
|
||||||
bool UpdateAvatarInterests(UserProfileProperties up, 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 SetUserAppData(UserAppData props, ref string result);
|
|
||||||
OSDArray GetUserImageAssets(UUID avatarId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,112 +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 OpenMetaverse;
|
|
||||||
using OpenSim.Framework;
|
|
||||||
|
|
||||||
namespace OpenSim.Data
|
|
||||||
{
|
|
||||||
public class RegionData
|
|
||||||
{
|
|
||||||
public UUID RegionID;
|
|
||||||
public UUID ScopeID;
|
|
||||||
public string RegionName;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The position in meters of this region.
|
|
||||||
/// </summary>
|
|
||||||
public int posX;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The position in meters of this region.
|
|
||||||
/// </summary>
|
|
||||||
public int posY;
|
|
||||||
|
|
||||||
public int sizeX;
|
|
||||||
public int sizeY;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Return the x-coordinate of this region in region units.
|
|
||||||
/// </summary>
|
|
||||||
public int coordX { get { return (int)Util.WorldToRegionLoc((uint)posX); } }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Return the y-coordinate of this region in region units.
|
|
||||||
/// </summary>
|
|
||||||
public int coordY { get { return (int)Util.WorldToRegionLoc((uint)posY); } }
|
|
||||||
|
|
||||||
public Dictionary<string, object> Data;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// An interface for connecting to the authentication datastore
|
|
||||||
/// </summary>
|
|
||||||
public interface IRegionData
|
|
||||||
{
|
|
||||||
RegionData Get(UUID regionID, UUID ScopeID);
|
|
||||||
List<RegionData> Get(string regionName, UUID ScopeID);
|
|
||||||
RegionData GetSpecific(string regionName, UUID ScopeID);
|
|
||||||
|
|
||||||
RegionData Get(int x, int y, UUID ScopeID);
|
|
||||||
List<RegionData> Get(int xStart, int yStart, int xEnd, int yEnd, UUID ScopeID);
|
|
||||||
|
|
||||||
bool Store(RegionData data);
|
|
||||||
|
|
||||||
bool SetDataItem(UUID principalID, string item, string value);
|
|
||||||
|
|
||||||
bool Delete(UUID regionID);
|
|
||||||
|
|
||||||
List<RegionData> GetDefaultRegions(UUID scopeID);
|
|
||||||
List<RegionData> GetDefaultHypergridRegions(UUID scopeID);
|
|
||||||
List<RegionData> GetFallbackRegions(UUID scopeID, int x, int y);
|
|
||||||
List<RegionData> GetHyperlinks(UUID scopeID);
|
|
||||||
}
|
|
||||||
|
|
||||||
public class RegionDataDistanceCompare : IComparer<RegionData>
|
|
||||||
{
|
|
||||||
private Vector2 m_origin;
|
|
||||||
|
|
||||||
public RegionDataDistanceCompare(int x, int y)
|
|
||||||
{
|
|
||||||
m_origin = new Vector2(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int Compare(RegionData regionA, RegionData regionB)
|
|
||||||
{
|
|
||||||
Vector2 vectorA = new Vector2(regionA.posX, regionA.posY);
|
|
||||||
Vector2 vectorB = new Vector2(regionB.posX, regionB.posY);
|
|
||||||
return Math.Sign(VectorDistance(m_origin, vectorA) - VectorDistance(m_origin, vectorB));
|
|
||||||
}
|
|
||||||
|
|
||||||
private float VectorDistance(Vector2 x, Vector2 y)
|
|
||||||
{
|
|
||||||
return (x - y).Length();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,55 +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 OpenMetaverse;
|
|
||||||
using OpenSim.Framework;
|
|
||||||
|
|
||||||
namespace OpenSim.Data
|
|
||||||
{
|
|
||||||
public class UserAccountData
|
|
||||||
{
|
|
||||||
public UUID PrincipalID;
|
|
||||||
public UUID ScopeID;
|
|
||||||
public string FirstName;
|
|
||||||
public string LastName;
|
|
||||||
public Dictionary<string, string> Data;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// An interface for connecting to the user accounts datastore
|
|
||||||
/// </summary>
|
|
||||||
public interface IUserAccountData
|
|
||||||
{
|
|
||||||
UserAccountData[] Get(string[] fields, string[] values);
|
|
||||||
bool Store(UserAccountData data);
|
|
||||||
bool Delete(string field, string val);
|
|
||||||
UserAccountData[] GetUsers(UUID scopeID, string query);
|
|
||||||
UserAccountData[] GetUsersWhere(UUID scopeID, string where);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// This interface exists to distinguish between the normal IAssetDataPlugin and the one used by XAssetService
|
|
||||||
/// for now.
|
|
||||||
/// </summary>
|
|
||||||
public interface IXAssetDataPlugin : IPlugin
|
|
||||||
{
|
|
||||||
AssetBase GetAsset(UUID uuid);
|
|
||||||
void StoreAsset(AssetBase asset);
|
|
||||||
bool[] AssetsExist(UUID[] uuids);
|
|
||||||
List<AssetMetadata> FetchAssetMetadataSet(int start, int count);
|
|
||||||
void Initialise(string connect);
|
|
||||||
bool Delete(string id);
|
|
||||||
}
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue