Compare commits
	
		
			No commits in common. "master" and "link-sitting" have entirely different histories. 
		
	
	
		
			master
			...
			link-sitti
		
	
		| 
						 | 
				
			
			@ -1,6 +1,5 @@
 | 
			
		|||
.project
 | 
			
		||||
.settings
 | 
			
		||||
.gitignore
 | 
			
		||||
*.csproj
 | 
			
		||||
*.csproj.user
 | 
			
		||||
*.build
 | 
			
		||||
| 
						 | 
				
			
			@ -11,7 +10,6 @@
 | 
			
		|||
*.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
 | 
			
		||||
| 
						 | 
				
			
			@ -31,8 +29,6 @@
 | 
			
		|||
*/*/*/*/*/bin
 | 
			
		||||
*/*/*/*/*/*/bin
 | 
			
		||||
*/*/*/*/*/*/*/bin
 | 
			
		||||
.vs/
 | 
			
		||||
addon-modules/
 | 
			
		||||
bin/Debug/*.dll
 | 
			
		||||
bin/*.dll.mdb
 | 
			
		||||
bin/*.db
 | 
			
		||||
| 
						 | 
				
			
			@ -58,7 +54,6 @@ bin/Regions/*
 | 
			
		|||
bin/UserAssets
 | 
			
		||||
bin/assetcache
 | 
			
		||||
bin/maptiles
 | 
			
		||||
bin/bakes
 | 
			
		||||
bin/estate_settings.xml
 | 
			
		||||
bin/config-include/CenomeCache.ini
 | 
			
		||||
bin/config-include/FlotsamCache.ini
 | 
			
		||||
| 
						 | 
				
			
			@ -71,12 +66,6 @@ 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
 | 
			
		||||
| 
						 | 
				
			
			@ -94,6 +83,7 @@ TAGS
 | 
			
		|||
Makefile.local
 | 
			
		||||
bin/.version
 | 
			
		||||
compile.bat
 | 
			
		||||
addon-modules
 | 
			
		||||
OpenSim/Data/Tests/test-results/
 | 
			
		||||
OpenSim/Framework/Serialization/Tests/test-results/
 | 
			
		||||
OpenSim/Framework/Servers/Tests/test-results/
 | 
			
		||||
| 
						 | 
				
			
			@ -112,5 +102,3 @@ OpenSim/Tests/test-results/
 | 
			
		|||
test-results/
 | 
			
		||||
doc/html
 | 
			
		||||
doc/doxygen.error.log
 | 
			
		||||
 | 
			
		||||
*.patch
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -113,12 +113,10 @@
 | 
			
		|||
  </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" />
 | 
			
		||||
| 
						 | 
				
			
			@ -145,12 +143,7 @@
 | 
			
		|||
  </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%"/>
 | 
			
		||||
  <delete dir="%temp%"/>
 | 
			
		||||
</target>
 | 
			
		||||
 | 
			
		||||
<target name="test-stress" depends="build, find-nunit">
 | 
			
		||||
| 
						 | 
				
			
			@ -233,12 +226,10 @@
 | 
			
		|||
    <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" />
 | 
			
		||||
| 
						 | 
				
			
			@ -265,23 +256,17 @@
 | 
			
		|||
    <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.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">
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										31
									
								
								BUILDING.md
								
								
								
								
							
							
						
						
									
										31
									
								
								BUILDING.md
								
								
								
								
							| 
						 | 
				
			
			@ -1,35 +1,34 @@
 | 
			
		|||
# 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
 | 
			
		||||
# Building on Linux
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
*	Mono >= 2.4.3
 | 
			
		||||
*	Nant >= 0.85
 | 
			
		||||
*	On some Linux distributions you may need to install additional packages.
 | 
			
		||||
	See http://opensimulator.org/wiki/Dependencies for more information.
 | 
			
		||||
*	May also use xbuild (included in mono distributions)
 | 
			
		||||
*	May use Monodevelop, a cross-platform IDE
 | 
			
		||||
 | 
			
		||||
From the distribution type:
 | 
			
		||||
 | 
			
		||||
 * ./runprebuild.sh
 | 
			
		||||
 * type msbuild or xbuild
 | 
			
		||||
 * nant (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
 | 
			
		||||
 * run mono OpenSim.exe
 | 
			
		||||
 | 
			
		||||
# Using Monodevelop
 | 
			
		||||
 | 
			
		||||
From the distribution type:
 | 
			
		||||
 * ./runprebuild.sh
 | 
			
		||||
 * type monodevelop OpenSim.sln
 | 
			
		||||
 | 
			
		||||
# References
 | 
			
		||||
 
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										101
									
								
								CONTRIBUTORS.txt
								
								
								
								
							
							
						
						
									
										101
									
								
								CONTRIBUTORS.txt
								
								
								
								
							| 
						 | 
				
			
			@ -1,22 +1,39 @@
 | 
			
		|||
The following people have contributed to OpenSim (Thank you for your effort!) 
 | 
			
		||||
   <<<>>>>The following people have contributed to OpenSim (Thank you 
 | 
			
		||||
for your effort!) 
 | 
			
		||||
 | 
			
		||||
= Current OpenSim Developers (in very rough order of appearance) =
 | 
			
		||||
These folks represent the current core team for OpenSim, and are the
 | 
			
		||||
people that make the day to day of OpenSim happen.
 | 
			
		||||
 | 
			
		||||
* justincc (OSVW Consulting, justincc.org)
 | 
			
		||||
* chi11ken (Genkii)
 | 
			
		||||
* dahlia 
 | 
			
		||||
* Melanie Thielker
 | 
			
		||||
* Diva (Crista Lopes, University of California, Irvine)
 | 
			
		||||
* Robert Adams (MisterBlue)
 | 
			
		||||
* Kevin Cozens
 | 
			
		||||
* Leal Duarte (Ubit Umarov)
 | 
			
		||||
* Dan Lake (Intel)
 | 
			
		||||
* Marck
 | 
			
		||||
* Mic Bowman (Intel)
 | 
			
		||||
* BlueWall (James Hughes)
 | 
			
		||||
* Nebadon Izumi (Michael Cerquoni, OSgrid)
 | 
			
		||||
* Snoopy Pfeffer
 | 
			
		||||
* Robert Adams (Intel)
 | 
			
		||||
 | 
			
		||||
= Core Developers Following the White Rabbit =
 | 
			
		||||
Core developers who have temporarily (we hope) gone chasing the white rabbit. 
 | 
			
		||||
They are in all similar to the active core developers, except that they haven't
 | 
			
		||||
been that active lately, so their voting rights are awaiting their come back. 
 | 
			
		||||
 | 
			
		||||
* Nebadon Izumi (Michael Cerquoni, OSgrid)
 | 
			
		||||
* Alicia Raven
 | 
			
		||||
* MW (Tribal Media AB)
 | 
			
		||||
* Adam Frisby 	(DeepThink Pty Ltd)
 | 
			
		||||
* lbsa71 (Tribal Media AB)
 | 
			
		||||
* Teravus (w3z)
 | 
			
		||||
* Ckrinke (Charles Krinke)
 | 
			
		||||
* Dr Scofield aka Dirk Husemann (IBM Research - Zurich)
 | 
			
		||||
* mikem (3Di)
 | 
			
		||||
* Homer_Horwitz
 | 
			
		||||
* nlin (3Di)
 | 
			
		||||
* Arthur Rodrigo S Valadares (IBM)
 | 
			
		||||
* John Hurliman
 | 
			
		||||
 | 
			
		||||
= Past Open Sim Developers =
 | 
			
		||||
These folks are alumns of the OpenSim core group, but are now
 | 
			
		||||
| 
						 | 
				
			
			@ -38,65 +55,36 @@ where we are today.
 | 
			
		|||
* 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
 | 
			
		||||
* aduffy70
 | 
			
		||||
* Ai Austin
 | 
			
		||||
* A_Biondi
 | 
			
		||||
* alex_carnell
 | 
			
		||||
* Alan Webb (IBM)
 | 
			
		||||
* Aleric
 | 
			
		||||
* Allen Kerensky
 | 
			
		||||
* BigFootAg
 | 
			
		||||
* Bill Blight
 | 
			
		||||
* BlueWall Slade
 | 
			
		||||
* bobshaffer2
 | 
			
		||||
* brianw/Sir_Ahzz
 | 
			
		||||
* CharlieO
 | 
			
		||||
* ChrisDown
 | 
			
		||||
* Chris Yeoh (IBM)
 | 
			
		||||
* cinderblocks
 | 
			
		||||
* controlbreak
 | 
			
		||||
* coyled
 | 
			
		||||
* ctrlaltdavid (David Rowe)
 | 
			
		||||
* Daedius
 | 
			
		||||
* daTwitch 
 | 
			
		||||
* Dev Random
 | 
			
		||||
* devalnor-#708
 | 
			
		||||
* dmiles (Daxtron Labs)
 | 
			
		||||
* Dong Jun Lan (IBM)
 | 
			
		||||
* DoranZemlja
 | 
			
		||||
* Drake Arconis
 | 
			
		||||
* dr0b3rts
 | 
			
		||||
* dslake
 | 
			
		||||
* eeyore
 | 
			
		||||
* dslake (Intel)
 | 
			
		||||
* FredoChaplin
 | 
			
		||||
* FreakyTech
 | 
			
		||||
* Garmin Kawaguichi
 | 
			
		||||
* Gavin Hird
 | 
			
		||||
* Gerhard
 | 
			
		||||
* Godfrey
 | 
			
		||||
* Greg C.
 | 
			
		||||
| 
						 | 
				
			
			@ -106,18 +94,12 @@ what it is today.
 | 
			
		|||
* 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)
 | 
			
		||||
| 
						 | 
				
			
			@ -125,36 +107,26 @@ what it is today.
 | 
			
		|||
* Jon Cundill
 | 
			
		||||
* Junta Kohime
 | 
			
		||||
* Kayne
 | 
			
		||||
* Kevin Cozens
 | 
			
		||||
* 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
 | 
			
		||||
* Misterblue
 | 
			
		||||
* Misterblue (Intel)
 | 
			
		||||
* Mircea Kitsune
 | 
			
		||||
* mpallari
 | 
			
		||||
* MrMonkE
 | 
			
		||||
| 
						 | 
				
			
			@ -163,42 +135,32 @@ what it is today.
 | 
			
		|||
* nornalbion
 | 
			
		||||
* Omar Vera Ustariz (IBM)
 | 
			
		||||
* openlifegrid.com
 | 
			
		||||
* Oren Hurvitz (Kitely)
 | 
			
		||||
* otakup0pe
 | 
			
		||||
* Pixel Tomsen
 | 
			
		||||
* Quill Littlefeather
 | 
			
		||||
* ralphos
 | 
			
		||||
* RemedyTomm
 | 
			
		||||
* Revolution
 | 
			
		||||
* Richard Alimi (IBM)
 | 
			
		||||
* Rick Alther (IBM)
 | 
			
		||||
* Rob Smart (IBM)
 | 
			
		||||
* 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)
 | 
			
		||||
| 
						 | 
				
			
			@ -210,18 +172,23 @@ what it is today.
 | 
			
		|||
* Zha Ewry
 | 
			
		||||
* ziah
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
= LSL Devs =
 | 
			
		||||
 | 
			
		||||
* Alondria
 | 
			
		||||
* CharlieO
 | 
			
		||||
* Tedd
 | 
			
		||||
* Melanie Thielker
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
= Testers =
 | 
			
		||||
 | 
			
		||||
* Ai Austin
 | 
			
		||||
* CharlieO (LSL)
 | 
			
		||||
* Ckrinke
 | 
			
		||||
* openlifegrid.com
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
This software uses components from the following developers:
 | 
			
		||||
* Sleepycat Software (Berkeley DB)
 | 
			
		||||
* Aurora-Sim (http://aurora-sim.org)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| 
						 | 
				
			
			@ -30,7 +30,6 @@ using System.Collections.Generic;
 | 
			
		|||
 | 
			
		||||
using OpenSim.Framework;
 | 
			
		||||
using OpenSim.Region.Framework.Interfaces;
 | 
			
		||||
using OpenSim.Services.Interfaces;
 | 
			
		||||
 | 
			
		||||
namespace OpenSim.Groups
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -174,7 +174,7 @@ namespace OpenSim.Groups
 | 
			
		|||
            if (dict.ContainsKey("ServiceLocation") && dict["ServiceLocation"] != null)
 | 
			
		||||
                grec.ServiceLocation = dict["ServiceLocation"].ToString();
 | 
			
		||||
            else
 | 
			
		||||
                grec.ServiceLocation = string.Empty;
 | 
			
		||||
                grec.GroupName = string.Empty;
 | 
			
		||||
 | 
			
		||||
            if (dict.ContainsKey("ShownInList") && dict["ShownInList"] != null)
 | 
			
		||||
                grec.ShowInList = bool.Parse(dict["ShownInList"].ToString());
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -56,8 +56,8 @@ namespace OpenSim.Groups
 | 
			
		|||
        private IGroupsServicesConnector m_groupData = null;
 | 
			
		||||
 | 
			
		||||
        // Config Options
 | 
			
		||||
        private bool m_groupMessagingEnabled;
 | 
			
		||||
        private bool m_debugEnabled;
 | 
			
		||||
        private bool m_groupMessagingEnabled = false;
 | 
			
		||||
        private bool m_debugEnabled = true;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// If enabled, module only tries to send group IMs to online users by querying cached presence information.
 | 
			
		||||
| 
						 | 
				
			
			@ -83,6 +83,7 @@ namespace OpenSim.Groups
 | 
			
		|||
        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)
 | 
			
		||||
| 
						 | 
				
			
			@ -110,17 +111,9 @@ namespace OpenSim.Groups
 | 
			
		|||
            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_debugEnabled = groupsConfig.GetBoolean("DebugEnabled", true);
 | 
			
		||||
 | 
			
		||||
            m_log.InfoFormat(
 | 
			
		||||
                "[Groups.Messaging]: GroupsMessagingModule enabled with MessageOnlineOnly = {0}, DebugEnabled = {1}",
 | 
			
		||||
| 
						 | 
				
			
			@ -140,14 +133,6 @@ namespace OpenSim.Groups
 | 
			
		|||
            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)
 | 
			
		||||
| 
						 | 
				
			
			@ -187,8 +172,10 @@ namespace OpenSim.Groups
 | 
			
		|||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            if (m_presenceService == null)
 | 
			
		||||
                m_presenceService = scene.PresenceService;
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void RemoveRegion(Scene scene)
 | 
			
		||||
| 
						 | 
				
			
			@ -235,25 +222,6 @@ namespace OpenSim.Groups
 | 
			
		|||
 | 
			
		||||
        #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.
 | 
			
		||||
| 
						 | 
				
			
			@ -277,20 +245,8 @@ namespace OpenSim.Groups
 | 
			
		|||
        
 | 
			
		||||
        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;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -298,7 +254,7 @@ namespace OpenSim.Groups
 | 
			
		|||
            // 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
 | 
			
		||||
            // We cache in order not to overwhlem 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))
 | 
			
		||||
| 
						 | 
				
			
			@ -317,6 +273,8 @@ namespace OpenSim.Groups
 | 
			
		|||
//                        "[Groups.Messaging]: SendMessageToGroup called for group {0} with {1} visible members, {2} online",
 | 
			
		||||
//                        groupID, groupMembersCount, groupMembers.Count());
 | 
			
		||||
 | 
			
		||||
            int requestStartTick = Environment.TickCount;
 | 
			
		||||
 | 
			
		||||
            im.imSessionID = groupID.Guid;
 | 
			
		||||
            im.fromGroup = true;
 | 
			
		||||
            IClientAPI thisClient = GetActiveClient(fromAgentID);
 | 
			
		||||
| 
						 | 
				
			
			@ -325,13 +283,6 @@ namespace OpenSim.Groups
 | 
			
		|||
                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;
 | 
			
		||||
| 
						 | 
				
			
			@ -348,27 +299,12 @@ namespace OpenSim.Groups
 | 
			
		|||
 | 
			
		||||
                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))
 | 
			
		||||
                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);
 | 
			
		||||
 | 
			
		||||
                    if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: {0} has dropped session, not delivering to them", member.AgentID);
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -599,34 +535,35 @@ namespace OpenSim.Groups
 | 
			
		|||
                {
 | 
			
		||||
                    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)
 | 
			
		||||
                            );
 | 
			
		||||
                    eq.ChatterboxInvitation(
 | 
			
		||||
                        GroupID
 | 
			
		||||
                        , groupInfo.GroupName
 | 
			
		||||
                        , new UUID(msg.fromAgentID)
 | 
			
		||||
                        , 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);
 | 
			
		||||
                    }
 | 
			
		||||
                    eq.ChatterBoxSessionAgentListUpdates(
 | 
			
		||||
                        new UUID(GroupID)
 | 
			
		||||
                        , AgentID
 | 
			
		||||
                        , new UUID(msg.toAgentID)
 | 
			
		||||
                        , false //canVoiceChat
 | 
			
		||||
                        , false //isModerator
 | 
			
		||||
                        , false //text mute
 | 
			
		||||
                        );
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -661,12 +598,14 @@ namespace OpenSim.Groups
 | 
			
		|||
                    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);
 | 
			
		||||
                    }
 | 
			
		||||
                    queue.ChatterBoxSessionAgentListUpdates(
 | 
			
		||||
                        GroupID
 | 
			
		||||
                        , AgentID
 | 
			
		||||
                        , new UUID(im.toAgentID)
 | 
			
		||||
                        , false //canVoiceChat
 | 
			
		||||
                        , false //isModerator
 | 
			
		||||
                        , false //text mute
 | 
			
		||||
                        );
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -708,7 +647,11 @@ namespace OpenSim.Groups
 | 
			
		|||
            bodyMap.Add("session_info", sessionMap);
 | 
			
		||||
 | 
			
		||||
            IEventQueue queue = remoteClient.Scene.RequestModuleInterface<IEventQueue>();
 | 
			
		||||
            queue?.Enqueue(queue.BuildEvent("ChatterBoxSessionStartReply", bodyMap), remoteClient.AgentId);
 | 
			
		||||
 | 
			
		||||
            if (queue != null)
 | 
			
		||||
            {
 | 
			
		||||
                queue.Enqueue(queue.BuildEvent("ChatterBoxSessionStartReply", bodyMap), remoteClient.AgentId);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void DebugGridInstantMessage(GridInstantMessage im)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| 
						 | 
				
			
			@ -1,4 +1,4 @@
 | 
			
		|||
/*
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) Contributors, http://opensimulator.org/
 | 
			
		||||
 * See CONTRIBUTORS.TXT for a full list of copyright holders.
 | 
			
		||||
 *
 | 
			
		||||
| 
						 | 
				
			
			@ -32,7 +32,6 @@ 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;
 | 
			
		||||
| 
						 | 
				
			
			@ -246,9 +245,9 @@ namespace OpenSim.Groups
 | 
			
		|||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public List<DirGroupsReplyData> FindGroups(string RequestingAgentIDstr, string search)
 | 
			
		||||
        public List<DirGroupsReplyData> FindGroups(string RequestingAgentID, string search)
 | 
			
		||||
        {
 | 
			
		||||
            return m_LocalGroupsConnector.FindGroups(RequestingAgentIDstr, search);
 | 
			
		||||
            return m_LocalGroupsConnector.FindGroups(AgentUUI(RequestingAgentID), search);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public List<GroupMembersData> GetGroupMembers(string RequestingAgentID, UUID GroupID)
 | 
			
		||||
| 
						 | 
				
			
			@ -561,7 +560,7 @@ namespace OpenSim.Groups
 | 
			
		|||
 | 
			
		||||
                    // so we have the list of urls to send the notice to
 | 
			
		||||
                    // this may take a long time...
 | 
			
		||||
                    WorkManager.RunInThread(delegate
 | 
			
		||||
                    Util.FireAndForget(delegate
 | 
			
		||||
                    {
 | 
			
		||||
                        foreach (string u in urls)
 | 
			
		||||
                        {
 | 
			
		||||
| 
						 | 
				
			
			@ -572,7 +571,7 @@ namespace OpenSim.Groups
 | 
			
		|||
                                    hasAttachment, attType, attName, attItemID, AgentUUIForOutside(attOwnerID));
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }, null, string.Format("AddGroupNotice (agent {0}, group {1})", RequestingAgentID, groupID));
 | 
			
		||||
                    });
 | 
			
		||||
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
| 
						 | 
				
			
			@ -605,8 +604,14 @@ namespace OpenSim.Groups
 | 
			
		|||
        private string AgentUUI(string AgentIDStr)
 | 
			
		||||
        {
 | 
			
		||||
            UUID AgentID = UUID.Zero;
 | 
			
		||||
            if (!UUID.TryParse(AgentIDStr, out AgentID) || AgentID == UUID.Zero)
 | 
			
		||||
                return UUID.Zero.ToString();
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                AgentID = new UUID(AgentIDStr);
 | 
			
		||||
            }
 | 
			
		||||
            catch (FormatException)
 | 
			
		||||
            {
 | 
			
		||||
                return AgentID.ToString();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (m_UserManagement.IsLocalGridUser(AgentID))
 | 
			
		||||
                return AgentID.ToString();
 | 
			
		||||
| 
						 | 
				
			
			@ -630,8 +635,14 @@ namespace OpenSim.Groups
 | 
			
		|||
        private string AgentUUIForOutside(string AgentIDStr)
 | 
			
		||||
        {
 | 
			
		||||
            UUID AgentID = UUID.Zero;
 | 
			
		||||
            if (!UUID.TryParse(AgentIDStr, out AgentID) || AgentID == UUID.Zero)
 | 
			
		||||
                return UUID.Zero.ToString();
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                AgentID = new UUID(AgentIDStr);
 | 
			
		||||
            }
 | 
			
		||||
            catch (FormatException)
 | 
			
		||||
            {
 | 
			
		||||
                return AgentID.ToString();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            AgentCircuitData agent = null;
 | 
			
		||||
            foreach (Scene scene in m_Scenes)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,4 @@
 | 
			
		|||
/*
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) Contributors, http://opensimulator.org/
 | 
			
		||||
 * See CONTRIBUTORS.TXT for a full list of copyright holders.
 | 
			
		||||
 *
 | 
			
		||||
| 
						 | 
				
			
			@ -115,10 +115,9 @@ namespace OpenSim.Groups
 | 
			
		|||
        protected override byte[] ProcessRequest(string path, Stream requestData,
 | 
			
		||||
                IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
 | 
			
		||||
        {
 | 
			
		||||
            string body;
 | 
			
		||||
            using(StreamReader sr = new StreamReader(requestData))
 | 
			
		||||
                body = sr.ReadToEnd();
 | 
			
		||||
 | 
			
		||||
            StreamReader sr = new StreamReader(requestData);
 | 
			
		||||
            string body = sr.ReadToEnd();
 | 
			
		||||
            sr.Close();
 | 
			
		||||
            body = body.Trim();
 | 
			
		||||
 | 
			
		||||
            //m_log.DebugFormat("[XXX]: query String: {0}", body);
 | 
			
		||||
| 
						 | 
				
			
			@ -159,7 +158,7 @@ namespace OpenSim.Groups
 | 
			
		|||
            }
 | 
			
		||||
            catch (Exception e)
 | 
			
		||||
            {
 | 
			
		||||
                m_log.Error(string.Format("[Groups.RobustHGConnector]: Exception {0} ", e.Message), e);
 | 
			
		||||
                m_log.DebugFormat("[Groups.RobustHGConnector]: Exception {0}", e.StackTrace);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return FailureResult();
 | 
			
		||||
| 
						 | 
				
			
			@ -210,13 +209,11 @@ namespace OpenSim.Groups
 | 
			
		|||
                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_GroupsService.RemoveAgentFromGroup(agentID, agentID, groupID, token);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
 | 
			
		||||
            result["RESULT"] = "true";
 | 
			
		||||
            return Util.UTF8NoBomEncoding.GetBytes(ServerUtils.BuildXmlResponse(result));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -39,7 +39,7 @@ namespace OpenSim.Groups
 | 
			
		|||
        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<DirGroupsReplyData> FindGroups(string RequestingAgentID, 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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -34,7 +34,6 @@ 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;
 | 
			
		||||
| 
						 | 
				
			
			@ -173,9 +172,9 @@ namespace OpenSim.Groups
 | 
			
		|||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public List<DirGroupsReplyData> FindGroups(string RequestingAgentIDstr, string search)
 | 
			
		||||
        public List<DirGroupsReplyData> FindGroups(string RequestingAgentID, string search)
 | 
			
		||||
        {
 | 
			
		||||
            return m_GroupsService.FindGroups(RequestingAgentIDstr, search);
 | 
			
		||||
            return m_GroupsService.FindGroups(RequestingAgentID, search);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public List<GroupMembersData> GetGroupMembers(string RequestingAgentID, UUID GroupID)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,7 +30,7 @@ using Mono.Addins;
 | 
			
		|||
//      Build Number
 | 
			
		||||
//      Revision
 | 
			
		||||
//
 | 
			
		||||
[assembly: AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)]
 | 
			
		||||
[assembly: AssemblyVersion("0.8.0.*")]
 | 
			
		||||
 | 
			
		||||
[assembly: Addin("OpenSim.Groups", OpenSim.VersionInfo.VersionNumber)]
 | 
			
		||||
[assembly: AddinDependency("OpenSim.Region.Framework", OpenSim.VersionInfo.VersionNumber)]
 | 
			
		||||
[assembly: Addin("OpenSim.Groups", "0.1")]
 | 
			
		||||
[assembly: AddinDependency("OpenSim", "0.5")]
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -32,12 +32,10 @@ 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
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -46,33 +44,15 @@ namespace OpenSim.Groups
 | 
			
		|||
        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)
 | 
			
		||||
        public GroupsServiceRemoteConnector(string url)
 | 
			
		||||
        {
 | 
			
		||||
            IConfig groupsConfig = config.Configs["Groups"];
 | 
			
		||||
            string url = groupsConfig.GetString("GroupsServerURI", string.Empty);
 | 
			
		||||
            if (!Uri.IsWellFormedUriString(url, UriKind.Absolute))
 | 
			
		||||
                throw new Exception(string.Format("[Groups.RemoteConnector]: Malformed groups server URL {0}. Fix it or disable the Groups feature.", url));
 | 
			
		||||
 | 
			
		||||
            m_ServerURI = url;
 | 
			
		||||
            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()));
 | 
			
		||||
            m_log.DebugFormat("[Groups.RemoteConnector]: Groups server at {0}", m_ServerURI);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public ExtendedGroupRecord CreateGroup(string RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment,
 | 
			
		||||
| 
						 | 
				
			
			@ -126,7 +106,7 @@ namespace OpenSim.Groups
 | 
			
		|||
            sendData["OP"] = "UPDATE";
 | 
			
		||||
            Dictionary<string, object> ret = MakeRequest("PUTGROUP", sendData);
 | 
			
		||||
 | 
			
		||||
            if (ret == null || (ret != null && (!ret.ContainsKey("RESULT") || ret["RESULT"].ToString() == "NULL")))
 | 
			
		||||
            if (ret == null || (ret != null && ret["RESULT"].ToString() == "NULL"))
 | 
			
		||||
                return null;
 | 
			
		||||
 | 
			
		||||
            return GroupsDataUtils.GroupRecord((Dictionary<string, object>)ret["RESULT"]);
 | 
			
		||||
| 
						 | 
				
			
			@ -147,13 +127,13 @@ namespace OpenSim.Groups
 | 
			
		|||
 | 
			
		||||
            Dictionary<string, object> ret = MakeRequest("GETGROUP", sendData);
 | 
			
		||||
 | 
			
		||||
            if (ret == null || (ret != null && (!ret.ContainsKey("RESULT") || ret["RESULT"].ToString() == "NULL")))
 | 
			
		||||
            if (ret == null || (ret != null && ret["RESULT"].ToString() == "NULL"))
 | 
			
		||||
                return null;
 | 
			
		||||
 | 
			
		||||
            return GroupsDataUtils.GroupRecord((Dictionary<string, object>)ret["RESULT"]);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public List<DirGroupsReplyData> FindGroups(string RequestingAgentIDstr, string query)
 | 
			
		||||
        public List<DirGroupsReplyData> FindGroups(string RequestingAgentID, string query)
 | 
			
		||||
        {
 | 
			
		||||
            List<DirGroupsReplyData> hits = new List<DirGroupsReplyData>();
 | 
			
		||||
            if (string.IsNullOrEmpty(query))
 | 
			
		||||
| 
						 | 
				
			
			@ -161,7 +141,7 @@ namespace OpenSim.Groups
 | 
			
		|||
 | 
			
		||||
            Dictionary<string, object> sendData = new Dictionary<string, object>();
 | 
			
		||||
            sendData["Query"] = query;
 | 
			
		||||
            sendData["RequestingAgentID"] = RequestingAgentIDstr;
 | 
			
		||||
            sendData["RequestingAgentID"] = RequestingAgentID;
 | 
			
		||||
 | 
			
		||||
            Dictionary<string, object> ret = MakeRequest("FINDGROUPS", sendData);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -287,7 +267,6 @@ namespace OpenSim.Groups
 | 
			
		|||
 | 
			
		||||
            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);
 | 
			
		||||
| 
						 | 
				
			
			@ -378,7 +357,6 @@ namespace OpenSim.Groups
 | 
			
		|||
 | 
			
		||||
            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);
 | 
			
		||||
| 
						 | 
				
			
			@ -679,8 +657,7 @@ namespace OpenSim.Groups
 | 
			
		|||
            lock (m_Lock)
 | 
			
		||||
                reply = SynchronousRestFormsRequester.MakeRequest("POST",
 | 
			
		||||
                         m_ServerURI + "groups",
 | 
			
		||||
                         ServerUtils.BuildQueryString(sendData),
 | 
			
		||||
                         m_Auth);
 | 
			
		||||
                         ServerUtils.BuildQueryString(sendData));
 | 
			
		||||
 | 
			
		||||
            if (reply == string.Empty)
 | 
			
		||||
                return null;
 | 
			
		||||
| 
						 | 
				
			
			@ -690,7 +667,7 @@ namespace OpenSim.Groups
 | 
			
		|||
 | 
			
		||||
            return replyData;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        #endregion
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -36,7 +36,6 @@ 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;
 | 
			
		||||
| 
						 | 
				
			
			@ -73,7 +72,12 @@ namespace OpenSim.Groups
 | 
			
		|||
 | 
			
		||||
        private void Init(IConfigSource config)
 | 
			
		||||
        {
 | 
			
		||||
            m_GroupsService = new GroupsServiceRemoteConnector(config);
 | 
			
		||||
            IConfig groupsConfig = config.Configs["Groups"];
 | 
			
		||||
            string url = groupsConfig.GetString("GroupsServerURI", string.Empty);
 | 
			
		||||
            if (!Uri.IsWellFormedUriString(url, UriKind.Absolute))
 | 
			
		||||
                throw new Exception(string.Format("[Groups.RemoteConnector]: Malformed groups server URL {0}. Fix it or disable the Groups feature.", url));
 | 
			
		||||
 | 
			
		||||
            m_GroupsService = new GroupsServiceRemoteConnector(url);
 | 
			
		||||
            m_Scenes = new List<Scene>();
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -192,10 +196,10 @@ namespace OpenSim.Groups
 | 
			
		|||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public List<DirGroupsReplyData> FindGroups(string RequestingAgentIDstr, string search)
 | 
			
		||||
        public List<DirGroupsReplyData> FindGroups(string RequestingAgentID, string search)
 | 
			
		||||
        {
 | 
			
		||||
            // TODO!
 | 
			
		||||
            return m_GroupsService.FindGroups(RequestingAgentIDstr, search);
 | 
			
		||||
            return m_GroupsService.FindGroups(RequestingAgentID, search);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool AddAgentToGroup(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID, string token, out string reason)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -36,7 +36,6 @@ 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;
 | 
			
		||||
| 
						 | 
				
			
			@ -53,26 +52,14 @@ namespace OpenSim.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));
 | 
			
		||||
            server.AddStreamHandler(new GroupsServicePostHandler(m_GroupsService));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -82,8 +69,8 @@ namespace OpenSim.Groups
 | 
			
		|||
 | 
			
		||||
        private GroupsService m_GroupsService;
 | 
			
		||||
 | 
			
		||||
        public GroupsServicePostHandler(GroupsService service, IServiceAuth auth) :
 | 
			
		||||
            base("POST", "/groups", auth)
 | 
			
		||||
        public GroupsServicePostHandler(GroupsService service) :
 | 
			
		||||
            base("POST", "/groups")
 | 
			
		||||
        {
 | 
			
		||||
            m_GroupsService = service;
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -91,10 +78,9 @@ namespace OpenSim.Groups
 | 
			
		|||
        protected override byte[] ProcessRequest(string path, Stream requestData,
 | 
			
		||||
                IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
 | 
			
		||||
        {
 | 
			
		||||
            string body;
 | 
			
		||||
            using(StreamReader sr = new StreamReader(requestData))
 | 
			
		||||
                body = sr.ReadToEnd();
 | 
			
		||||
 | 
			
		||||
            StreamReader sr = new StreamReader(requestData);
 | 
			
		||||
            string body = sr.ReadToEnd();
 | 
			
		||||
            sr.Close();
 | 
			
		||||
            body = body.Trim();
 | 
			
		||||
 | 
			
		||||
            //m_log.DebugFormat("[XXX]: query String: {0}", body);
 | 
			
		||||
| 
						 | 
				
			
			@ -110,7 +96,7 @@ namespace OpenSim.Groups
 | 
			
		|||
                string method = request["METHOD"].ToString();
 | 
			
		||||
                request.Remove("METHOD");
 | 
			
		||||
 | 
			
		||||
//                m_log.DebugFormat("[Groups.Handler]: {0}", method);
 | 
			
		||||
                m_log.DebugFormat("[Groups.Handler]: {0}", method);
 | 
			
		||||
                switch (method)
 | 
			
		||||
                {
 | 
			
		||||
                    case "PUTGROUP":
 | 
			
		||||
| 
						 | 
				
			
			@ -154,7 +140,7 @@ namespace OpenSim.Groups
 | 
			
		|||
            }
 | 
			
		||||
            catch (Exception e)
 | 
			
		||||
            {
 | 
			
		||||
                m_log.Error(string.Format("[GROUPS HANDLER]: Exception {0} ", e.Message), e);
 | 
			
		||||
                m_log.DebugFormat("[GROUPS HANDLER]: Exception {0}", e.StackTrace);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return FailureResult();
 | 
			
		||||
| 
						 | 
				
			
			@ -286,13 +272,11 @@ namespace OpenSim.Groups
 | 
			
		|||
                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_GroupsService.RemoveAgentFromGroup(requestingAgentID, agentID, groupID);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
 | 
			
		||||
            result["RESULT"] = "true";
 | 
			
		||||
            return Util.UTF8NoBomEncoding.GetBytes(ServerUtils.BuildXmlResponse(result));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -668,11 +652,7 @@ namespace OpenSim.Groups
 | 
			
		|||
                    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";
 | 
			
		||||
 | 
			
		||||
                    result["RESULT"] = GroupsDataUtils.GroupInviteInfo(invite);
 | 
			
		||||
                    return Util.UTF8NoBomEncoding.GetBytes(ServerUtils.BuildXmlResponse(result));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -804,14 +784,6 @@ namespace OpenSim.Groups
 | 
			
		|||
            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
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -31,8 +31,7 @@ using System.Reflection;
 | 
			
		|||
using System.Threading;
 | 
			
		||||
 | 
			
		||||
using OpenSim.Framework;
 | 
			
		||||
//using OpenSim.Region.Framework.Interfaces;
 | 
			
		||||
using OpenSim.Services.Interfaces;
 | 
			
		||||
using OpenSim.Region.Framework.Interfaces;
 | 
			
		||||
 | 
			
		||||
using OpenMetaverse;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -145,20 +144,14 @@ namespace OpenSim.Groups
 | 
			
		|||
 | 
			
		||||
                if (firstCall)
 | 
			
		||||
                {
 | 
			
		||||
                    try
 | 
			
		||||
                    {
 | 
			
		||||
                        //group = m_GroupsService.GetGroupRecord(RequestingAgentID, GroupID, GroupName);
 | 
			
		||||
                        group = d();
 | 
			
		||||
                    //group = m_GroupsService.GetGroupRecord(RequestingAgentID, GroupID, GroupName);
 | 
			
		||||
                    group = d();
 | 
			
		||||
 | 
			
		||||
                        lock (m_Cache)
 | 
			
		||||
                        {
 | 
			
		||||
                            m_Cache.AddOrUpdate(cacheKey, group, GROUPS_CACHE_TIMEOUT);
 | 
			
		||||
                            return (ExtendedGroupRecord)group;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    finally
 | 
			
		||||
                    lock (m_Cache)
 | 
			
		||||
                    {
 | 
			
		||||
                        m_Cache.AddOrUpdate(cacheKey, group, GROUPS_CACHE_TIMEOUT);
 | 
			
		||||
                        m_ActiveRequests.Remove(cacheKey);
 | 
			
		||||
                        return (ExtendedGroupRecord)group;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
| 
						 | 
				
			
			@ -250,19 +243,13 @@ namespace OpenSim.Groups
 | 
			
		|||
 | 
			
		||||
                if (firstCall)
 | 
			
		||||
                {
 | 
			
		||||
                    try
 | 
			
		||||
                    {
 | 
			
		||||
                        membership = d();
 | 
			
		||||
                    membership = d();
 | 
			
		||||
 | 
			
		||||
                        lock (m_Cache)
 | 
			
		||||
                        {
 | 
			
		||||
                            m_Cache.AddOrUpdate(cacheKey, membership, GROUPS_CACHE_TIMEOUT);
 | 
			
		||||
                            return (ExtendedGroupMembershipData)membership;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    finally
 | 
			
		||||
                    lock (m_Cache)
 | 
			
		||||
                    {
 | 
			
		||||
                        m_Cache.AddOrUpdate(cacheKey, membership, GROUPS_CACHE_TIMEOUT);
 | 
			
		||||
                        m_ActiveRequests.Remove(cacheKey);
 | 
			
		||||
                        return (ExtendedGroupMembershipData)membership;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
| 
						 | 
				
			
			@ -299,18 +286,12 @@ namespace OpenSim.Groups
 | 
			
		|||
 | 
			
		||||
                if (firstCall)
 | 
			
		||||
                {
 | 
			
		||||
                    try
 | 
			
		||||
                    {
 | 
			
		||||
                        membership = d();
 | 
			
		||||
                        lock (m_Cache)
 | 
			
		||||
                        {
 | 
			
		||||
                            m_Cache.AddOrUpdate(cacheKey, membership, GROUPS_CACHE_TIMEOUT);
 | 
			
		||||
                            return (ExtendedGroupMembershipData)membership;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    finally
 | 
			
		||||
                    membership = d();
 | 
			
		||||
                    lock (m_Cache)
 | 
			
		||||
                    {
 | 
			
		||||
                        m_Cache.AddOrUpdate(cacheKey, membership, GROUPS_CACHE_TIMEOUT);
 | 
			
		||||
                        m_ActiveRequests.Remove(cacheKey);
 | 
			
		||||
                        return (ExtendedGroupMembershipData)membership;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
| 
						 | 
				
			
			@ -346,18 +327,12 @@ namespace OpenSim.Groups
 | 
			
		|||
 | 
			
		||||
                if (firstCall)
 | 
			
		||||
                {
 | 
			
		||||
                    try
 | 
			
		||||
                    {
 | 
			
		||||
                        memberships = d();
 | 
			
		||||
                        lock (m_Cache)
 | 
			
		||||
                        {
 | 
			
		||||
                            m_Cache.AddOrUpdate(cacheKey, memberships, GROUPS_CACHE_TIMEOUT);
 | 
			
		||||
                            return (List<GroupMembershipData>)memberships;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    finally
 | 
			
		||||
                    memberships = d();
 | 
			
		||||
                    lock (m_Cache)
 | 
			
		||||
                    {
 | 
			
		||||
                        m_Cache.AddOrUpdate(cacheKey, memberships, GROUPS_CACHE_TIMEOUT);
 | 
			
		||||
                        m_ActiveRequests.Remove(cacheKey);
 | 
			
		||||
                        return (List<GroupMembershipData>)memberships;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
| 
						 | 
				
			
			@ -394,26 +369,20 @@ namespace OpenSim.Groups
 | 
			
		|||
 | 
			
		||||
                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
 | 
			
		||||
                    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);
 | 
			
		||||
                        m_ActiveRequests.Remove(cacheKey);
 | 
			
		||||
 | 
			
		||||
                        return (List<GroupMembersData>)members;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
| 
						 | 
				
			
			@ -528,22 +497,16 @@ namespace OpenSim.Groups
 | 
			
		|||
 | 
			
		||||
                if (firstCall)
 | 
			
		||||
                {
 | 
			
		||||
                    try
 | 
			
		||||
                    roles = d();
 | 
			
		||||
                    if (roles != null)
 | 
			
		||||
                    {
 | 
			
		||||
                        roles = d();
 | 
			
		||||
                        if (roles != null)
 | 
			
		||||
                        lock (m_Cache)
 | 
			
		||||
                        {
 | 
			
		||||
                            lock (m_Cache)
 | 
			
		||||
                            {
 | 
			
		||||
                                m_Cache.AddOrUpdate(cacheKey, roles, GROUPS_CACHE_TIMEOUT);
 | 
			
		||||
                                return (List<GroupRolesData>)roles;
 | 
			
		||||
                            }
 | 
			
		||||
                            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);
 | 
			
		||||
| 
						 | 
				
			
			@ -578,29 +541,23 @@ namespace OpenSim.Groups
 | 
			
		|||
 | 
			
		||||
                if (firstCall)
 | 
			
		||||
                {
 | 
			
		||||
                    try
 | 
			
		||||
                    {
 | 
			
		||||
                        List<ExtendedGroupRoleMembersData> _rmembers = d();
 | 
			
		||||
                    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>();
 | 
			
		||||
                    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
 | 
			
		||||
                    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);
 | 
			
		||||
                        m_ActiveRequests.Remove(cacheKey);
 | 
			
		||||
                        return (List<GroupRoleMembersData>)rmembers;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
| 
						 | 
				
			
			@ -709,19 +666,12 @@ namespace OpenSim.Groups
 | 
			
		|||
 | 
			
		||||
                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
 | 
			
		||||
                    roles = d();
 | 
			
		||||
                    lock (m_Cache)
 | 
			
		||||
                    {
 | 
			
		||||
                        m_Cache.AddOrUpdate(cacheKey, roles, GROUPS_CACHE_TIMEOUT);
 | 
			
		||||
                        m_ActiveRequests.Remove(cacheKey);
 | 
			
		||||
                        return (List<GroupRolesData>)roles;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
| 
						 | 
				
			
			@ -817,19 +767,13 @@ namespace OpenSim.Groups
 | 
			
		|||
 | 
			
		||||
                if (firstCall)
 | 
			
		||||
                {
 | 
			
		||||
                    try
 | 
			
		||||
                    {
 | 
			
		||||
                        GroupNoticeInfo _notice = d();
 | 
			
		||||
                    GroupNoticeInfo _notice = d();
 | 
			
		||||
 | 
			
		||||
                        lock (m_Cache)
 | 
			
		||||
                        {
 | 
			
		||||
                            m_Cache.AddOrUpdate(cacheKey, _notice, GROUPS_CACHE_TIMEOUT);
 | 
			
		||||
                            return _notice;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    finally
 | 
			
		||||
                    lock (m_Cache)
 | 
			
		||||
                    {
 | 
			
		||||
                        m_Cache.AddOrUpdate(cacheKey, _notice, GROUPS_CACHE_TIMEOUT);
 | 
			
		||||
                        m_ActiveRequests.Remove(cacheKey);
 | 
			
		||||
                        return _notice;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
| 
						 | 
				
			
			@ -865,24 +809,20 @@ namespace OpenSim.Groups
 | 
			
		|||
 | 
			
		||||
                if (firstCall)
 | 
			
		||||
                {
 | 
			
		||||
                    try
 | 
			
		||||
                    {
 | 
			
		||||
                        notices = d();
 | 
			
		||||
                    notices = d();
 | 
			
		||||
 | 
			
		||||
                        lock (m_Cache)
 | 
			
		||||
                        {
 | 
			
		||||
                            m_Cache.AddOrUpdate(cacheKey, notices, GROUPS_CACHE_TIMEOUT);
 | 
			
		||||
                            return (List<ExtendedGroupNoticeData>)notices;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    finally
 | 
			
		||||
                    lock (m_Cache)
 | 
			
		||||
                    {
 | 
			
		||||
                        m_Cache.AddOrUpdate(cacheKey, notices, GROUPS_CACHE_TIMEOUT);
 | 
			
		||||
                        m_ActiveRequests.Remove(cacheKey);
 | 
			
		||||
                        return (List<ExtendedGroupNoticeData>)notices;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                    Thread.Sleep(50);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -43,63 +43,59 @@ namespace OpenSim.Groups
 | 
			
		|||
    {
 | 
			
		||||
        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 | 
			
		||||
 | 
			
		||||
        public const GroupPowers DefaultEveryonePowers =
 | 
			
		||||
            GroupPowers.AllowSetHome |
 | 
			
		||||
            GroupPowers.Accountable |
 | 
			
		||||
            GroupPowers.JoinChat |
 | 
			
		||||
            GroupPowers.AllowVoiceChat |
 | 
			
		||||
            GroupPowers.ReceiveNotices |
 | 
			
		||||
            GroupPowers.StartProposal |
 | 
			
		||||
            GroupPowers.VoteOnProposal;
 | 
			
		||||
        public const GroupPowers DefaultEveryonePowers = GroupPowers.AllowSetHome |
 | 
			
		||||
                                                         GroupPowers.Accountable |
 | 
			
		||||
                                                         GroupPowers.JoinChat |
 | 
			
		||||
                                                         GroupPowers.AllowVoiceChat |
 | 
			
		||||
                                                         GroupPowers.ReceiveNotices |
 | 
			
		||||
                                                         GroupPowers.StartProposal |
 | 
			
		||||
                                                         GroupPowers.VoteOnProposal;
 | 
			
		||||
 | 
			
		||||
        public const GroupPowers OfficersPowers = DefaultEveryonePowers |
 | 
			
		||||
            GroupPowers.AllowFly |
 | 
			
		||||
            GroupPowers.AllowLandmark |
 | 
			
		||||
            GroupPowers.AllowRez |
 | 
			
		||||
            GroupPowers.AssignMemberLimited |
 | 
			
		||||
            GroupPowers.ChangeIdentity |
 | 
			
		||||
            GroupPowers.ChangeMedia |
 | 
			
		||||
            GroupPowers.ChangeOptions |
 | 
			
		||||
            GroupPowers.DeedObject |
 | 
			
		||||
            GroupPowers.Eject |
 | 
			
		||||
            GroupPowers.FindPlaces |
 | 
			
		||||
            GroupPowers.Invite |
 | 
			
		||||
            GroupPowers.LandChangeIdentity |
 | 
			
		||||
            GroupPowers.LandDeed |
 | 
			
		||||
            GroupPowers.LandDivideJoin |
 | 
			
		||||
            GroupPowers.LandEdit |
 | 
			
		||||
            GroupPowers.AllowEnvironment |
 | 
			
		||||
            GroupPowers.LandEjectAndFreeze |
 | 
			
		||||
            GroupPowers.LandGardening |
 | 
			
		||||
            GroupPowers.LandManageAllowed |
 | 
			
		||||
            GroupPowers.LandManageBanned |
 | 
			
		||||
            GroupPowers.LandManagePasses |
 | 
			
		||||
            GroupPowers.LandOptions |
 | 
			
		||||
            GroupPowers.LandRelease |
 | 
			
		||||
            GroupPowers.LandSetSale |
 | 
			
		||||
            GroupPowers.MemberVisible |
 | 
			
		||||
            GroupPowers.ModerateChat |
 | 
			
		||||
            GroupPowers.ObjectManipulate |
 | 
			
		||||
            GroupPowers.ObjectSetForSale |
 | 
			
		||||
            GroupPowers.ReturnGroupOwned |
 | 
			
		||||
            GroupPowers.ReturnGroupSet |
 | 
			
		||||
            GroupPowers.ReturnNonGroup |
 | 
			
		||||
            GroupPowers.RoleProperties |
 | 
			
		||||
            GroupPowers.SendNotices |
 | 
			
		||||
            GroupPowers.SetLandingPoint;
 | 
			
		||||
 | 
			
		||||
        public const GroupPowers OwnerPowers = OfficersPowers | 
 | 
			
		||||
            GroupPowers.Accountable |
 | 
			
		||||
            GroupPowers.AllowEditLand |
 | 
			
		||||
            GroupPowers.AssignMember |
 | 
			
		||||
            GroupPowers.ChangeActions |
 | 
			
		||||
            GroupPowers.CreateRole |
 | 
			
		||||
            GroupPowers.DeleteRole |
 | 
			
		||||
            GroupPowers.ExperienceAdmin |
 | 
			
		||||
            GroupPowers.ExperienceCreator |
 | 
			
		||||
            GroupPowers.GroupBanAccess |
 | 
			
		||||
            GroupPowers.HostEvent |
 | 
			
		||||
            GroupPowers.RemoveMember;
 | 
			
		||||
        public const GroupPowers OwnerPowers = GroupPowers.Accountable |
 | 
			
		||||
                                                GroupPowers.AllowEditLand |
 | 
			
		||||
                                                GroupPowers.AllowFly |
 | 
			
		||||
                                                GroupPowers.AllowLandmark |
 | 
			
		||||
                                                GroupPowers.AllowRez |
 | 
			
		||||
                                                GroupPowers.AllowSetHome |
 | 
			
		||||
                                                GroupPowers.AllowVoiceChat |
 | 
			
		||||
                                                GroupPowers.AssignMember |
 | 
			
		||||
                                                GroupPowers.AssignMemberLimited |
 | 
			
		||||
                                                GroupPowers.ChangeActions |
 | 
			
		||||
                                                GroupPowers.ChangeIdentity |
 | 
			
		||||
                                                GroupPowers.ChangeMedia |
 | 
			
		||||
                                                GroupPowers.ChangeOptions |
 | 
			
		||||
                                                GroupPowers.CreateRole |
 | 
			
		||||
                                                GroupPowers.DeedObject |
 | 
			
		||||
                                                GroupPowers.DeleteRole |
 | 
			
		||||
                                                GroupPowers.Eject |
 | 
			
		||||
                                                GroupPowers.FindPlaces |
 | 
			
		||||
                                                GroupPowers.Invite |
 | 
			
		||||
                                                GroupPowers.JoinChat |
 | 
			
		||||
                                                GroupPowers.LandChangeIdentity |
 | 
			
		||||
                                                GroupPowers.LandDeed |
 | 
			
		||||
                                                GroupPowers.LandDivideJoin |
 | 
			
		||||
                                                GroupPowers.LandEdit |
 | 
			
		||||
                                                GroupPowers.LandEjectAndFreeze |
 | 
			
		||||
                                                GroupPowers.LandGardening |
 | 
			
		||||
                                                GroupPowers.LandManageAllowed |
 | 
			
		||||
                                                GroupPowers.LandManageBanned |
 | 
			
		||||
                                                GroupPowers.LandManagePasses |
 | 
			
		||||
                                                GroupPowers.LandOptions |
 | 
			
		||||
                                                GroupPowers.LandRelease |
 | 
			
		||||
                                                GroupPowers.LandSetSale |
 | 
			
		||||
                                                GroupPowers.ModerateChat |
 | 
			
		||||
                                                GroupPowers.ObjectManipulate |
 | 
			
		||||
                                                GroupPowers.ObjectSetForSale |
 | 
			
		||||
                                                GroupPowers.ReceiveNotices |
 | 
			
		||||
                                                GroupPowers.RemoveMember |
 | 
			
		||||
                                                GroupPowers.ReturnGroupOwned |
 | 
			
		||||
                                                GroupPowers.ReturnGroupSet |
 | 
			
		||||
                                                GroupPowers.ReturnNonGroup |
 | 
			
		||||
                                                GroupPowers.RoleProperties |
 | 
			
		||||
                                                GroupPowers.SendNotices |
 | 
			
		||||
                                                GroupPowers.SetLandingPoint |
 | 
			
		||||
                                                GroupPowers.StartProposal |
 | 
			
		||||
                                                GroupPowers.VoteOnProposal;
 | 
			
		||||
 | 
			
		||||
        #region Daily Cleanup
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -154,25 +150,20 @@ namespace OpenSim.Groups
 | 
			
		|||
            data.Data["ShowInList"] = showInList ? "1" : "0";
 | 
			
		||||
            data.Data["AllowPublish"] = allowPublish ? "1" : "0";
 | 
			
		||||
            data.Data["MaturePublish"] = maturePublish ? "1" : "0";
 | 
			
		||||
            UUID ownerRoleID = UUID.Random();
 | 
			
		||||
            data.Data["OwnerRoleID"] = ownerRoleID.ToString();
 | 
			
		||||
            data.Data["OwnerRoleID"] = UUID.Random().ToString();
 | 
			
		||||
 | 
			
		||||
            if (!m_Database.StoreGroup(data))
 | 
			
		||||
                return UUID.Zero;
 | 
			
		||||
 | 
			
		||||
            // Create Everyone role
 | 
			
		||||
            _AddOrUpdateGroupRole(RequestingAgentID, data.GroupID, UUID.Zero, "Everyone", "Everyone in the group is in the everyone role.", "Member of " + name, (ulong)DefaultEveryonePowers, true);
 | 
			
		||||
 | 
			
		||||
            // Create Officers role
 | 
			
		||||
            UUID officersRoleID = UUID.Random();
 | 
			
		||||
            _AddOrUpdateGroupRole(RequestingAgentID, data.GroupID, officersRoleID, "Officers", "The officers of the group, with more powers than regular members.", "Officer of " + name, (ulong)OfficersPowers, true);
 | 
			
		||||
            _AddOrUpdateGroupRole(RequestingAgentID, data.GroupID, UUID.Zero, "Everyone", "Everyone in the group", "Member of " + name, (ulong)DefaultEveryonePowers, true);
 | 
			
		||||
 | 
			
		||||
            // Create Owner role
 | 
			
		||||
            _AddOrUpdateGroupRole(RequestingAgentID, data.GroupID, ownerRoleID, "Owners", "Owners of the group", "Owner of " + name, (ulong)OwnerPowers, true);
 | 
			
		||||
            UUID roleID = UUID.Random();
 | 
			
		||||
            _AddOrUpdateGroupRole(RequestingAgentID, data.GroupID, roleID, "Owners", "Owners of the group", "Owner of " + name, (ulong)OwnerPowers, true);
 | 
			
		||||
 | 
			
		||||
            // Add founder to group
 | 
			
		||||
            _AddAgentToGroup(RequestingAgentID, founderID.ToString(), data.GroupID, ownerRoleID);
 | 
			
		||||
            _AddAgentToGroup(RequestingAgentID, founderID.ToString(), data.GroupID, officersRoleID);
 | 
			
		||||
            _AddAgentToGroup(RequestingAgentID, founderID.ToString(), data.GroupID, roleID);
 | 
			
		||||
 | 
			
		||||
            return data.GroupID;
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -231,22 +222,15 @@ namespace OpenSim.Groups
 | 
			
		|||
                    if (d.Data.ContainsKey("Location") && d.Data["Location"] != string.Empty)
 | 
			
		||||
                        continue;
 | 
			
		||||
 | 
			
		||||
                    int nmembers = m_Database.MemberCount(d.GroupID);
 | 
			
		||||
                    if(nmembers == 0)
 | 
			
		||||
                        continue;
 | 
			
		||||
 | 
			
		||||
                    DirGroupsReplyData g = new DirGroupsReplyData();
 | 
			
		||||
                    g.groupID = d.GroupID;
 | 
			
		||||
 | 
			
		||||
                    if (d.Data.ContainsKey("Name"))
 | 
			
		||||
                        g.groupName = d.Data["Name"];
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        m_log.DebugFormat("[Groups]: Key Name not found");
 | 
			
		||||
                        continue;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    g.groupID = d.GroupID;
 | 
			
		||||
                    g.members = nmembers;
 | 
			
		||||
                    g.members = m_Database.MemberCount(d.GroupID);
 | 
			
		||||
 | 
			
		||||
                    groups.Add(g);
 | 
			
		||||
                }
 | 
			
		||||
| 
						 | 
				
			
			@ -263,9 +247,6 @@ namespace OpenSim.Groups
 | 
			
		|||
            if (group == null)
 | 
			
		||||
                return members;
 | 
			
		||||
 | 
			
		||||
            // Unfortunately this doesn't quite work on legacy group data because of a bug
 | 
			
		||||
            // that's also being fixed here on CreateGroup. The OwnerRoleID sent to the DB was wrong.
 | 
			
		||||
            // See how to find the ownerRoleID a few lines below.
 | 
			
		||||
            UUID ownerRoleID = new UUID(group.Data["OwnerRoleID"]);
 | 
			
		||||
 | 
			
		||||
            RoleData[] roles = m_Database.RetrieveRoles(GroupID);
 | 
			
		||||
| 
						 | 
				
			
			@ -274,11 +255,6 @@ namespace OpenSim.Groups
 | 
			
		|||
                return members;
 | 
			
		||||
            List<RoleData> rolesList = new List<RoleData>(roles);
 | 
			
		||||
 | 
			
		||||
            // Let's find the "real" ownerRoleID
 | 
			
		||||
            RoleData ownerRole = rolesList.Find(r => r.Data["Powers"] == ((long)OwnerPowers).ToString());
 | 
			
		||||
            if (ownerRole != null)
 | 
			
		||||
                ownerRoleID = ownerRole.RoleID;
 | 
			
		||||
 | 
			
		||||
            // Check visibility? 
 | 
			
		||||
            // When we don't want to check visibility, we pass it "all" as the requestingAgentID
 | 
			
		||||
            bool checkVisibility = !RequestingAgentID.Equals(UUID.Zero.ToString());
 | 
			
		||||
| 
						 | 
				
			
			@ -315,32 +291,17 @@ namespace OpenSim.Groups
 | 
			
		|||
                {
 | 
			
		||||
                    m.Title = selected.Data["Title"];
 | 
			
		||||
                    m.AgentPowers = UInt64.Parse(selected.Data["Powers"]);
 | 
			
		||||
 | 
			
		||||
                    m.AgentID = d.PrincipalID;
 | 
			
		||||
                    m.AcceptNotices = d.Data["AcceptNotices"] == "1" ? true : false;
 | 
			
		||||
                    m.Contribution = Int32.Parse(d.Data["Contribution"]);
 | 
			
		||||
                    m.ListInProfile = d.Data["ListInProfile"] == "1" ? true : false;
 | 
			
		||||
 | 
			
		||||
                    // Is this person an owner of the group?
 | 
			
		||||
                    m.IsOwner = (rolemembershipsList.Find(r => r.RoleID == ownerRoleID) != null) ? true : false;
 | 
			
		||||
 | 
			
		||||
                    members.Add(m);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                m.AgentID = d.PrincipalID;
 | 
			
		||||
                m.AcceptNotices = d.Data["AcceptNotices"] == "1" ? true : false;
 | 
			
		||||
                m.Contribution = Int32.Parse(d.Data["Contribution"]);
 | 
			
		||||
                m.ListInProfile = d.Data["ListInProfile"] == "1" ? true : false;
 | 
			
		||||
 | 
			
		||||
                GridUserData gud = m_GridUserService.Get(d.PrincipalID);
 | 
			
		||||
                if (gud != null)
 | 
			
		||||
                {
 | 
			
		||||
                    if (bool.Parse(gud.Data["Online"]))
 | 
			
		||||
                    {
 | 
			
		||||
                        m.OnlineStatus = @"Online";
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        int unixtime = int.Parse(gud.Data["Login"]);
 | 
			
		||||
                        // The viewer is very picky about how these strings are formed. Eg. it will crash on malformed dates!
 | 
			
		||||
                        m.OnlineStatus = (unixtime == 0) ? @"unknown" : Util.ToDateTime(unixtime).ToString("MM/dd/yyyy");
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // Is this person an owner of the group?
 | 
			
		||||
                m.IsOwner = (rolemembershipsList.Find(r => r.RoleID == ownerRoleID) != null) ? true : false;
 | 
			
		||||
 | 
			
		||||
                members.Add(m);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return members;
 | 
			
		||||
| 
						 | 
				
			
			@ -432,15 +393,13 @@ namespace OpenSim.Groups
 | 
			
		|||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool RemoveAgentFromGroup(string RequestingAgentID, string AgentID, UUID GroupID)
 | 
			
		||||
        public void RemoveAgentFromGroup(string RequestingAgentID, string AgentID, UUID GroupID)
 | 
			
		||||
        {
 | 
			
		||||
            // check perms
 | 
			
		||||
            if (RequestingAgentID != AgentID && !HasPower(RequestingAgentID, GroupID, GroupPowers.Eject))
 | 
			
		||||
                return false;
 | 
			
		||||
                    return;
 | 
			
		||||
 | 
			
		||||
            _RemoveAgentFromGroup(RequestingAgentID, AgentID, GroupID);
 | 
			
		||||
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool AddAgentToGroupInvite(string RequestingAgentID, UUID inviteID, UUID groupID, UUID roleID, string agentID)
 | 
			
		||||
| 
						 | 
				
			
			@ -500,8 +459,8 @@ namespace OpenSim.Groups
 | 
			
		|||
 | 
			
		||||
            // check permissions
 | 
			
		||||
            bool limited = HasPower(RequestingAgentID, GroupID, GroupPowers.AssignMemberLimited);
 | 
			
		||||
            bool unlimited = HasPower(RequestingAgentID, GroupID, GroupPowers.AssignMember) || IsOwner(RequestingAgentID, GroupID);
 | 
			
		||||
            if (!limited && !unlimited)
 | 
			
		||||
            bool unlimited = HasPower(RequestingAgentID, GroupID, GroupPowers.AssignMember) | IsOwner(RequestingAgentID, GroupID);
 | 
			
		||||
            if (!limited || !unlimited)
 | 
			
		||||
            {
 | 
			
		||||
                m_log.DebugFormat("[Groups]: ({0}) Attempt at assigning {1} to role {2} denied because of lack of permission", RequestingAgentID, AgentID, RoleID);
 | 
			
		||||
                return false;
 | 
			
		||||
| 
						 | 
				
			
			@ -511,7 +470,7 @@ namespace OpenSim.Groups
 | 
			
		|||
            if (!unlimited && limited)
 | 
			
		||||
            {
 | 
			
		||||
                // check whether person's has this role
 | 
			
		||||
                RoleMembershipData rolemembership = m_Database.RetrieveRoleMember(GroupID, RoleID, RequestingAgentID);
 | 
			
		||||
                RoleMembershipData rolemembership = m_Database.RetrieveRoleMember(GroupID, RoleID, AgentID);
 | 
			
		||||
                if (rolemembership == null)
 | 
			
		||||
                {
 | 
			
		||||
                    m_log.DebugFormat("[Groups]: ({0}) Attempt at assigning {1} to role {2} denied because of limited permission", RequestingAgentID, AgentID, RoleID);
 | 
			
		||||
| 
						 | 
				
			
			@ -531,26 +490,13 @@ namespace OpenSim.Groups
 | 
			
		|||
                return false;
 | 
			
		||||
 | 
			
		||||
            // check permissions
 | 
			
		||||
            bool limited = HasPower(RequestingAgentID, GroupID, GroupPowers.AssignMemberLimited);
 | 
			
		||||
            bool unlimited = HasPower(RequestingAgentID, GroupID, GroupPowers.AssignMember) || IsOwner(RequestingAgentID, GroupID);
 | 
			
		||||
            if (!limited && !unlimited)
 | 
			
		||||
            if (!unlimited)
 | 
			
		||||
            {
 | 
			
		||||
                m_log.DebugFormat("[Groups]: ({0}) Attempt at removing {1} from role {2} denied because of lack of permission", RequestingAgentID, AgentID, RoleID);
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // AssignMemberLimited means that the person can assign another person to the same roles that she has in the group
 | 
			
		||||
            if (!unlimited && limited)
 | 
			
		||||
            {
 | 
			
		||||
                // check whether person's has this role
 | 
			
		||||
                RoleMembershipData rolemembership = m_Database.RetrieveRoleMember(GroupID, RoleID, RequestingAgentID);
 | 
			
		||||
                if (rolemembership == null)
 | 
			
		||||
                {
 | 
			
		||||
                    m_log.DebugFormat("[Groups]: ({0}) Attempt at removing {1} from role {2} denied because of limited permission", RequestingAgentID, AgentID, RoleID);
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            RoleMembershipData rolemember = m_Database.RetrieveRoleMember(GroupID, RoleID, AgentID);
 | 
			
		||||
 | 
			
		||||
            if (rolemember == null)
 | 
			
		||||
| 
						 | 
				
			
			@ -840,7 +786,7 @@ namespace OpenSim.Groups
 | 
			
		|||
            if (RoleID != UUID.Zero)
 | 
			
		||||
                _AddAgentToGroupRole(RequestingAgentID, AgentID, GroupID, RoleID);
 | 
			
		||||
 | 
			
		||||
            // Make this the active group
 | 
			
		||||
            // Make thit this active group
 | 
			
		||||
            PrincipalData pdata = new PrincipalData();
 | 
			
		||||
            pdata.PrincipalID = AgentID;
 | 
			
		||||
            pdata.ActiveGroupID = GroupID;
 | 
			
		||||
| 
						 | 
				
			
			@ -858,7 +804,7 @@ namespace OpenSim.Groups
 | 
			
		|||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (!add && data == null) // it doesn't exist, can't update
 | 
			
		||||
            if (!add && data == null) // it deosn't exist, can't update
 | 
			
		||||
            {
 | 
			
		||||
                m_log.DebugFormat("[Groups]: Group {0} doesn't exist. Can't update it", groupID);
 | 
			
		||||
                return false;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,4 @@
 | 
			
		|||
/*
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) Contributors, http://opensimulator.org/
 | 
			
		||||
 * See CONTRIBUTORS.TXT for a full list of copyright holders.
 | 
			
		||||
 *
 | 
			
		||||
| 
						 | 
				
			
			@ -38,7 +38,6 @@ 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)
 | 
			
		||||
| 
						 | 
				
			
			@ -46,7 +45,6 @@ namespace OpenSim.Groups
 | 
			
		|||
            string dllName = String.Empty;
 | 
			
		||||
            string connString = String.Empty;
 | 
			
		||||
            string realm = "os_groups";
 | 
			
		||||
            string usersRealm = "GridUser";
 | 
			
		||||
            string configName = (cName == string.Empty) ? "Groups" : cName;
 | 
			
		||||
 | 
			
		||||
            //
 | 
			
		||||
| 
						 | 
				
			
			@ -81,21 +79,6 @@ namespace OpenSim.Groups
 | 
			
		|||
            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);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -131,27 +131,19 @@ namespace OpenSim.Groups
 | 
			
		|||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool RemoveAgentFromGroup(string RequestingAgentID, string AgentID, UUID GroupID, string token)
 | 
			
		||||
        public void RemoveAgentFromGroup(string RequestingAgentID, string AgentID, UUID GroupID, string token)
 | 
			
		||||
        {
 | 
			
		||||
            // check the token
 | 
			
		||||
            MembershipData membership = m_Database.RetrieveMember(GroupID, AgentID);
 | 
			
		||||
            if (membership != null)
 | 
			
		||||
            {
 | 
			
		||||
                if (token != string.Empty && token.Equals(membership.Data["AccessToken"]))
 | 
			
		||||
                {
 | 
			
		||||
                    return RemoveAgentFromGroup(RequestingAgentID, AgentID, GroupID);
 | 
			
		||||
                }
 | 
			
		||||
                    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)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -66,7 +66,7 @@ namespace OpenSim.OfflineIM
 | 
			
		|||
            if (serviceLocation == string.Empty)
 | 
			
		||||
                m_OfflineIMService = new OfflineIMService(config);
 | 
			
		||||
            else
 | 
			
		||||
                m_OfflineIMService = new OfflineIMServiceRemoteConnector(config);
 | 
			
		||||
                m_OfflineIMService = new OfflineIMServiceRemoteConnector(serviceLocation);
 | 
			
		||||
 | 
			
		||||
            m_ForwardOfflineGroupMessages = cnf.GetBoolean("ForwardOfflineGroupMessages", m_ForwardOfflineGroupMessages);
 | 
			
		||||
            m_log.DebugFormat("[OfflineIM.V2]: Offline messages enabled by {0}", Name);
 | 
			
		||||
| 
						 | 
				
			
			@ -114,6 +114,7 @@ namespace OpenSim.OfflineIM
 | 
			
		|||
            scene.ForEachClient(delegate(IClientAPI client)
 | 
			
		||||
            {
 | 
			
		||||
                client.OnRetrieveInstantMessages -= RetrieveInstantMessages;
 | 
			
		||||
                client.OnMuteListRequest -= OnMuteListRequest;
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -161,6 +162,7 @@ namespace OpenSim.OfflineIM
 | 
			
		|||
        private void OnNewClient(IClientAPI client)
 | 
			
		||||
        {
 | 
			
		||||
            client.OnRetrieveInstantMessages += RetrieveInstantMessages;
 | 
			
		||||
            client.OnMuteListRequest += OnMuteListRequest;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void RetrieveInstantMessages(IClientAPI client)
 | 
			
		||||
| 
						 | 
				
			
			@ -192,6 +194,20 @@ namespace OpenSim.OfflineIM
 | 
			
		|||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Apparently this is needed in order for the viewer to request the IMs.
 | 
			
		||||
        private void OnMuteListRequest(IClientAPI client, uint crc)
 | 
			
		||||
        {
 | 
			
		||||
            m_log.DebugFormat("[OfflineIM.V2] Got mute list request for crc {0}", crc);
 | 
			
		||||
            string filename = "mutes" + client.AgentId.ToString();
 | 
			
		||||
 | 
			
		||||
            IXfer xfer = client.Scene.RequestModuleInterface<IXfer>();
 | 
			
		||||
            if (xfer != null)
 | 
			
		||||
            {
 | 
			
		||||
                xfer.AddNewFile(filename, new Byte[0]);
 | 
			
		||||
                client.SendMuteListUpdate(filename);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void UndeliveredMessage(GridInstantMessage im)
 | 
			
		||||
        {
 | 
			
		||||
            if (im.dialog != (byte)InstantMessageDialog.MessageFromObject &&
 | 
			
		||||
| 
						 | 
				
			
			@ -210,6 +226,10 @@ namespace OpenSim.OfflineIM
 | 
			
		|||
                    return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            Scene scene = FindScene(new UUID(im.fromAgentID));
 | 
			
		||||
            if (scene == null)
 | 
			
		||||
                scene = m_SceneList[0];
 | 
			
		||||
 | 
			
		||||
            string reason = string.Empty;
 | 
			
		||||
            bool success = m_OfflineIMService.StoreMessage(im, out reason);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -241,11 +261,6 @@ namespace OpenSim.OfflineIM
 | 
			
		|||
            return m_OfflineIMService.StoreMessage(im, out reason);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void DeleteMessages(UUID userID)
 | 
			
		||||
        {
 | 
			
		||||
            m_OfflineIMService.DeleteMessages(userID);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        #endregion
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,7 +30,7 @@ using Mono.Addins;
 | 
			
		|||
//      Build Number
 | 
			
		||||
//      Revision
 | 
			
		||||
//
 | 
			
		||||
[assembly: AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)]
 | 
			
		||||
[assembly: AssemblyVersion("0.8.0.*")]
 | 
			
		||||
 | 
			
		||||
[assembly: Addin("OpenSim.OfflineIM", OpenSim.VersionInfo.VersionNumber)]
 | 
			
		||||
[assembly: AddinDependency("OpenSim.Region.Framework", OpenSim.VersionInfo.VersionNumber)]
 | 
			
		||||
[assembly: Addin("OpenSim.OfflineIM", "0.1")]
 | 
			
		||||
[assembly: AddinDependency("OpenSim", "0.5")]
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -32,7 +32,6 @@ using System.Reflection;
 | 
			
		|||
using System.Text;
 | 
			
		||||
 | 
			
		||||
using OpenSim.Framework;
 | 
			
		||||
using OpenSim.Framework.ServiceAuth;
 | 
			
		||||
using OpenSim.Server.Base;
 | 
			
		||||
using OpenSim.Services.Interfaces;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -47,7 +46,6 @@ namespace OpenSim.OfflineIM
 | 
			
		|||
        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)
 | 
			
		||||
| 
						 | 
				
			
			@ -67,18 +65,6 @@ namespace OpenSim.OfflineIM
 | 
			
		|||
 | 
			
		||||
            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
 | 
			
		||||
| 
						 | 
				
			
			@ -96,13 +82,8 @@ namespace OpenSim.OfflineIM
 | 
			
		|||
            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);
 | 
			
		||||
            if (ret["RESULT"].ToString() == "NULL")
 | 
			
		||||
                return ims;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            foreach (object v in ((Dictionary<string, object>)ret["RESULT"]).Values)
 | 
			
		||||
            {
 | 
			
		||||
| 
						 | 
				
			
			@ -129,21 +110,13 @@ namespace OpenSim.OfflineIM
 | 
			
		|||
            string result = ret["RESULT"].ToString();
 | 
			
		||||
            if (result == "NULL" || result.ToLower() == "false")
 | 
			
		||||
            {
 | 
			
		||||
                reason = ret.ContainsKey("REASON") ? ret["REASON"].ToString() : "Unknown error";
 | 
			
		||||
                reason = ret["REASON"].ToString();
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void DeleteMessages(UUID userID)
 | 
			
		||||
        {
 | 
			
		||||
            Dictionary<string, object> sendData = new Dictionary<string, object>();
 | 
			
		||||
            sendData["UserID"] = userID;
 | 
			
		||||
 | 
			
		||||
            MakeRequest("DELETE", sendData);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        #endregion
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -157,8 +130,7 @@ namespace OpenSim.OfflineIM
 | 
			
		|||
            lock (m_Lock)
 | 
			
		||||
                reply = SynchronousRestFormsRequester.MakeRequest("POST",
 | 
			
		||||
                         m_ServerURI + "/offlineim",
 | 
			
		||||
                         ServerUtils.BuildQueryString(sendData),
 | 
			
		||||
                         m_Auth);
 | 
			
		||||
                         ServerUtils.BuildQueryString(sendData));
 | 
			
		||||
 | 
			
		||||
            Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(
 | 
			
		||||
                    reply);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,4 @@
 | 
			
		|||
/*
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) Contributors, http://opensimulator.org/
 | 
			
		||||
 * See CONTRIBUTORS.TXT for a full list of copyright holders.
 | 
			
		||||
 *
 | 
			
		||||
| 
						 | 
				
			
			@ -36,7 +36,6 @@ 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;
 | 
			
		||||
| 
						 | 
				
			
			@ -60,9 +59,7 @@ namespace OpenSim.OfflineIM
 | 
			
		|||
 | 
			
		||||
            m_OfflineIMService = new OfflineIMService(config);
 | 
			
		||||
 | 
			
		||||
            IServiceAuth auth = ServiceAuth.Create(config, m_ConfigName);
 | 
			
		||||
 | 
			
		||||
            server.AddStreamHandler(new OfflineIMServicePostHandler(m_OfflineIMService, auth));
 | 
			
		||||
            server.AddStreamHandler(new OfflineIMServicePostHandler(m_OfflineIMService));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -72,8 +69,8 @@ namespace OpenSim.OfflineIM
 | 
			
		|||
 | 
			
		||||
        private IOfflineIMService m_OfflineIMService;
 | 
			
		||||
 | 
			
		||||
        public OfflineIMServicePostHandler(IOfflineIMService service, IServiceAuth auth) :
 | 
			
		||||
            base("POST", "/offlineim", auth)
 | 
			
		||||
        public OfflineIMServicePostHandler(IOfflineIMService service) :
 | 
			
		||||
            base("POST", "/offlineim")
 | 
			
		||||
        {
 | 
			
		||||
            m_OfflineIMService = service;
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -99,20 +96,19 @@ namespace OpenSim.OfflineIM
 | 
			
		|||
                string method = request["METHOD"].ToString();
 | 
			
		||||
                request.Remove("METHOD");
 | 
			
		||||
 | 
			
		||||
                m_log.DebugFormat("[OfflineIM.V2.Handler]: {0}", 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);
 | 
			
		||||
                m_log.DebugFormat("[OFFLINE IM HANDLER]: Exception {0}", e.StackTrace);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return FailureResult();
 | 
			
		||||
| 
						 | 
				
			
			@ -163,21 +159,6 @@ namespace OpenSim.OfflineIM
 | 
			
		|||
            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)
 | 
			
		||||
| 
						 | 
				
			
			@ -215,7 +196,18 @@ namespace OpenSim.OfflineIM
 | 
			
		|||
 | 
			
		||||
            rootElement.AppendChild(result);
 | 
			
		||||
 | 
			
		||||
            return Util.DocToBytes(doc);
 | 
			
		||||
            return DocToBytes(doc);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private byte[] DocToBytes(XmlDocument doc)
 | 
			
		||||
        {
 | 
			
		||||
            MemoryStream ms = new MemoryStream();
 | 
			
		||||
            XmlTextWriter xw = new XmlTextWriter(ms, null);
 | 
			
		||||
            xw.Formatting = Formatting.Indented;
 | 
			
		||||
            doc.WriteTo(xw);
 | 
			
		||||
            xw.Flush();
 | 
			
		||||
 | 
			
		||||
            return ms.ToArray();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        #endregion
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,4 @@
 | 
			
		|||
/*
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) Contributors, http://opensimulator.org/
 | 
			
		||||
 * See CONTRIBUTORS.TXT for a full list of copyright holders.
 | 
			
		||||
 *
 | 
			
		||||
| 
						 | 
				
			
			@ -91,7 +91,7 @@ namespace OpenSim.OfflineIM
 | 
			
		|||
        {
 | 
			
		||||
            reason = string.Empty;
 | 
			
		||||
            
 | 
			
		||||
            // Check limits
 | 
			
		||||
            // TODO Check limits
 | 
			
		||||
            UUID principalID = new UUID(im.toAgentID);
 | 
			
		||||
            long count = m_Database.GetCount("PrincipalID", principalID.ToString());
 | 
			
		||||
            if (count >= MAX_IM)
 | 
			
		||||
| 
						 | 
				
			
			@ -100,35 +100,32 @@ namespace OpenSim.OfflineIM
 | 
			
		|||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            string imXml;
 | 
			
		||||
            string imXml = string.Empty;
 | 
			
		||||
            using (MemoryStream mstream = new MemoryStream())
 | 
			
		||||
            {
 | 
			
		||||
                XmlWriterSettings settings = new XmlWriterSettings();
 | 
			
		||||
                settings.Encoding = Util.UTF8NoBomEncoding;
 | 
			
		||||
                settings.Encoding = Encoding.UTF8;
 | 
			
		||||
 | 
			
		||||
                using (XmlWriter writer = XmlWriter.Create(mstream, settings))
 | 
			
		||||
                {
 | 
			
		||||
                    m_serializer.Serialize(writer, im);
 | 
			
		||||
                    writer.Flush();
 | 
			
		||||
                    imXml = Util.UTF8NoBomEncoding.GetString(mstream.ToArray());
 | 
			
		||||
                    
 | 
			
		||||
                    mstream.Position = 0;
 | 
			
		||||
                    using (StreamReader sreader = new StreamReader(mstream))
 | 
			
		||||
                    {
 | 
			
		||||
                        imXml = sreader.ReadToEnd();
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            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());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -32,17 +32,16 @@ using System.Threading;
 | 
			
		|||
using log4net;
 | 
			
		||||
using OpenMetaverse;
 | 
			
		||||
using OpenSim.Framework;
 | 
			
		||||
using OpenSim.Framework.RegionLoader.Filesystem;
 | 
			
		||||
using OpenSim.Framework.RegionLoader.Web;
 | 
			
		||||
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;
 | 
			
		||||
 | 
			
		||||
namespace OpenSim.ApplicationPlugins.LoadRegions
 | 
			
		||||
{
 | 
			
		||||
    [Extension(Path="/OpenSim/Startup", Id="LoadRegions", NodeName="Plugin")]
 | 
			
		||||
    public class LoadRegionsPlugin : IApplicationPlugin, IRegionCreator
 | 
			
		||||
    {
 | 
			
		||||
        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 | 
			
		||||
| 
						 | 
				
			
			@ -131,7 +130,7 @@ namespace OpenSim.ApplicationPlugins.LoadRegions
 | 
			
		|||
                createdScenes.Add(scene);
 | 
			
		||||
 | 
			
		||||
                if (changed)
 | 
			
		||||
                    m_openSim.EstateDataService.StoreEstateSettings(regionsToLoad[i].EstateSettings);
 | 
			
		||||
                    regionsToLoad[i].EstateSettings.Save();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            foreach (IScene scene in createdScenes)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -27,17 +27,16 @@
 | 
			
		|||
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
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.LoadRegions")]
 | 
			
		||||
[assembly : AssemblyTitle("OpenSim.Addin")]
 | 
			
		||||
[assembly : AssemblyDescription("")]
 | 
			
		||||
[assembly : AssemblyConfiguration("")]
 | 
			
		||||
[assembly : AssemblyCompany("http://opensimulator.org")]
 | 
			
		||||
[assembly : AssemblyProduct("OpenSim")]
 | 
			
		||||
[assembly : AssemblyProduct("OpenSim.Addin")]
 | 
			
		||||
[assembly : AssemblyCopyright("Copyright © OpenSimulator.org Developers 2007-2009")]
 | 
			
		||||
[assembly : AssemblyTrademark("")]
 | 
			
		||||
[assembly : AssemblyCulture("")]
 | 
			
		||||
| 
						 | 
				
			
			@ -61,8 +60,6 @@ using Mono.Addins;
 | 
			
		|||
//
 | 
			
		||||
// You can specify all the values or you can default the Build and Revision Numbers
 | 
			
		||||
// by using the '*' as shown below:
 | 
			
		||||
// [assembly: AssemblyVersion("0.7.6.*")]
 | 
			
		||||
 | 
			
		||||
[assembly : AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)]
 | 
			
		||||
 | 
			
		||||
[assembly: Addin("OpenSim.ApplicationPlugins.LoadRegions", OpenSim.VersionInfo.VersionNumber)]
 | 
			
		||||
[assembly: AddinDependency("OpenSim", OpenSim.VersionInfo.VersionNumber)]
 | 
			
		||||
[assembly : AssemblyVersion("0.8.0.*")]
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,11 @@
 | 
			
		|||
<Addin id="OpenSim.ApplicationPlugins.LoadRegions" version="0.1">
 | 
			
		||||
    <Runtime>
 | 
			
		||||
        <Import assembly="OpenSim.ApplicationPlugins.LoadRegions.dll"/>
 | 
			
		||||
    </Runtime>
 | 
			
		||||
    <Dependencies>
 | 
			
		||||
        <Addin id="OpenSim" version="0.5" />
 | 
			
		||||
    </Dependencies>
 | 
			
		||||
    <Extension path = "/OpenSim/Startup">
 | 
			
		||||
        <Plugin id="LoadRegions" type="OpenSim.ApplicationPlugins.LoadRegions.LoadRegionsPlugin" />
 | 
			
		||||
    </Extension>
 | 
			
		||||
</Addin>
 | 
			
		||||
| 
						 | 
				
			
			@ -1,7 +1,6 @@
 | 
			
		|||
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
 | 
			
		||||
| 
						 | 
				
			
			@ -30,7 +29,5 @@ using Mono.Addins;
 | 
			
		|||
//      Build Number
 | 
			
		||||
//      Revision
 | 
			
		||||
//
 | 
			
		||||
[assembly: AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)]
 | 
			
		||||
[assembly: AssemblyVersion("0.8.0.*")]
 | 
			
		||||
 | 
			
		||||
[assembly: Addin("OpenSim.ApplicationPlugins.RegionModulesController", OpenSim.VersionInfo.VersionNumber)]
 | 
			
		||||
[assembly: AddinDependency("OpenSim", OpenSim.VersionInfo.VersionNumber)]
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -32,13 +32,11 @@ 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
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			@ -47,12 +45,6 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
 | 
			
		|||
                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;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -69,11 +61,6 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
 | 
			
		|||
        private List<ISharedRegionModule> m_sharedInstances =
 | 
			
		||||
                new List<ISharedRegionModule>();
 | 
			
		||||
 | 
			
		||||
        public RegionModulesControllerPlugin()
 | 
			
		||||
        {
 | 
			
		||||
            LoadModulesFromAddins = true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
#region IApplicationPlugin implementation
 | 
			
		||||
        
 | 
			
		||||
        public void Initialise (OpenSimBase openSim)
 | 
			
		||||
| 
						 | 
				
			
			@ -82,9 +69,6 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
 | 
			
		|||
            m_openSim.ApplicationRegistry.RegisterInterface<IRegionModulesController>(this);
 | 
			
		||||
            m_log.DebugFormat("[REGIONMODULES]: Initializing...");
 | 
			
		||||
 | 
			
		||||
            if (!LoadModulesFromAddins)
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
            // Who we are
 | 
			
		||||
            string id = AddinManager.CurrentAddin.Id;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -104,8 +88,40 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
 | 
			
		|||
            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 (TypeExtensionNode node in
 | 
			
		||||
                    AddinManager.GetExtensionNodes("/OpenSim/RegionModules"))
 | 
			
		||||
            {
 | 
			
		||||
                IList<int> loadedModuleData;
 | 
			
		||||
 | 
			
		||||
                if (!loadedModules.ContainsKey(node.Addin))
 | 
			
		||||
                    loadedModules.Add(node.Addin, new List<int> { 0, 0, 0 });
 | 
			
		||||
 | 
			
		||||
                loadedModuleData = loadedModules[node.Addin];
 | 
			
		||||
                      
 | 
			
		||||
                if (node.Type.GetInterface(typeof(ISharedRegionModule).ToString()) != null)
 | 
			
		||||
                {
 | 
			
		||||
                    if (CheckModuleEnabled(node, modulesConfig))
 | 
			
		||||
                    {
 | 
			
		||||
                        m_log.DebugFormat("[REGIONMODULES]: Found shared region module {0}, class {1}", node.Id, node.Type);
 | 
			
		||||
                        m_sharedModules.Add(node);
 | 
			
		||||
                        loadedModuleData[0]++;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                else if (node.Type.GetInterface(typeof(INonSharedRegionModule).ToString()) != null)
 | 
			
		||||
                {
 | 
			
		||||
                    if (CheckModuleEnabled(node, modulesConfig))
 | 
			
		||||
                    {
 | 
			
		||||
                        m_log.DebugFormat("[REGIONMODULES]: Found non-shared region module {0}, class {1}", node.Id, node.Type);
 | 
			
		||||
                        m_nonSharedModules.Add(node);
 | 
			
		||||
                        loadedModuleData[1]++;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    m_log.WarnFormat("[REGIONMODULES]: Found unknown type of module {0}, class {1}", node.Id, node.Type);
 | 
			
		||||
                    loadedModuleData[2]++;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            foreach (KeyValuePair<RuntimeAddin, IList<int>> loadedModuleData in loadedModules)
 | 
			
		||||
            {
 | 
			
		||||
| 
						 | 
				
			
			@ -131,9 +147,6 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
 | 
			
		|||
                // 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)
 | 
			
		||||
| 
						 | 
				
			
			@ -181,41 +194,6 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
 | 
			
		|||
 | 
			
		||||
#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 ()
 | 
			
		||||
| 
						 | 
				
			
			@ -237,7 +215,6 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
 | 
			
		|||
                m_sharedInstances[0].Close();
 | 
			
		||||
                m_sharedInstances.RemoveAt(0);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            m_sharedModules.Clear();
 | 
			
		||||
            m_nonSharedModules.Clear();
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -368,10 +345,6 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
 | 
			
		|||
                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)
 | 
			
		||||
                {
 | 
			
		||||
| 
						 | 
				
			
			@ -509,8 +482,6 @@ namespace OpenSim.ApplicationPlugins.RegionModulesController
 | 
			
		|||
            {
 | 
			
		||||
                module.RegionLoaded(scene);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            scene.AllModulesLoaded();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void RemoveRegionFromModules (Scene scene)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,13 @@
 | 
			
		|||
<Addin id="OpenSim.ApplicationPlugins.RegionModulesController" version="0.1">
 | 
			
		||||
    <Runtime>
 | 
			
		||||
        <Import assembly="OpenSim.ApplicationPlugins.RegionModulesController.dll"/>
 | 
			
		||||
    </Runtime>
 | 
			
		||||
 | 
			
		||||
    <Dependencies>
 | 
			
		||||
        <Addin id="OpenSim" version="0.5" />
 | 
			
		||||
    </Dependencies>
 | 
			
		||||
 | 
			
		||||
    <Extension path = "/OpenSim/Startup">
 | 
			
		||||
        <Plugin id="RegionModulesController" type="OpenSim.ApplicationPlugins.RegionModulesController.RegionModulesControllerPlugin" />
 | 
			
		||||
    </Extension>
 | 
			
		||||
</Addin>
 | 
			
		||||
| 
						 | 
				
			
			@ -1,7 +1,6 @@
 | 
			
		|||
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
 | 
			
		||||
| 
						 | 
				
			
			@ -30,7 +29,5 @@ using Mono.Addins;
 | 
			
		|||
//      Build Number
 | 
			
		||||
//      Revision
 | 
			
		||||
//
 | 
			
		||||
[assembly: AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)]
 | 
			
		||||
[assembly: AssemblyVersion("0.8.0.*")]
 | 
			
		||||
 | 
			
		||||
[assembly: Addin("OpenSim.ApplicationPlugins.RemoteController", OpenSim.VersionInfo.VersionNumber)]
 | 
			
		||||
[assembly: AddinDependency("OpenSim", OpenSim.VersionInfo.VersionNumber)]
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -39,9 +39,9 @@ using log4net;
 | 
			
		|||
using Nini.Config;
 | 
			
		||||
using Nwc.XmlRpc;
 | 
			
		||||
using OpenMetaverse;
 | 
			
		||||
using Mono.Addins;
 | 
			
		||||
using OpenSim;
 | 
			
		||||
using OpenSim.Framework;
 | 
			
		||||
using OpenSim.Framework.Communications;
 | 
			
		||||
using OpenSim.Framework.Console;
 | 
			
		||||
using OpenSim.Framework.Servers;
 | 
			
		||||
using OpenSim.Framework.Servers.HttpServer;
 | 
			
		||||
| 
						 | 
				
			
			@ -56,7 +56,6 @@ using RegionInfo = OpenSim.Framework.RegionInfo;
 | 
			
		|||
 | 
			
		||||
namespace OpenSim.ApplicationPlugins.RemoteController
 | 
			
		||||
{
 | 
			
		||||
    [Extension(Path = "/OpenSim/Startup", Id = "LoadRegions", NodeName = "Plugin")]
 | 
			
		||||
    public class RemoteAdminPlugin : IApplicationPlugin
 | 
			
		||||
    {
 | 
			
		||||
        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 | 
			
		||||
| 
						 | 
				
			
			@ -74,7 +73,6 @@ namespace OpenSim.ApplicationPlugins.RemoteController
 | 
			
		|||
 | 
			
		||||
        private string m_name = "RemoteAdminPlugin";
 | 
			
		||||
        private string m_version = "0.0";
 | 
			
		||||
        private string m_openSimVersion;
 | 
			
		||||
 | 
			
		||||
        public string Version
 | 
			
		||||
        {
 | 
			
		||||
| 
						 | 
				
			
			@ -94,8 +92,6 @@ namespace OpenSim.ApplicationPlugins.RemoteController
 | 
			
		|||
 | 
			
		||||
        public void Initialise(OpenSimBase openSim)
 | 
			
		||||
        {
 | 
			
		||||
            m_openSimVersion = openSim.GetVersionText();
 | 
			
		||||
 | 
			
		||||
            m_configSource = openSim.ConfigSource.Source;
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
| 
						 | 
				
			
			@ -138,13 +134,10 @@ namespace OpenSim.ApplicationPlugins.RemoteController
 | 
			
		|||
                    availableMethods["admin_region_query"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcRegionQueryMethod);
 | 
			
		||||
                    availableMethods["admin_shutdown"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcShutdownMethod);
 | 
			
		||||
                    availableMethods["admin_broadcast"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcAlertMethod);
 | 
			
		||||
                    availableMethods["admin_dialog"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcDialogMethod);
 | 
			
		||||
                    availableMethods["admin_restart"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcRestartMethod);
 | 
			
		||||
                    availableMethods["admin_load_heightmap"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcLoadHeightmapMethod);
 | 
			
		||||
                    availableMethods["admin_save_heightmap"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcSaveHeightmapMethod);
 | 
			
		||||
 | 
			
		||||
                    availableMethods["admin_reset_land"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcResetLand);
 | 
			
		||||
 | 
			
		||||
                    // Agent management
 | 
			
		||||
                    availableMethods["admin_get_agents"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcGetAgentsMethod);
 | 
			
		||||
                    availableMethods["admin_teleport_agent"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcTeleportAgentMethod);
 | 
			
		||||
| 
						 | 
				
			
			@ -169,12 +162,6 @@ namespace OpenSim.ApplicationPlugins.RemoteController
 | 
			
		|||
                    availableMethods["admin_acl_list"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcAccessListList);
 | 
			
		||||
                    availableMethods["admin_estate_reload"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcEstateReload);
 | 
			
		||||
 | 
			
		||||
                    // Misc
 | 
			
		||||
                    availableMethods["admin_refresh_search"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcRefreshSearch);
 | 
			
		||||
                    availableMethods["admin_refresh_map"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcRefreshMap);
 | 
			
		||||
                    availableMethods["admin_get_opensim_version"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcGetOpenSimVersion);
 | 
			
		||||
                    availableMethods["admin_get_agent_count"] = (req, ep) => InvokeXmlRpcMethod(req, ep, XmlRpcGetAgentCount);
 | 
			
		||||
 | 
			
		||||
                    // Either enable full remote functionality or just selected features
 | 
			
		||||
                    string enabledMethods = m_config.GetString("enabled_methods", "all");
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -274,148 +261,32 @@ namespace OpenSim.ApplicationPlugins.RemoteController
 | 
			
		|||
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                m_log.Info("[RADMIN]: Request to restart Region.");
 | 
			
		||||
 | 
			
		||||
                CheckRegionParams(requestData, responseData);
 | 
			
		||||
 | 
			
		||||
                Scene rebootedScene = null;
 | 
			
		||||
                bool restartAll = false;
 | 
			
		||||
 | 
			
		||||
                IConfig startupConfig = m_configSource.Configs["Startup"];
 | 
			
		||||
                if (startupConfig != null)
 | 
			
		||||
                {
 | 
			
		||||
                    if (startupConfig.GetBoolean("InworldRestartShutsDown", false))
 | 
			
		||||
                    {
 | 
			
		||||
                        rebootedScene = m_application.SceneManager.CurrentOrFirstScene;
 | 
			
		||||
                        restartAll = true;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (rebootedScene == null)
 | 
			
		||||
                {
 | 
			
		||||
                    CheckRegionParams(requestData, responseData);
 | 
			
		||||
 | 
			
		||||
                    GetSceneFromRegionParams(requestData, responseData, out rebootedScene);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                IRestartModule restartModule = rebootedScene.RequestModuleInterface<IRestartModule>();
 | 
			
		||||
                GetSceneFromRegionParams(requestData, responseData, out rebootedScene);
 | 
			
		||||
 | 
			
		||||
                responseData["success"] = false;
 | 
			
		||||
                responseData["accepted"] = true;
 | 
			
		||||
                responseData["rebooting"] = true;
 | 
			
		||||
 | 
			
		||||
                string message;
 | 
			
		||||
                List<int> times = new List<int>();
 | 
			
		||||
 | 
			
		||||
                if (requestData.ContainsKey("alerts"))
 | 
			
		||||
                IRestartModule restartModule = rebootedScene.RequestModuleInterface<IRestartModule>();
 | 
			
		||||
                if (restartModule != null)
 | 
			
		||||
                {
 | 
			
		||||
                    string[] alertTimes = requestData["alerts"].ToString().Split( new char[] {','});
 | 
			
		||||
                    if (alertTimes.Length == 1 && Convert.ToInt32(alertTimes[0]) == -1)
 | 
			
		||||
                    {
 | 
			
		||||
                        m_log.Info("[RADMIN]: Request to cancel restart.");
 | 
			
		||||
                    List<int> times = new List<int> { 30, 15 };
 | 
			
		||||
 | 
			
		||||
                        if (restartModule != null)
 | 
			
		||||
                        {
 | 
			
		||||
                            message = "Restart has been cancelled";
 | 
			
		||||
 | 
			
		||||
                            if (requestData.ContainsKey("message"))
 | 
			
		||||
                                message = requestData["message"].ToString();
 | 
			
		||||
 | 
			
		||||
                            restartModule.AbortRestart(message);
 | 
			
		||||
 | 
			
		||||
                            responseData["success"] = true;
 | 
			
		||||
                            responseData["rebooting"] = false;
 | 
			
		||||
 | 
			
		||||
                            return;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    foreach (string a in alertTimes)
 | 
			
		||||
                        times.Add(Convert.ToInt32(a));
 | 
			
		||||
                    restartModule.ScheduleRestart(UUID.Zero, "Region will restart in {0}", times.ToArray(), true);
 | 
			
		||||
                    responseData["success"] = true;
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    int timeout = 30;
 | 
			
		||||
                    if (requestData.ContainsKey("milliseconds"))
 | 
			
		||||
                        timeout = Int32.Parse(requestData["milliseconds"].ToString()) / 1000;
 | 
			
		||||
                    while (timeout > 0)
 | 
			
		||||
                    {
 | 
			
		||||
                        times.Add(timeout);
 | 
			
		||||
                        if (timeout > 300)
 | 
			
		||||
                            timeout -= 120;
 | 
			
		||||
                        else if (timeout > 30)
 | 
			
		||||
                            timeout -= 30;
 | 
			
		||||
                        else
 | 
			
		||||
                            timeout -= 15;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                m_log.Info("[RADMIN]: Request to restart Region.");
 | 
			
		||||
 | 
			
		||||
                message = "Region is restarting in {0}. Please save what you are doing and log out.";
 | 
			
		||||
 | 
			
		||||
                if (requestData.ContainsKey("message"))
 | 
			
		||||
                    message = requestData["message"].ToString();
 | 
			
		||||
 | 
			
		||||
                bool notice = true;
 | 
			
		||||
                if (requestData.ContainsKey("noticetype")
 | 
			
		||||
                    && ((string)requestData["noticetype"] == "dialog"))
 | 
			
		||||
                {
 | 
			
		||||
                    notice = false;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (startupConfig.GetBoolean("SkipDelayOnEmptyRegion", false))
 | 
			
		||||
                {
 | 
			
		||||
                    m_log.Info("[RADMIN]: Counting affected avatars");
 | 
			
		||||
                    int agents = 0;
 | 
			
		||||
 | 
			
		||||
                    if (restartAll)
 | 
			
		||||
                    {
 | 
			
		||||
                        foreach (Scene s in m_application.SceneManager.Scenes)
 | 
			
		||||
                        {
 | 
			
		||||
                            foreach (ScenePresence sp in s.GetScenePresences())
 | 
			
		||||
                            {
 | 
			
		||||
                                if (!sp.IsChildAgent && !sp.IsNPC)
 | 
			
		||||
                                    agents++;
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        foreach (ScenePresence sp in rebootedScene.GetScenePresences())
 | 
			
		||||
                        {
 | 
			
		||||
                            if (!sp.IsChildAgent && !sp.IsNPC)
 | 
			
		||||
                                agents++;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    m_log.InfoFormat("[RADMIN]: Avatars in region: {0}", agents);
 | 
			
		||||
 | 
			
		||||
                    if (agents == 0)
 | 
			
		||||
                    {
 | 
			
		||||
                        m_log.Info("[RADMIN]: No avatars detected, shutting down without delay");
 | 
			
		||||
 | 
			
		||||
                        times.Clear();
 | 
			
		||||
                        times.Add(0);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                List<Scene> restartList;
 | 
			
		||||
 | 
			
		||||
                if (restartAll)
 | 
			
		||||
                    restartList = m_application.SceneManager.Scenes;
 | 
			
		||||
                else
 | 
			
		||||
                    restartList = new List<Scene>() { rebootedScene };
 | 
			
		||||
 | 
			
		||||
                foreach (Scene s in m_application.SceneManager.Scenes)
 | 
			
		||||
                {
 | 
			
		||||
                    restartModule = s.RequestModuleInterface<IRestartModule>();
 | 
			
		||||
                    if (restartModule != null)
 | 
			
		||||
                        restartModule.ScheduleRestart(UUID.Zero, message, times.ToArray(), notice);
 | 
			
		||||
                }
 | 
			
		||||
                responseData["success"] = true;
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception e)
 | 
			
		||||
            {
 | 
			
		||||
                m_log.ErrorFormat("[RADMIN]: Restart region: failed: {0} {1}", e.Message, e.StackTrace);
 | 
			
		||||
//                m_log.ErrorFormat("[RADMIN]: Restart region: failed: {0} {1}", e.Message, e.StackTrace);
 | 
			
		||||
                responseData["rebooting"] = false;
 | 
			
		||||
 | 
			
		||||
                throw;
 | 
			
		||||
                throw e;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            m_log.Info("[RADMIN]: Restart Region request complete");
 | 
			
		||||
| 
						 | 
				
			
			@ -445,32 +316,6 @@ namespace OpenSim.ApplicationPlugins.RemoteController
 | 
			
		|||
            m_log.Info("[RADMIN]: Alert request complete");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void XmlRpcDialogMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
 | 
			
		||||
        {
 | 
			
		||||
            Hashtable responseData = (Hashtable)response.Value;
 | 
			
		||||
 | 
			
		||||
            m_log.Info("[RADMIN]: Dialog request started");
 | 
			
		||||
 | 
			
		||||
            Hashtable requestData = (Hashtable)request.Params[0];
 | 
			
		||||
 | 
			
		||||
            string message = (string)requestData["message"];
 | 
			
		||||
            string fromuuid = (string)requestData["from"];
 | 
			
		||||
            m_log.InfoFormat("[RADMIN]: Broadcasting: {0}", message);
 | 
			
		||||
 | 
			
		||||
            responseData["accepted"] = true;
 | 
			
		||||
            responseData["success"] = true;
 | 
			
		||||
 | 
			
		||||
            m_application.SceneManager.ForEachScene(
 | 
			
		||||
                delegate(Scene scene)
 | 
			
		||||
                {
 | 
			
		||||
                    IDialogModule dialogModule = scene.RequestModuleInterface<IDialogModule>();
 | 
			
		||||
                    if (dialogModule != null)
 | 
			
		||||
                        dialogModule.SendNotificationToUsersInRegion(UUID.Zero, fromuuid, message);
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            m_log.Info("[RADMIN]: Dialog request complete");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void XmlRpcLoadHeightmapMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
 | 
			
		||||
        {
 | 
			
		||||
            m_log.Info("[RADMIN]: Load height maps request started");
 | 
			
		||||
| 
						 | 
				
			
			@ -574,32 +419,13 @@ namespace OpenSim.ApplicationPlugins.RemoteController
 | 
			
		|||
                message = "Region is going down now.";
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (requestData.ContainsKey("noticetype")
 | 
			
		||||
                && ((string) requestData["noticetype"] == "dialog"))
 | 
			
		||||
            {
 | 
			
		||||
                m_application.SceneManager.ForEachScene(
 | 
			
		||||
 | 
			
		||||
            m_application.SceneManager.ForEachScene(
 | 
			
		||||
                delegate(Scene scene)
 | 
			
		||||
                {
 | 
			
		||||
                    IDialogModule dialogModule = scene.RequestModuleInterface<IDialogModule>();
 | 
			
		||||
                    if (dialogModule != null)
 | 
			
		||||
                            dialogModule.SendNotificationToUsersInRegion(UUID.Zero, "System", message);
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                if (!requestData.ContainsKey("noticetype")
 | 
			
		||||
                    || ((string)requestData["noticetype"] != "none"))
 | 
			
		||||
                {
 | 
			
		||||
                    m_application.SceneManager.ForEachScene(
 | 
			
		||||
                    delegate(Scene scene)
 | 
			
		||||
                    {
 | 
			
		||||
                        IDialogModule dialogModule = scene.RequestModuleInterface<IDialogModule>();
 | 
			
		||||
                        if (dialogModule != null)
 | 
			
		||||
                            dialogModule.SendGeneralAlert(message);
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Perform shutdown
 | 
			
		||||
            System.Timers.Timer shutdownTimer = new System.Timers.Timer(timeout); // Wait before firing
 | 
			
		||||
| 
						 | 
				
			
			@ -868,7 +694,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
 | 
			
		|||
                    region.EstateSettings.EstateName = (string) requestData["estate_name"];
 | 
			
		||||
                    region.EstateSettings.EstateOwner = userID;
 | 
			
		||||
                    // Persistence does not seem to effect the need to save a new estate
 | 
			
		||||
                    m_application.EstateDataService.StoreEstateSettings(region.EstateSettings);
 | 
			
		||||
                    region.EstateSettings.Save();
 | 
			
		||||
 | 
			
		||||
                    if (!m_application.EstateDataService.LinkRegion(region.RegionID, (int) region.EstateSettings.EstateID))
 | 
			
		||||
                        throw new Exception("Failed to join estate.");
 | 
			
		||||
| 
						 | 
				
			
			@ -898,7 +724,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
 | 
			
		|||
                // If an access specification was provided, use it.
 | 
			
		||||
                // Otherwise accept the default.
 | 
			
		||||
                newScene.RegionInfo.EstateSettings.PublicAccess = GetBoolean(requestData, "public", m_publicAccess);
 | 
			
		||||
                m_application.EstateDataService.StoreEstateSettings(newScene.RegionInfo.EstateSettings);
 | 
			
		||||
                newScene.RegionInfo.EstateSettings.Save();
 | 
			
		||||
 | 
			
		||||
                // enable voice on newly created region if
 | 
			
		||||
                // requested by either the XmlRpc request or the
 | 
			
		||||
| 
						 | 
				
			
			@ -1084,7 +910,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
 | 
			
		|||
                scene.RegionInfo.EstateSettings.PublicAccess =
 | 
			
		||||
                    GetBoolean(requestData,"public", scene.RegionInfo.EstateSettings.PublicAccess);
 | 
			
		||||
                if (scene.RegionInfo.Persistent)
 | 
			
		||||
                    m_application.EstateDataService.StoreEstateSettings(scene.RegionInfo.EstateSettings);
 | 
			
		||||
                    scene.RegionInfo.EstateSettings.Save();
 | 
			
		||||
 | 
			
		||||
                if (requestData.ContainsKey("enable_voice"))
 | 
			
		||||
                {
 | 
			
		||||
| 
						 | 
				
			
			@ -1196,7 +1022,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
 | 
			
		|||
                    // Set home position
 | 
			
		||||
 | 
			
		||||
                    GridRegion home = scene.GridService.GetRegionByPosition(scopeID, 
 | 
			
		||||
                                        (int)Util.RegionToWorldLoc(regionXLocation), (int)Util.RegionToWorldLoc(regionYLocation));
 | 
			
		||||
                        (int)(regionXLocation * Constants.RegionSize), (int)(regionYLocation * Constants.RegionSize));
 | 
			
		||||
                    if (null == home)
 | 
			
		||||
                    {
 | 
			
		||||
                        m_log.WarnFormat("[RADMIN]: Unable to set home region for newly created user account {0} {1}", firstName, lastName);
 | 
			
		||||
| 
						 | 
				
			
			@ -1426,7 +1252,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
 | 
			
		|||
                    if ((null != regionXLocation) && (null != regionYLocation))
 | 
			
		||||
                    {
 | 
			
		||||
                        GridRegion home = scene.GridService.GetRegionByPosition(scopeID, 
 | 
			
		||||
                                        (int)Util.RegionToWorldLoc((uint)regionXLocation), (int)Util.RegionToWorldLoc((uint)regionYLocation));
 | 
			
		||||
                            (int)(regionXLocation * Constants.RegionSize), (int)(regionYLocation * Constants.RegionSize));
 | 
			
		||||
                        if (null == home) {
 | 
			
		||||
                            m_log.WarnFormat("[RADMIN]: Unable to set home region for updated user account {0} {1}", firstName, lastName);
 | 
			
		||||
                        } else {
 | 
			
		||||
| 
						 | 
				
			
			@ -1658,11 +1484,8 @@ namespace OpenSim.ApplicationPlugins.RemoteController
 | 
			
		|||
                    }
 | 
			
		||||
 | 
			
		||||
                    IRegionArchiverModule archiver = scene.RequestModuleInterface<IRegionArchiverModule>();
 | 
			
		||||
                    Dictionary<string, object> archiveOptions = new Dictionary<string, object>();
 | 
			
		||||
                    if (mergeOar) archiveOptions.Add("merge", null);
 | 
			
		||||
                    if (skipAssets) archiveOptions.Add("skipAssets", null);
 | 
			
		||||
                    if (archiver != null)
 | 
			
		||||
                        archiver.DearchiveRegion(filename, Guid.Empty, archiveOptions);
 | 
			
		||||
                        archiver.DearchiveRegion(filename, mergeOar, skipAssets, Guid.Empty);
 | 
			
		||||
                    else
 | 
			
		||||
                        throw new Exception("Archiver module not present for scene");
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1918,31 +1741,21 @@ namespace OpenSim.ApplicationPlugins.RemoteController
 | 
			
		|||
 | 
			
		||||
        private void XmlRpcRegionQueryMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
 | 
			
		||||
        {
 | 
			
		||||
            m_log.Info("[RADMIN]: Received Query XML Administrator Request");
 | 
			
		||||
 | 
			
		||||
            Hashtable responseData = (Hashtable)response.Value;
 | 
			
		||||
            Hashtable requestData = (Hashtable)request.Params[0];
 | 
			
		||||
 | 
			
		||||
            int flags = 0;
 | 
			
		||||
            string text = String.Empty;
 | 
			
		||||
            int health = 0;
 | 
			
		||||
            responseData["success"] = true;
 | 
			
		||||
 | 
			
		||||
            CheckRegionParams(requestData, responseData);
 | 
			
		||||
 | 
			
		||||
            Scene scene = null;
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                GetSceneFromRegionParams(requestData, responseData, out scene);
 | 
			
		||||
                health = scene.GetHealth(out flags, out text);
 | 
			
		||||
            }
 | 
			
		||||
            catch
 | 
			
		||||
            {
 | 
			
		||||
                responseData["error"] = null;
 | 
			
		||||
            }
 | 
			
		||||
            GetSceneFromRegionParams(requestData, responseData, out scene);
 | 
			
		||||
 | 
			
		||||
            int health = scene.GetHealth();
 | 
			
		||||
            responseData["health"] = health;
 | 
			
		||||
 | 
			
		||||
            responseData["success"] = true;
 | 
			
		||||
            responseData["health"] = health;
 | 
			
		||||
            responseData["flags"] = flags;
 | 
			
		||||
            responseData["message"] = text;
 | 
			
		||||
            m_log.Info("[RADMIN]: Query XML Administrator Request complete");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void XmlRpcConsoleCommandMethod(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
 | 
			
		||||
| 
						 | 
				
			
			@ -1976,7 +1789,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
 | 
			
		|||
            scene.RegionInfo.EstateSettings.EstateAccess = new UUID[]{};
 | 
			
		||||
 | 
			
		||||
            if (scene.RegionInfo.Persistent)
 | 
			
		||||
                m_application.EstateDataService.StoreEstateSettings(scene.RegionInfo.EstateSettings);
 | 
			
		||||
                scene.RegionInfo.EstateSettings.Save();
 | 
			
		||||
 | 
			
		||||
            m_log.Info("[RADMIN]: Access List Clear Request complete");
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -2022,7 +1835,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
 | 
			
		|||
                }
 | 
			
		||||
                scene.RegionInfo.EstateSettings.EstateAccess = accessControlList.ToArray();
 | 
			
		||||
                if (scene.RegionInfo.Persistent)
 | 
			
		||||
                    m_application.EstateDataService.StoreEstateSettings(scene.RegionInfo.EstateSettings);
 | 
			
		||||
                    scene.RegionInfo.EstateSettings.Save();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            responseData["added"] = addedUsers;
 | 
			
		||||
| 
						 | 
				
			
			@ -2071,7 +1884,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
 | 
			
		|||
                }
 | 
			
		||||
                scene.RegionInfo.EstateSettings.EstateAccess = accessControlList.ToArray();
 | 
			
		||||
                if (scene.RegionInfo.Persistent)
 | 
			
		||||
                    m_application.EstateDataService.StoreEstateSettings(scene.RegionInfo.EstateSettings);
 | 
			
		||||
                    scene.RegionInfo.EstateSettings.Save();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            responseData["removed"] = removedUsers;
 | 
			
		||||
| 
						 | 
				
			
			@ -2247,143 +2060,6 @@ namespace OpenSim.ApplicationPlugins.RemoteController
 | 
			
		|||
            responseData["success"] = true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void XmlRpcResetLand(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
 | 
			
		||||
        {
 | 
			
		||||
            Hashtable requestData = (Hashtable)request.Params[0];
 | 
			
		||||
            Hashtable responseData = (Hashtable)response.Value;
 | 
			
		||||
            string musicURL = string.Empty;
 | 
			
		||||
            UUID groupID = UUID.Zero;
 | 
			
		||||
            uint flags = 0;
 | 
			
		||||
            bool set_group = false, set_music = false, set_flags = false;
 | 
			
		||||
 | 
			
		||||
            if (requestData.Contains("group") && requestData["group"] != null)
 | 
			
		||||
                set_group = UUID.TryParse(requestData["group"].ToString(), out groupID);
 | 
			
		||||
            if (requestData.Contains("music") && requestData["music"] != null)
 | 
			
		||||
            {
 | 
			
		||||
 | 
			
		||||
                musicURL = requestData["music"].ToString();
 | 
			
		||||
                set_music = true;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (requestData.Contains("flags") && requestData["flags"] != null)
 | 
			
		||||
                set_flags = UInt32.TryParse(requestData["flags"].ToString(), out flags);
 | 
			
		||||
 | 
			
		||||
            m_log.InfoFormat("[RADMIN]: Received Reset Land Request group={0} musicURL={1} flags={2}",
 | 
			
		||||
                (set_group ? groupID.ToString() : "unchanged"),
 | 
			
		||||
                (set_music ? musicURL : "unchanged"),
 | 
			
		||||
                (set_flags ? flags.ToString() : "unchanged"));
 | 
			
		||||
 | 
			
		||||
            m_application.SceneManager.ForEachScene(delegate (Scene s)
 | 
			
		||||
            {
 | 
			
		||||
                List<ILandObject> parcels = s.LandChannel.AllParcels();
 | 
			
		||||
                foreach (ILandObject p in parcels)
 | 
			
		||||
                {
 | 
			
		||||
                    if (set_music)
 | 
			
		||||
                        p.LandData.MusicURL = musicURL;
 | 
			
		||||
                    if (set_group)
 | 
			
		||||
                        p.LandData.GroupID = groupID;
 | 
			
		||||
                    if (set_flags)
 | 
			
		||||
                        p.LandData.Flags = flags;
 | 
			
		||||
                    s.LandChannel.UpdateLandObject(p.LandData.LocalID, p.LandData);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            );
 | 
			
		||||
            responseData["success"] = true;
 | 
			
		||||
            m_log.Info("[RADMIN]: Reset Land Request complete");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void XmlRpcRefreshSearch(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
 | 
			
		||||
        {
 | 
			
		||||
            m_log.Info("[RADMIN]: Received Refresh Search Request");
 | 
			
		||||
 | 
			
		||||
            Hashtable responseData = (Hashtable)response.Value;
 | 
			
		||||
            Hashtable requestData = (Hashtable)request.Params[0];
 | 
			
		||||
 | 
			
		||||
            CheckRegionParams(requestData, responseData);
 | 
			
		||||
 | 
			
		||||
            Scene scene = null;
 | 
			
		||||
            GetSceneFromRegionParams(requestData, responseData, out scene);
 | 
			
		||||
 | 
			
		||||
            ISearchModule searchModule = scene.RequestModuleInterface<ISearchModule>();
 | 
			
		||||
            if (searchModule != null)
 | 
			
		||||
            {
 | 
			
		||||
                searchModule.Refresh();
 | 
			
		||||
                responseData["success"] = true;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                responseData["success"] = false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            m_log.Info("[RADMIN]: Refresh Search Request complete");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void XmlRpcRefreshMap(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
 | 
			
		||||
        {
 | 
			
		||||
            m_log.Info("[RADMIN]: Received Refresh Map Request");
 | 
			
		||||
 | 
			
		||||
            Hashtable responseData = (Hashtable)response.Value;
 | 
			
		||||
            Hashtable requestData = (Hashtable)request.Params[0];
 | 
			
		||||
 | 
			
		||||
            CheckRegionParams(requestData, responseData);
 | 
			
		||||
 | 
			
		||||
            Scene scene = null;
 | 
			
		||||
            GetSceneFromRegionParams(requestData, responseData, out scene);
 | 
			
		||||
 | 
			
		||||
            IMapImageUploadModule mapTileModule = scene.RequestModuleInterface<IMapImageUploadModule>();
 | 
			
		||||
            if (mapTileModule != null)
 | 
			
		||||
            {
 | 
			
		||||
                Util.FireAndForget((x) =>
 | 
			
		||||
                {
 | 
			
		||||
                    mapTileModule.UploadMapTile(scene);
 | 
			
		||||
                });
 | 
			
		||||
                responseData["success"] = true;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                responseData["success"] = false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            m_log.Info("[RADMIN]: Refresh Map Request complete");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void XmlRpcGetOpenSimVersion(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
 | 
			
		||||
        {
 | 
			
		||||
            m_log.Info("[RADMIN]: Received Get OpenSim Version Request");
 | 
			
		||||
 | 
			
		||||
            Hashtable responseData = (Hashtable)response.Value;
 | 
			
		||||
 | 
			
		||||
            responseData["version"] = m_openSimVersion;
 | 
			
		||||
            responseData["success"] = true;
 | 
			
		||||
 | 
			
		||||
            m_log.Info("[RADMIN]: Get OpenSim Version Request complete");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void XmlRpcGetAgentCount(XmlRpcRequest request, XmlRpcResponse response, IPEndPoint remoteClient)
 | 
			
		||||
        {
 | 
			
		||||
            m_log.Info("[RADMIN]: Received Get Agent Count Request");
 | 
			
		||||
 | 
			
		||||
            Hashtable responseData = (Hashtable)response.Value;
 | 
			
		||||
            Hashtable requestData = (Hashtable)request.Params[0];
 | 
			
		||||
 | 
			
		||||
            CheckRegionParams(requestData, responseData);
 | 
			
		||||
 | 
			
		||||
            Scene scene = null;
 | 
			
		||||
            GetSceneFromRegionParams(requestData, responseData, out scene);
 | 
			
		||||
 | 
			
		||||
            if (scene == null)
 | 
			
		||||
            {
 | 
			
		||||
                responseData["success"] = false;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                responseData["count"] = scene.GetRootAgentCount();
 | 
			
		||||
                responseData["success"] = true;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            m_log.Info("[RADMIN]: Get Agent Count Request complete");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Parse a float with the given parameter name from a request data hash table.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
| 
						 | 
				
			
			@ -2559,6 +2235,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
 | 
			
		|||
                {
 | 
			
		||||
                    account.ServiceURLs = new Dictionary<string, object>();
 | 
			
		||||
                    account.ServiceURLs["HomeURI"] = string.Empty;
 | 
			
		||||
                    account.ServiceURLs["GatekeeperURI"] = string.Empty;
 | 
			
		||||
                    account.ServiceURLs["InventoryServerURI"] = string.Empty;
 | 
			
		||||
                    account.ServiceURLs["AssetServerURI"] = string.Empty;
 | 
			
		||||
                }
 | 
			
		||||
| 
						 | 
				
			
			@ -2805,8 +2482,8 @@ namespace OpenSim.ApplicationPlugins.RemoteController
 | 
			
		|||
            try
 | 
			
		||||
            {
 | 
			
		||||
                Dictionary<UUID,UUID> inventoryMap = new Dictionary<UUID,UUID>();
 | 
			
		||||
                CopyInventoryFolders(destination, source, FolderType.Clothing, inventoryMap, avatarAppearance);
 | 
			
		||||
                CopyInventoryFolders(destination, source, FolderType.BodyPart, inventoryMap, avatarAppearance);
 | 
			
		||||
                CopyInventoryFolders(destination, source, AssetType.Clothing, inventoryMap, avatarAppearance);
 | 
			
		||||
                CopyInventoryFolders(destination, source, AssetType.Bodypart, inventoryMap, avatarAppearance);
 | 
			
		||||
 | 
			
		||||
                AvatarWearable[] wearables = avatarAppearance.Wearables;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2842,20 +2519,20 @@ namespace OpenSim.ApplicationPlugins.RemoteController
 | 
			
		|||
            IInventoryService inventoryService = m_application.SceneManager.CurrentOrFirstScene.InventoryService;
 | 
			
		||||
 | 
			
		||||
            // Get Clothing folder of receiver
 | 
			
		||||
            InventoryFolderBase destinationFolder = inventoryService.GetFolderForType(destination, FolderType.Clothing);
 | 
			
		||||
            InventoryFolderBase destinationFolder = inventoryService.GetFolderForType(destination, AssetType.Clothing);
 | 
			
		||||
 | 
			
		||||
            if (destinationFolder == null)
 | 
			
		||||
                throw new Exception("Cannot locate folder(s)");
 | 
			
		||||
 | 
			
		||||
            // Missing destination folder? This should *never* be the case
 | 
			
		||||
            if (destinationFolder.Type != (short)FolderType.Clothing)
 | 
			
		||||
            if (destinationFolder.Type != (short)AssetType.Clothing)
 | 
			
		||||
            {
 | 
			
		||||
                destinationFolder = new InventoryFolderBase();
 | 
			
		||||
                
 | 
			
		||||
                destinationFolder.ID       = UUID.Random();
 | 
			
		||||
                destinationFolder.Name     = "Clothing";
 | 
			
		||||
                destinationFolder.Owner    = destination;
 | 
			
		||||
                destinationFolder.Type = (short)FolderType.Clothing;
 | 
			
		||||
                destinationFolder.Type     = (short)AssetType.Clothing;
 | 
			
		||||
                destinationFolder.ParentID = inventoryService.GetRootFolder(destination).ID;
 | 
			
		||||
                destinationFolder.Version  = 1;
 | 
			
		||||
                inventoryService.AddFolder(destinationFolder);     // store base record
 | 
			
		||||
| 
						 | 
				
			
			@ -2872,7 +2549,8 @@ namespace OpenSim.ApplicationPlugins.RemoteController
 | 
			
		|||
                if (wearable[0].ItemID != UUID.Zero)
 | 
			
		||||
                {
 | 
			
		||||
                    // Get inventory item and copy it
 | 
			
		||||
                    InventoryItemBase item = inventoryService.GetItem(source, wearable[0].ItemID);
 | 
			
		||||
                    InventoryItemBase item = new InventoryItemBase(wearable[0].ItemID, source);
 | 
			
		||||
                    item = inventoryService.GetItem(item);
 | 
			
		||||
 | 
			
		||||
                    if (item != null)
 | 
			
		||||
                    {
 | 
			
		||||
| 
						 | 
				
			
			@ -2925,7 +2603,8 @@ namespace OpenSim.ApplicationPlugins.RemoteController
 | 
			
		|||
                if (itemID != UUID.Zero)
 | 
			
		||||
                {
 | 
			
		||||
                    // Get inventory item and copy it
 | 
			
		||||
                    InventoryItemBase item = inventoryService.GetItem(source, itemID);
 | 
			
		||||
                    InventoryItemBase item = new InventoryItemBase(itemID, source);
 | 
			
		||||
                    item = inventoryService.GetItem(item);
 | 
			
		||||
 | 
			
		||||
                    if (item != null)
 | 
			
		||||
                    {
 | 
			
		||||
| 
						 | 
				
			
			@ -2971,7 +2650,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
 | 
			
		|||
        /// This method is called by establishAppearance to copy inventory folders to make
 | 
			
		||||
        /// copies of Clothing and Bodyparts inventory folders and attaches worn attachments
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        private void CopyInventoryFolders(UUID destination, UUID source, FolderType assetType, Dictionary<UUID, UUID> inventoryMap,
 | 
			
		||||
        private void CopyInventoryFolders(UUID destination, UUID source, AssetType assetType, Dictionary<UUID,UUID> inventoryMap,
 | 
			
		||||
                                          AvatarAppearance avatarAppearance)
 | 
			
		||||
        {
 | 
			
		||||
            IInventoryService inventoryService = m_application.SceneManager.CurrentOrFirstScene.InventoryService;
 | 
			
		||||
| 
						 | 
				
			
			@ -2987,12 +2666,9 @@ namespace OpenSim.ApplicationPlugins.RemoteController
 | 
			
		|||
            {
 | 
			
		||||
                sourceFolder = new InventoryFolderBase();
 | 
			
		||||
                sourceFolder.ID       = UUID.Random();
 | 
			
		||||
                if (assetType == FolderType.Clothing)
 | 
			
		||||
                {
 | 
			
		||||
                if (assetType == AssetType.Clothing) {
 | 
			
		||||
                    sourceFolder.Name     = "Clothing";
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                } else {
 | 
			
		||||
                    sourceFolder.Name     = "Body Parts";
 | 
			
		||||
                }
 | 
			
		||||
                sourceFolder.Owner    = source;
 | 
			
		||||
| 
						 | 
				
			
			@ -3008,7 +2684,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
 | 
			
		|||
            {
 | 
			
		||||
                destinationFolder = new InventoryFolderBase();
 | 
			
		||||
                destinationFolder.ID       = UUID.Random();
 | 
			
		||||
                if (assetType == FolderType.Clothing)
 | 
			
		||||
                if (assetType == AssetType.Clothing)
 | 
			
		||||
                {
 | 
			
		||||
                    destinationFolder.Name  = "Clothing";
 | 
			
		||||
                }
 | 
			
		||||
| 
						 | 
				
			
			@ -3087,13 +2763,15 @@ namespace OpenSim.ApplicationPlugins.RemoteController
 | 
			
		|||
        /// </summary>
 | 
			
		||||
        private void ApplyNextOwnerPermissions(InventoryItemBase item)
 | 
			
		||||
        {
 | 
			
		||||
            if (item.InvType == (int)InventoryType.Object)
 | 
			
		||||
            if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0)
 | 
			
		||||
            {
 | 
			
		||||
                uint perms = item.CurrentPermissions;
 | 
			
		||||
                PermissionsUtil.ApplyFoldedPermissions(item.CurrentPermissions, ref perms);
 | 
			
		||||
                item.CurrentPermissions = perms;
 | 
			
		||||
                if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0)
 | 
			
		||||
                    item.CurrentPermissions &= ~(uint)PermissionMask.Copy;
 | 
			
		||||
                if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0)
 | 
			
		||||
                    item.CurrentPermissions &= ~(uint)PermissionMask.Transfer;
 | 
			
		||||
                if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
 | 
			
		||||
                    item.CurrentPermissions &= ~(uint)PermissionMask.Modify;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            item.CurrentPermissions &= item.NextPermissions;
 | 
			
		||||
            item.BasePermissions &= item.NextPermissions;
 | 
			
		||||
            item.EveryOnePermissions &= item.NextPermissions;
 | 
			
		||||
| 
						 | 
				
			
			@ -3205,7 +2883,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
 | 
			
		|||
                            // Set home position
 | 
			
		||||
 | 
			
		||||
                            GridRegion home = scene.GridService.GetRegionByPosition(scopeID, 
 | 
			
		||||
                                        (int)Util.RegionToWorldLoc(regionXLocation), (int)Util.RegionToWorldLoc(regionYLocation));
 | 
			
		||||
                                (int)(regionXLocation * Constants.RegionSize), (int)(regionYLocation * Constants.RegionSize));
 | 
			
		||||
                            if (null == home) {
 | 
			
		||||
                                m_log.WarnFormat("[RADMIN]: Unable to set home region for newly created user account {0} {1}", names[0], names[1]);
 | 
			
		||||
                            } else {
 | 
			
		||||
| 
						 | 
				
			
			@ -3247,16 +2925,16 @@ namespace OpenSim.ApplicationPlugins.RemoteController
 | 
			
		|||
                                // m_log.DebugFormat("[RADMIN] {0} folders, {1} items in inventory",
 | 
			
		||||
                                //   uic.folders.Count, uic.items.Count);
 | 
			
		||||
 | 
			
		||||
                                InventoryFolderBase clothingFolder = inventoryService.GetFolderForType(ID, FolderType.Clothing);
 | 
			
		||||
                                InventoryFolderBase clothingFolder = inventoryService.GetFolderForType(ID, AssetType.Clothing);
 | 
			
		||||
 | 
			
		||||
                                // This should *never* be the case
 | 
			
		||||
                                if (clothingFolder == null || clothingFolder.Type != (short)FolderType.Clothing)
 | 
			
		||||
                                if (clothingFolder == null || clothingFolder.Type != (short)AssetType.Clothing)
 | 
			
		||||
                                {
 | 
			
		||||
                                    clothingFolder = new InventoryFolderBase();
 | 
			
		||||
                                    clothingFolder.ID       = UUID.Random();
 | 
			
		||||
                                    clothingFolder.Name     = "Clothing";
 | 
			
		||||
                                    clothingFolder.Owner    = ID;
 | 
			
		||||
                                    clothingFolder.Type     = (short)FolderType.Clothing;
 | 
			
		||||
                                    clothingFolder.Type     = (short)AssetType.Clothing;
 | 
			
		||||
                                    clothingFolder.ParentID = inventoryService.GetRootFolder(ID).ID;
 | 
			
		||||
                                    clothingFolder.Version  = 1;
 | 
			
		||||
                                    inventoryService.AddFolder(clothingFolder);     // store base record
 | 
			
		||||
| 
						 | 
				
			
			@ -3302,7 +2980,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
 | 
			
		|||
                                        extraFolder.ID       = UUID.Random();
 | 
			
		||||
                                        extraFolder.Name     = outfitName;
 | 
			
		||||
                                        extraFolder.Owner    = ID;
 | 
			
		||||
                                        extraFolder.Type     = (short)FolderType.Clothing;
 | 
			
		||||
                                        extraFolder.Type     = (short)AssetType.Clothing;
 | 
			
		||||
                                        extraFolder.Version  = 1;
 | 
			
		||||
                                        extraFolder.ParentID = clothingFolder.ID;
 | 
			
		||||
                                        inventoryService.AddFolder(extraFolder);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,11 @@
 | 
			
		|||
<Addin id="OpenSim.ApplicationPlugins.RemoteController" version="0.1">
 | 
			
		||||
    <Runtime>
 | 
			
		||||
        <Import assembly="OpenSim.ApplicationPlugins.RemoteController.dll"/>
 | 
			
		||||
    </Runtime>
 | 
			
		||||
    <Dependencies>
 | 
			
		||||
        <Addin id="OpenSim" version="0.5" />
 | 
			
		||||
    </Dependencies>
 | 
			
		||||
    <Extension path = "/OpenSim/Startup">
 | 
			
		||||
        <Plugin id="RemoteController" type="OpenSim.ApplicationPlugins.RemoteController.RemoteAdminPlugin" />
 | 
			
		||||
    </Extension>
 | 
			
		||||
</Addin>
 | 
			
		||||
| 
						 | 
				
			
			@ -28,10 +28,8 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.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;
 | 
			
		||||
| 
						 | 
				
			
			@ -50,9 +48,10 @@ namespace OpenSim.Framework.Capabilities
 | 
			
		|||
    /// </summary>
 | 
			
		||||
    public delegate IClientAPI GetClientDelegate(UUID agentID);
 | 
			
		||||
 | 
			
		||||
    public class Caps : IDisposable
 | 
			
		||||
    public class Caps
 | 
			
		||||
    {
 | 
			
		||||
        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 | 
			
		||||
//        private static readonly ILog m_log =
 | 
			
		||||
//            LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 | 
			
		||||
 | 
			
		||||
        private string m_httpListenerHostName;
 | 
			
		||||
        private uint m_httpListenPort;
 | 
			
		||||
| 
						 | 
				
			
			@ -65,15 +64,14 @@ namespace OpenSim.Framework.Capabilities
 | 
			
		|||
 | 
			
		||||
        private CapsHandlers m_capsHandlers;
 | 
			
		||||
 | 
			
		||||
        private ConcurrentDictionary<string, PollServiceEventArgs> m_pollServiceHandlers
 | 
			
		||||
            = new ConcurrentDictionary<string, PollServiceEventArgs>();
 | 
			
		||||
        private Dictionary<string, PollServiceEventArgs> m_pollServiceHandlers 
 | 
			
		||||
            = new Dictionary<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
 | 
			
		||||
        {
 | 
			
		||||
| 
						 | 
				
			
			@ -120,19 +118,6 @@ namespace OpenSim.Framework.Capabilities
 | 
			
		|||
            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)
 | 
			
		||||
        {
 | 
			
		||||
| 
						 | 
				
			
			@ -150,37 +135,8 @@ namespace OpenSim.Framework.Capabilities
 | 
			
		|||
            }
 | 
			
		||||
 | 
			
		||||
            m_agentID = agent;
 | 
			
		||||
            m_capsHandlers = new CapsHandlers(httpServer, httpListen, httpPort);
 | 
			
		||||
            m_capsHandlers = new CapsHandlers(httpServer, httpListen, httpPort, (httpServer == null) ? false : httpServer.UseSSL);
 | 
			
		||||
            m_regionName = regionName;
 | 
			
		||||
            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>
 | 
			
		||||
| 
						 | 
				
			
			@ -194,27 +150,11 @@ namespace OpenSim.Framework.Capabilities
 | 
			
		|||
            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);
 | 
			
		||||
            m_pollServiceHandlers.Add(capName, pollServiceHandler);
 | 
			
		||||
 | 
			
		||||
            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);
 | 
			
		||||
            m_httpListener.AddPollServiceHTTPHandler(pollServiceHandler.Url, pollServiceHandler);
 | 
			
		||||
 | 
			
		||||
//            uint port = (MainServer.Instance == null) ? 0 : MainServer.Instance.Port;
 | 
			
		||||
//            string protocol = "http";
 | 
			
		||||
| 
						 | 
				
			
			@ -254,9 +194,8 @@ namespace OpenSim.Framework.Capabilities
 | 
			
		|||
 | 
			
		||||
            foreach (PollServiceEventArgs handler in m_pollServiceHandlers.Values)
 | 
			
		||||
            {
 | 
			
		||||
                m_httpListener.RemovePollServiceHTTPHandler(handler.Url);
 | 
			
		||||
                m_httpListener.RemovePollServiceHTTPHandler("", handler.Url);
 | 
			
		||||
            }
 | 
			
		||||
            m_pollServiceHandlers.Clear();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool TryGetPollHandler(string name, out PollServiceEventArgs pollHandler)
 | 
			
		||||
| 
						 | 
				
			
			@ -295,6 +234,9 @@ namespace OpenSim.Framework.Capabilities
 | 
			
		|||
                            port = MainServer.Instance.SSLPort;
 | 
			
		||||
                            protocol = "https";
 | 
			
		||||
                        }
 | 
			
		||||
    //
 | 
			
		||||
    //            caps.RegisterHandler("FetchInventoryDescendents2", String.Format("{0}://{1}:{2}{3}", protocol, hostName, port, capUrl));
 | 
			
		||||
 | 
			
		||||
                        caps[kvp.Key] = string.Format("{0}://{1}:{2}{3}", protocol, hostName, port, kvp.Value.Url);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -308,19 +250,7 @@ namespace OpenSim.Framework.Capabilities
 | 
			
		|||
                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);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -27,7 +27,6 @@
 | 
			
		|||
 | 
			
		||||
using System.Collections;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Collections.Concurrent;
 | 
			
		||||
using OpenSim.Framework.Servers;
 | 
			
		||||
using OpenSim.Framework.Servers.HttpServer;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -41,7 +40,6 @@ namespace OpenSim.Framework.Capabilities
 | 
			
		|||
    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;
 | 
			
		||||
| 
						 | 
				
			
			@ -55,15 +53,31 @@ namespace OpenSim.Framework.Capabilities
 | 
			
		|||
        /// <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)
 | 
			
		||||
           {
 | 
			
		||||
        public CapsHandlers(BaseHttpServer httpListener, string httpListenerHostname, uint httpListenerPort)
 | 
			
		||||
            : this(httpListener,httpListenerHostname,httpListenerPort, false)
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary></summary>
 | 
			
		||||
        /// CapsHandlers is a cap handler container but also takes
 | 
			
		||||
        /// care of adding and removing cap handlers to and from the
 | 
			
		||||
        /// supplied BaseHttpServer.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="httpListener">base HTTP server</param>
 | 
			
		||||
        /// <param name="httpListenerHostname">host name of the HTTP
 | 
			
		||||
        /// server</param>
 | 
			
		||||
        /// <param name="httpListenerPort">HTTP port</param>
 | 
			
		||||
        public CapsHandlers(IHttpServer httpListener, string httpListenerHostname, uint httpListenerPort, bool https)
 | 
			
		||||
        {
 | 
			
		||||
            m_httpListener = httpListener;
 | 
			
		||||
            m_httpListenerHostName = httpListenerHostname;
 | 
			
		||||
            m_httpListenerPort = httpListenerPort;
 | 
			
		||||
            if (httpListener != null && httpListener.UseSSL)
 | 
			
		||||
                m_useSSL = true;
 | 
			
		||||
            else
 | 
			
		||||
                m_useSSL = false;
 | 
			
		||||
            m_useSSL = https;
 | 
			
		||||
            if (httpListener != null && m_useSSL)
 | 
			
		||||
            {
 | 
			
		||||
                m_httpListenerHostName = httpListener.SSLCommonName;
 | 
			
		||||
                m_httpListenerPort = httpListener.SSLPort;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
| 
						 | 
				
			
			@ -75,35 +89,16 @@ namespace OpenSim.Framework.Capabilities
 | 
			
		|||
        {
 | 
			
		||||
            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);
 | 
			
		||||
                }
 | 
			
		||||
                m_httpListener.RemoveStreamHandler("POST", m_capsHandlers[capsName].Path);
 | 
			
		||||
                m_httpListener.RemoveStreamHandler("GET", 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);
 | 
			
		||||
                return m_capsHandlers.ContainsKey(cap);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
| 
						 | 
				
			
			@ -130,9 +125,6 @@ namespace OpenSim.Framework.Capabilities
 | 
			
		|||
                    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);
 | 
			
		||||
                    }
 | 
			
		||||
    
 | 
			
		||||
| 
						 | 
				
			
			@ -154,9 +146,8 @@ namespace OpenSim.Framework.Capabilities
 | 
			
		|||
            {
 | 
			
		||||
                lock (m_capsHandlers)
 | 
			
		||||
                {
 | 
			
		||||
                    string[] __keys = new string[m_capsHandlers.Keys.Count + m_capsSimpleHandlers.Keys.Count];
 | 
			
		||||
                    string[] __keys = new string[m_capsHandlers.Keys.Count];
 | 
			
		||||
                    m_capsHandlers.Keys.CopyTo(__keys, 0);
 | 
			
		||||
                    m_capsSimpleHandlers.Keys.CopyTo(__keys, m_capsHandlers.Keys.Count);
 | 
			
		||||
                    return __keys;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -170,39 +161,24 @@ namespace OpenSim.Framework.Capabilities
 | 
			
		|||
        public Hashtable GetCapsDetails(bool excludeSeed, List<string> requestedCaps)
 | 
			
		||||
        {
 | 
			
		||||
            Hashtable caps = new Hashtable();
 | 
			
		||||
            string protocol = "http://";
 | 
			
		||||
            
 | 
			
		||||
            if (m_useSSL)
 | 
			
		||||
                protocol = "https://";
 | 
			
		||||
 | 
			
		||||
            string protocol = m_useSSL ? "https://" : "http://";
 | 
			
		||||
            string baseUrl = protocol + m_httpListenerHostName + ":" + m_httpListenerPort.ToString();
 | 
			
		||||
 | 
			
		||||
            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)
 | 
			
		||||
                foreach (string capsName in m_capsHandlers.Keys)
 | 
			
		||||
                {
 | 
			
		||||
                    string capsName = requestedCaps[i];
 | 
			
		||||
                    if (excludeSeed && "SEED" == capsName)
 | 
			
		||||
                        continue;
 | 
			
		||||
 | 
			
		||||
                    if (m_capsSimpleHandlers.TryGetValue(capsName, out ISimpleStreamHandler shdr))
 | 
			
		||||
                    {
 | 
			
		||||
                        caps[capsName] = baseUrl + shdr.Path;
 | 
			
		||||
                    if (requestedCaps != null && !requestedCaps.Contains(capsName))
 | 
			
		||||
                        continue;
 | 
			
		||||
                    }
 | 
			
		||||
                    if (m_capsHandlers.TryGetValue(capsName, out IRequestHandler chdr))
 | 
			
		||||
                    {
 | 
			
		||||
                        caps[capsName] = baseUrl + chdr.Path;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    caps[capsName] = baseUrl + m_capsHandlers[capsName].Path;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,116 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) Contributors, http://opensimulator.org/
 | 
			
		||||
 * See CONTRIBUTORS.TXT for a full list of copyright holders.
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 *     * Redistributions of source code must retain the above copyright
 | 
			
		||||
 *       notice, this list of conditions and the following disclaimer.
 | 
			
		||||
 *     * Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *       notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *       documentation and/or other materials provided with the distribution.
 | 
			
		||||
 *     * Neither the name of the OpenSimulator Project nor the
 | 
			
		||||
 *       names of its contributors may be used to endorse or promote products
 | 
			
		||||
 *       derived from this software without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
 | 
			
		||||
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 | 
			
		||||
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 | 
			
		||||
 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
 | 
			
		||||
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 | 
			
		||||
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 | 
			
		||||
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 | 
			
		||||
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
			
		||||
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 | 
			
		||||
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Collections.Specialized;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
using System.Web;
 | 
			
		||||
using log4net;
 | 
			
		||||
using Nini.Config;
 | 
			
		||||
using OpenMetaverse;
 | 
			
		||||
using OpenSim.Framework;
 | 
			
		||||
using OpenSim.Framework.Capabilities;
 | 
			
		||||
using OpenSim.Framework.Servers;
 | 
			
		||||
using OpenSim.Framework.Servers.HttpServer;
 | 
			
		||||
//using OpenSim.Region.Framework.Interfaces;
 | 
			
		||||
using OpenSim.Services.Interfaces;
 | 
			
		||||
using Caps = OpenSim.Framework.Capabilities.Caps;
 | 
			
		||||
 | 
			
		||||
namespace OpenSim.Capabilities.Handlers
 | 
			
		||||
{
 | 
			
		||||
    public class AvatarPickerSearchHandler : BaseStreamHandler
 | 
			
		||||
    {
 | 
			
		||||
        private static readonly ILog m_log =
 | 
			
		||||
            LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 | 
			
		||||
        private IPeople m_PeopleService;
 | 
			
		||||
 | 
			
		||||
        public AvatarPickerSearchHandler(string path, IPeople peopleService, string name, string description)
 | 
			
		||||
            : base("GET", path, name, description)
 | 
			
		||||
        {
 | 
			
		||||
            m_PeopleService = peopleService;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
 | 
			
		||||
        {
 | 
			
		||||
            // Try to parse the texture ID from the request URL
 | 
			
		||||
            NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query);
 | 
			
		||||
            string names = query.GetOne("names");
 | 
			
		||||
            string psize = query.GetOne("page_size");
 | 
			
		||||
            string pnumber = query.GetOne("page");
 | 
			
		||||
 | 
			
		||||
            if (m_PeopleService == null)
 | 
			
		||||
                return FailureResponse(names, (int)System.Net.HttpStatusCode.InternalServerError, httpResponse);
 | 
			
		||||
 | 
			
		||||
            if (string.IsNullOrEmpty(names) || names.Length < 3)
 | 
			
		||||
                return FailureResponse(names, (int)System.Net.HttpStatusCode.BadRequest, httpResponse);
 | 
			
		||||
 | 
			
		||||
            m_log.DebugFormat("[AVATAR PICKER SEARCH]: search for {0}", names);
 | 
			
		||||
 | 
			
		||||
            int page_size = (string.IsNullOrEmpty(psize) ? 500 : Int32.Parse(psize));
 | 
			
		||||
            int page_number = (string.IsNullOrEmpty(pnumber) ? 1 : Int32.Parse(pnumber));
 | 
			
		||||
            
 | 
			
		||||
            // Full content request
 | 
			
		||||
            httpResponse.StatusCode = (int)System.Net.HttpStatusCode.OK;
 | 
			
		||||
            //httpResponse.ContentLength = ??;
 | 
			
		||||
            httpResponse.ContentType = "application/llsd+xml";
 | 
			
		||||
 | 
			
		||||
            List<UserData> users = m_PeopleService.GetUserData(names, page_size, page_number);
 | 
			
		||||
 | 
			
		||||
            LLSDAvatarPicker osdReply = new LLSDAvatarPicker();
 | 
			
		||||
            osdReply.next_page_url = httpRequest.RawUrl;
 | 
			
		||||
            foreach (UserData u in users)
 | 
			
		||||
                osdReply.agents.Array.Add(ConvertUserData(u));
 | 
			
		||||
 | 
			
		||||
            string reply = LLSDHelpers.SerialiseLLSDReply(osdReply);
 | 
			
		||||
            return System.Text.Encoding.UTF8.GetBytes(reply);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private LLSDPerson ConvertUserData(UserData user)
 | 
			
		||||
        {
 | 
			
		||||
            LLSDPerson p = new LLSDPerson();
 | 
			
		||||
            p.legacy_first_name = user.FirstName;
 | 
			
		||||
            p.legacy_last_name = user.LastName;
 | 
			
		||||
            p.display_name = user.FirstName + " " + user.LastName;
 | 
			
		||||
            if (user.LastName.StartsWith("@"))
 | 
			
		||||
                p.username = user.FirstName.ToLower() + user.LastName.ToLower();
 | 
			
		||||
            else
 | 
			
		||||
                p.username = user.FirstName.ToLower() + "." + user.LastName.ToLower();
 | 
			
		||||
            p.id = user.Id;
 | 
			
		||||
            p.is_display_name_default = false;
 | 
			
		||||
            return p;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private byte[] FailureResponse(string names, int statuscode, IOSHttpResponse httpResponse)
 | 
			
		||||
        {
 | 
			
		||||
            m_log.Error("[AVATAR PICKER SEARCH]: Error searching for " + names);
 | 
			
		||||
            httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
 | 
			
		||||
            return System.Text.Encoding.UTF8.GetBytes(string.Empty);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,449 +0,0 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) Contributors, http://opensimulator.org/
 | 
			
		||||
 * See CONTRIBUTORS.TXT for a full list of copyright holders.
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 *     * Redistributions of source code must retain the above copyright
 | 
			
		||||
 *       notice, this list of conditions and the following disclaimer.
 | 
			
		||||
 *     * Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *       notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *       documentation and/or other materials provided with the distribution.
 | 
			
		||||
 *     * Neither the name of the OpenSimulator Project nor the
 | 
			
		||||
 *       names of its contributors may be used to endorse or promote products
 | 
			
		||||
 *       derived from this software without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
 | 
			
		||||
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 | 
			
		||||
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 | 
			
		||||
 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
 | 
			
		||||
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 | 
			
		||||
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 | 
			
		||||
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 | 
			
		||||
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
			
		||||
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 | 
			
		||||
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using log4net;
 | 
			
		||||
using Nini.Config;
 | 
			
		||||
using OpenMetaverse;
 | 
			
		||||
using OpenMetaverse.StructuredData;
 | 
			
		||||
using OpenSim.Framework;
 | 
			
		||||
using OpenSim.Framework.Capabilities;
 | 
			
		||||
using OpenSim.Framework.Servers.HttpServer;
 | 
			
		||||
using OpenSim.Services.Interfaces;
 | 
			
		||||
using OSDMap = OpenMetaverse.StructuredData.OSDMap;
 | 
			
		||||
using OSDArray = OpenMetaverse.StructuredData.OSDArray;
 | 
			
		||||
 | 
			
		||||
namespace OpenSim.Capabilities.Handlers
 | 
			
		||||
{
 | 
			
		||||
    public class FetchInvDescHandler
 | 
			
		||||
    {
 | 
			
		||||
        private static readonly ILog m_log =
 | 
			
		||||
            LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 | 
			
		||||
 | 
			
		||||
        private static byte[] EmptyResponse = Util.UTF8NBGetbytes("<llsd><map><key>folders</key><array /></map></llsd>");
 | 
			
		||||
        private IInventoryService m_InventoryService;
 | 
			
		||||
        private ILibraryService m_LibraryService;
 | 
			
		||||
        private IScene m_Scene;
 | 
			
		||||
 | 
			
		||||
        public FetchInvDescHandler(IInventoryService invService, ILibraryService libService, IScene s)
 | 
			
		||||
        {
 | 
			
		||||
            m_InventoryService = invService;
 | 
			
		||||
            m_LibraryService = libService;
 | 
			
		||||
            m_Scene = s;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void FetchInventoryDescendentsRequest(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, ExpiringKey<UUID> BadRequests)
 | 
			
		||||
        {
 | 
			
		||||
            //m_log.DebugFormat("[XXX]: FetchInventoryDescendentsRequest in {0}, {1}", (m_Scene == null) ? "none" : m_Scene.Name, request);
 | 
			
		||||
 | 
			
		||||
            List<LLSDFetchInventoryDescendents> folders = null;
 | 
			
		||||
            List<UUID> bad_folders = new List<UUID>();
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                OSDArray foldersrequested = null;
 | 
			
		||||
                OSD tmp = OSDParser.DeserializeLLSDXml(httpRequest.InputStream);
 | 
			
		||||
                OSDMap map = (OSDMap)tmp;
 | 
			
		||||
                if(map.TryGetValue("folders", out tmp) && tmp is OSDArray)
 | 
			
		||||
                    foldersrequested = tmp as OSDArray;
 | 
			
		||||
 | 
			
		||||
                if (foldersrequested == null || foldersrequested.Count == 0)
 | 
			
		||||
                {
 | 
			
		||||
                    httpResponse.RawBuffer = EmptyResponse;
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                folders = new List<LLSDFetchInventoryDescendents>(foldersrequested.Count);
 | 
			
		||||
                for (int i = 0; i < foldersrequested.Count; i++)
 | 
			
		||||
                {
 | 
			
		||||
                    OSDMap mfolder = foldersrequested[i] as OSDMap;
 | 
			
		||||
                    UUID id = mfolder["folder_id"].AsUUID();
 | 
			
		||||
                    if(BadRequests.ContainsKey(id))
 | 
			
		||||
                    {
 | 
			
		||||
                        bad_folders.Add(id);
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        LLSDFetchInventoryDescendents llsdRequest = new LLSDFetchInventoryDescendents();
 | 
			
		||||
                        try
 | 
			
		||||
                        {
 | 
			
		||||
                            llsdRequest.folder_id = id;
 | 
			
		||||
                            llsdRequest.owner_id = mfolder["owner_id"].AsUUID();
 | 
			
		||||
                            llsdRequest.sort_order = mfolder["sort_order"].AsInteger();
 | 
			
		||||
                            llsdRequest.fetch_folders = mfolder["fetch_folders"].AsBoolean();
 | 
			
		||||
                            llsdRequest.fetch_items = mfolder["fetch_items"].AsBoolean();
 | 
			
		||||
                        }
 | 
			
		||||
                        catch (Exception e)
 | 
			
		||||
                        {
 | 
			
		||||
                            m_log.Debug("[WEB FETCH INV DESC HANDLER]: caught exception doing OSD deserialize" + e.Message);
 | 
			
		||||
                            continue;
 | 
			
		||||
                        }
 | 
			
		||||
                        folders.Add(llsdRequest);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                foldersrequested = null;
 | 
			
		||||
                tmp = null;
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception e)
 | 
			
		||||
            {
 | 
			
		||||
                m_log.ErrorFormat("[FETCH INV DESC]: fail parsing request: {0}", e.Message);
 | 
			
		||||
                httpResponse.RawBuffer = EmptyResponse;
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (folders == null || folders.Count == 0)
 | 
			
		||||
            {
 | 
			
		||||
                if(bad_folders.Count == 0)
 | 
			
		||||
                {
 | 
			
		||||
                    httpResponse.RawBuffer = EmptyResponse;
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                StringBuilder sb = osStringBuilderCache.Acquire();
 | 
			
		||||
                sb.Append("<llsd><map><key>folders</key><array /></map><map><key>bad_folders</key><array>");
 | 
			
		||||
                foreach (UUID bad in bad_folders)
 | 
			
		||||
                {
 | 
			
		||||
                    sb.Append("<map><key>folder_id</key><uuid>");
 | 
			
		||||
                    sb.Append(bad.ToString());
 | 
			
		||||
                    sb.Append("</uuid><key>error</key><string>Unknown</string></map>");
 | 
			
		||||
                }
 | 
			
		||||
                sb.Append("</array></map></llsd>");
 | 
			
		||||
                httpResponse.RawBuffer = Util.UTF8NBGetbytes(osStringBuilderCache.GetStringAndRelease(sb));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            int total_folders = 0;
 | 
			
		||||
            int total_items = 0;
 | 
			
		||||
 | 
			
		||||
            List<InventoryCollection> invcollSet = Fetch(folders, bad_folders, ref total_folders, ref total_items);
 | 
			
		||||
            //m_log.DebugFormat("[XXX]: Got {0} folders from a request of {1}", invcollSet.Count, folders.Count);
 | 
			
		||||
 | 
			
		||||
            int invcollSetCount = 0;
 | 
			
		||||
            if (invcollSet != null)
 | 
			
		||||
                invcollSetCount = invcollSet.Count;
 | 
			
		||||
 | 
			
		||||
            int mem = 8192 + ((256 * invcollSetCount +
 | 
			
		||||
                                384 * total_folders +
 | 
			
		||||
                                1024 * total_items +
 | 
			
		||||
                                128 * bad_folders.Count) & 0x7ffff000);
 | 
			
		||||
 | 
			
		||||
            StringBuilder lastresponse = new StringBuilder(mem);
 | 
			
		||||
            lastresponse.Append("<llsd>");
 | 
			
		||||
 | 
			
		||||
            if (invcollSetCount > 0)
 | 
			
		||||
            {
 | 
			
		||||
                lastresponse.Append("<map><key>folders</key><array>");
 | 
			
		||||
                int i = 0;
 | 
			
		||||
                InventoryCollection thiscoll;
 | 
			
		||||
                for (i = 0; i < invcollSetCount; i++)
 | 
			
		||||
                {
 | 
			
		||||
                    thiscoll = invcollSet[i];
 | 
			
		||||
                    invcollSet[i] = null;
 | 
			
		||||
 | 
			
		||||
                    LLSDxmlEncode.AddMap(lastresponse);
 | 
			
		||||
                    LLSDxmlEncode.AddElem("agent_id", thiscoll.OwnerID, lastresponse);
 | 
			
		||||
                    LLSDxmlEncode.AddElem("descendents", thiscoll.Descendents, lastresponse);
 | 
			
		||||
                    LLSDxmlEncode.AddElem("folder_id", thiscoll.FolderID, lastresponse);
 | 
			
		||||
 | 
			
		||||
                    if (thiscoll.Folders == null || thiscoll.Folders.Count == 0)
 | 
			
		||||
                        LLSDxmlEncode.AddEmptyArray("categories", lastresponse);
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        LLSDxmlEncode.AddArray("categories", lastresponse);
 | 
			
		||||
                        foreach (InventoryFolderBase invFolder in thiscoll.Folders)
 | 
			
		||||
                        {
 | 
			
		||||
                            LLSDxmlEncode.AddMap(lastresponse);
 | 
			
		||||
 | 
			
		||||
                            LLSDxmlEncode.AddElem("folder_id", invFolder.ID, lastresponse);
 | 
			
		||||
                            LLSDxmlEncode.AddElem("parent_id", invFolder.ParentID, lastresponse);
 | 
			
		||||
                            LLSDxmlEncode.AddElem("name", invFolder.Name, lastresponse);
 | 
			
		||||
                            LLSDxmlEncode.AddElem("type", invFolder.Type, lastresponse);
 | 
			
		||||
                            LLSDxmlEncode.AddElem("preferred_type", (int)-1, lastresponse);
 | 
			
		||||
                            LLSDxmlEncode.AddElem("version", invFolder.Version, lastresponse);
 | 
			
		||||
 | 
			
		||||
                            LLSDxmlEncode.AddEndMap(lastresponse);
 | 
			
		||||
                        }
 | 
			
		||||
                        LLSDxmlEncode.AddEndArray(lastresponse);
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    if (thiscoll.Items == null || thiscoll.Items.Count == 0)
 | 
			
		||||
                        LLSDxmlEncode.AddEmptyArray("items", lastresponse);
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        LLSDxmlEncode.AddArray("items", lastresponse);
 | 
			
		||||
                        foreach (InventoryItemBase invItem in thiscoll.Items)
 | 
			
		||||
                        {
 | 
			
		||||
                            invItem.ToLLSDxml(lastresponse);
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        LLSDxmlEncode.AddEndArray(lastresponse);
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    LLSDxmlEncode.AddElem("owner_id", thiscoll.OwnerID, lastresponse);
 | 
			
		||||
                    LLSDxmlEncode.AddElem("version", thiscoll.Version, lastresponse);
 | 
			
		||||
 | 
			
		||||
                    LLSDxmlEncode.AddEndMap(lastresponse);
 | 
			
		||||
                    invcollSet[i] = null;
 | 
			
		||||
                }
 | 
			
		||||
                lastresponse.Append("</array></map>");
 | 
			
		||||
                thiscoll = null;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                lastresponse.Append("<map><key>folders</key><array /></map>");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            //m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Bad folders {0}", string.Join(", ", bad_folders));
 | 
			
		||||
            if (bad_folders.Count > 0)
 | 
			
		||||
            {
 | 
			
		||||
                lastresponse.Append("<map><key>bad_folders</key><array>");
 | 
			
		||||
                foreach (UUID bad in bad_folders)
 | 
			
		||||
                {
 | 
			
		||||
                    BadRequests.Add(bad);
 | 
			
		||||
                    lastresponse.Append("<map><key>folder_id</key><uuid>");
 | 
			
		||||
                    lastresponse.Append(bad.ToString());
 | 
			
		||||
                    lastresponse.Append("</uuid><key>error</key><string>Unknown</string></map>");
 | 
			
		||||
                }
 | 
			
		||||
                lastresponse.Append("</array></map>");
 | 
			
		||||
            }
 | 
			
		||||
            lastresponse.Append("</llsd>");
 | 
			
		||||
 | 
			
		||||
            httpResponse.RawBuffer = Util.UTF8NBGetbytes(lastresponse.ToString());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void AddLibraryFolders(List<LLSDFetchInventoryDescendents> libFolders, List<InventoryCollection> result, ref int total_folders, ref int total_items)
 | 
			
		||||
        {
 | 
			
		||||
            InventoryFolderImpl fold;
 | 
			
		||||
            if (m_LibraryService == null || m_LibraryService.LibraryRootFolder == null)
 | 
			
		||||
                return;
 | 
			
		||||
            
 | 
			
		||||
            foreach (LLSDFetchInventoryDescendents f in libFolders)
 | 
			
		||||
            {
 | 
			
		||||
                if ((fold = m_LibraryService.LibraryRootFolder.FindFolder(f.folder_id)) != null)
 | 
			
		||||
                {
 | 
			
		||||
                    InventoryCollection Collection = new InventoryCollection();
 | 
			
		||||
//                        ret.Collection.Folders = new List<InventoryFolderBase>();
 | 
			
		||||
                    Collection.Folders = fold.RequestListOfFolders();
 | 
			
		||||
                    Collection.Items = fold.RequestListOfItems();
 | 
			
		||||
                    Collection.OwnerID = m_LibraryService.LibraryRootFolder.Owner;
 | 
			
		||||
                    Collection.FolderID = f.folder_id;
 | 
			
		||||
                    Collection.Version = fold.Version;
 | 
			
		||||
 | 
			
		||||
                    Collection.Descendents = Collection.Items.Count + Collection.Folders.Count;
 | 
			
		||||
                    total_folders += Collection.Folders.Count;
 | 
			
		||||
                    total_items += Collection.Items.Count;
 | 
			
		||||
                    result.Add(Collection);
 | 
			
		||||
 | 
			
		||||
                    //m_log.DebugFormat("[XXX]: Added libfolder {0} ({1}) {2}", ret.Collection.FolderID, ret.Collection.OwnerID);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private List<InventoryCollection> Fetch(List<LLSDFetchInventoryDescendents> fetchFolders, List<UUID> bad_folders, ref int total_folders, ref int total_items)
 | 
			
		||||
        {
 | 
			
		||||
            //m_log.DebugFormat(
 | 
			
		||||
            //    "[WEB FETCH INV DESC HANDLER]: Fetching {0} folders for owner {1}", fetchFolders.Count, fetchFolders[0].owner_id);
 | 
			
		||||
 | 
			
		||||
            // FIXME MAYBE: We're not handling sortOrder!
 | 
			
		||||
 | 
			
		||||
            List<InventoryCollection> result = new List<InventoryCollection>(32);
 | 
			
		||||
            List<LLSDFetchInventoryDescendents> libFolders = new List<LLSDFetchInventoryDescendents>(32);
 | 
			
		||||
            List<LLSDFetchInventoryDescendents> otherFolders = new List<LLSDFetchInventoryDescendents>(32);
 | 
			
		||||
            HashSet<UUID> libIDs = new HashSet<UUID>();
 | 
			
		||||
            HashSet<UUID> otherIDs = new HashSet<UUID>();
 | 
			
		||||
 | 
			
		||||
            bool dolib = (m_LibraryService != null && m_LibraryService.LibraryRootFolder != null);
 | 
			
		||||
            UUID libOwner = UUID.Zero;
 | 
			
		||||
            if(dolib)
 | 
			
		||||
                libOwner = m_LibraryService.LibraryRootFolder.Owner;
 | 
			
		||||
 | 
			
		||||
            // Filter folder Zero right here. Some viewers (Firestorm) send request for folder Zero, which doesn't make sense
 | 
			
		||||
            // and can kill the sim (all root folders have parent_id Zero)
 | 
			
		||||
            // send something.
 | 
			
		||||
            bool doneZeroID = false;
 | 
			
		||||
            foreach(LLSDFetchInventoryDescendents f in fetchFolders)
 | 
			
		||||
            {
 | 
			
		||||
                if (f.folder_id == UUID.Zero)
 | 
			
		||||
                {
 | 
			
		||||
                    if(doneZeroID)
 | 
			
		||||
                        continue;
 | 
			
		||||
                    doneZeroID = true;
 | 
			
		||||
                    InventoryCollection Collection = new InventoryCollection();
 | 
			
		||||
                    Collection.OwnerID = f.owner_id;
 | 
			
		||||
                    Collection.Version = 0;
 | 
			
		||||
                    Collection.FolderID = f.folder_id;
 | 
			
		||||
                    Collection.Descendents = 0;
 | 
			
		||||
                    result.Add(Collection);
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
                if(dolib && f.owner_id == libOwner)
 | 
			
		||||
                {
 | 
			
		||||
                    if(libIDs.Contains(f.folder_id))
 | 
			
		||||
                        continue;
 | 
			
		||||
                    libIDs.Add(f.folder_id);
 | 
			
		||||
                    libFolders.Add(f);
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
                if(otherIDs.Contains(f.folder_id))
 | 
			
		||||
                    continue;
 | 
			
		||||
 | 
			
		||||
                otherIDs.Add(f.folder_id);
 | 
			
		||||
                otherFolders.Add(f);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            fetchFolders.Clear();
 | 
			
		||||
 | 
			
		||||
            if(otherFolders.Count > 0)
 | 
			
		||||
            { 
 | 
			
		||||
                int i = 0;
 | 
			
		||||
 | 
			
		||||
                //m_log.DebugFormat("[XXX]: {0}", string.Join(",", fids));
 | 
			
		||||
 | 
			
		||||
                InventoryCollection[] fetchedContents = m_InventoryService.GetMultipleFoldersContent(otherFolders[0].owner_id, otherIDs.ToArray());
 | 
			
		||||
 | 
			
		||||
                if (fetchedContents == null)
 | 
			
		||||
                     return null;
 | 
			
		||||
 
 | 
			
		||||
                if (fetchedContents.Length == 0)
 | 
			
		||||
                {
 | 
			
		||||
                    foreach (LLSDFetchInventoryDescendents freq in otherFolders)
 | 
			
		||||
                        BadFolder(freq, null, bad_folders);
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    i = 0;
 | 
			
		||||
                    // Do some post-processing. May need to fetch more from inv server for links
 | 
			
		||||
                    foreach (InventoryCollection contents in fetchedContents)
 | 
			
		||||
                    {
 | 
			
		||||
                        // Find the original request
 | 
			
		||||
                        LLSDFetchInventoryDescendents freq = otherFolders[i];
 | 
			
		||||
                        otherFolders[i]=null;
 | 
			
		||||
                        i++;
 | 
			
		||||
 | 
			
		||||
                        if (BadFolder(freq, contents, bad_folders))
 | 
			
		||||
                            continue;
 | 
			
		||||
 | 
			
		||||
                        if(!freq.fetch_folders)
 | 
			
		||||
                            contents.Folders.Clear();
 | 
			
		||||
                        if(!freq.fetch_items)
 | 
			
		||||
                            contents.Items.Clear();
 | 
			
		||||
 | 
			
		||||
                        contents.Descendents = contents.Items.Count + contents.Folders.Count;
 | 
			
		||||
 
 | 
			
		||||
                        // Next: link management
 | 
			
		||||
                        ProcessLinks(freq, contents);
 | 
			
		||||
 | 
			
		||||
                        total_folders += contents.Folders.Count;
 | 
			
		||||
                        total_items += contents.Items.Count;
 | 
			
		||||
                        result.Add(contents);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if(dolib && libFolders.Count > 0)
 | 
			
		||||
            {
 | 
			
		||||
                AddLibraryFolders(libFolders, result, ref total_folders, ref total_items);           
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return result;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private bool BadFolder(LLSDFetchInventoryDescendents freq, InventoryCollection contents, List<UUID> bad_folders)
 | 
			
		||||
        {
 | 
			
		||||
            if (contents == null)
 | 
			
		||||
            {
 | 
			
		||||
                bad_folders.Add(freq.folder_id);
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // The inventory server isn't sending FolderID in the collection...
 | 
			
		||||
            // Must fetch it individually
 | 
			
		||||
            if (contents.FolderID == UUID.Zero)
 | 
			
		||||
            {
 | 
			
		||||
                InventoryFolderBase containingFolder = m_InventoryService.GetFolder(freq.owner_id, freq.folder_id);
 | 
			
		||||
                if (containingFolder == null)
 | 
			
		||||
                {
 | 
			
		||||
                    m_log.WarnFormat("[WEB FETCH INV DESC HANDLER]: Unable to fetch folder {0}", freq.folder_id);
 | 
			
		||||
                    bad_folders.Add(freq.folder_id);
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
                contents.FolderID = containingFolder.ID;
 | 
			
		||||
                contents.OwnerID = containingFolder.Owner;
 | 
			
		||||
                contents.Version = containingFolder.Version;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ProcessLinks(LLSDFetchInventoryDescendents freq, InventoryCollection contents)
 | 
			
		||||
        {
 | 
			
		||||
            if (contents.Items == null || contents.Items.Count == 0)
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
            // viewers are lasy and want a copy of the linked item sent before the link to it
 | 
			
		||||
 | 
			
		||||
            // look for item links
 | 
			
		||||
            List<UUID> itemIDs = new List<UUID>();
 | 
			
		||||
            foreach (InventoryItemBase item in contents.Items)
 | 
			
		||||
            {
 | 
			
		||||
                //m_log.DebugFormat("[XXX]:   {0} {1}", item.Name, item.AssetType);
 | 
			
		||||
                if (item.AssetType == (int)AssetType.Link)
 | 
			
		||||
                    itemIDs.Add(item.AssetID);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // get the linked if any
 | 
			
		||||
            if (itemIDs.Count > 0)
 | 
			
		||||
            {
 | 
			
		||||
                InventoryItemBase[] linked = m_InventoryService.GetMultipleItems(freq.owner_id, itemIDs.ToArray());
 | 
			
		||||
                    
 | 
			
		||||
                if (linked != null)
 | 
			
		||||
                {
 | 
			
		||||
                    List<InventoryItemBase> linkedItems = new List<InventoryItemBase>(linked.Length);
 | 
			
		||||
                    // check for broken
 | 
			
		||||
                    foreach (InventoryItemBase linkedItem in linked)
 | 
			
		||||
                    {
 | 
			
		||||
                        // Take care of genuinely broken links where the target doesn't exist
 | 
			
		||||
                        // HACK: Also, don't follow up links that just point to other links.  In theory this is legitimate,
 | 
			
		||||
                        // but no viewer has been observed to set these up and this is the lazy way of avoiding cycles
 | 
			
		||||
                        // rather than having to keep track of every folder requested in the recursion.
 | 
			
		||||
                        if (linkedItem != null && linkedItem.AssetType != (int)AssetType.Link)
 | 
			
		||||
                        {
 | 
			
		||||
                            linkedItems.Add(linkedItem);
 | 
			
		||||
                            //m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Added {0} {1} {2}", linkedItem.Name, linkedItem.AssetType, linkedItem.Folder);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    // insert them
 | 
			
		||||
                    if(linkedItems.Count > 0)
 | 
			
		||||
                        contents.Items.InsertRange(0, linkedItems);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,166 +0,0 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) Contributors, http://opensimulator.org/
 | 
			
		||||
 * See CONTRIBUTORS.TXT for a full list of copyright holders.
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 *     * Redistributions of source code must retain the above copyright
 | 
			
		||||
 *       notice, this list of conditions and the following disclaimer.
 | 
			
		||||
 *     * Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *       notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *       documentation and/or other materials provided with the distribution.
 | 
			
		||||
 *     * Neither the name of the OpenSimulator Project nor the
 | 
			
		||||
 *       names of its contributors may be used to endorse or promote products
 | 
			
		||||
 *       derived from this software without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
 | 
			
		||||
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 | 
			
		||||
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 | 
			
		||||
 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
 | 
			
		||||
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 | 
			
		||||
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 | 
			
		||||
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 | 
			
		||||
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
			
		||||
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 | 
			
		||||
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
using System.Net;
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using OpenMetaverse;
 | 
			
		||||
using OpenMetaverse.StructuredData;
 | 
			
		||||
using OpenSim.Framework;
 | 
			
		||||
using OpenSim.Framework.Servers.HttpServer;
 | 
			
		||||
using OpenSim.Services.Interfaces;
 | 
			
		||||
using OSDArray = OpenMetaverse.StructuredData.OSDArray;
 | 
			
		||||
using OSDMap = OpenMetaverse.StructuredData.OSDMap;
 | 
			
		||||
 | 
			
		||||
using log4net;
 | 
			
		||||
 | 
			
		||||
namespace OpenSim.Capabilities.Handlers
 | 
			
		||||
{
 | 
			
		||||
    public class FetchInventory2Handler
 | 
			
		||||
    {
 | 
			
		||||
        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 | 
			
		||||
 | 
			
		||||
        private IInventoryService m_inventoryService;
 | 
			
		||||
        private UUID m_agentID;
 | 
			
		||||
 | 
			
		||||
        public FetchInventory2Handler(IInventoryService invService, UUID agentId)
 | 
			
		||||
        {
 | 
			
		||||
            m_inventoryService = invService;
 | 
			
		||||
            m_agentID = agentId;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public string FetchInventoryRequest(string request, string path, string param, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
 | 
			
		||||
        {
 | 
			
		||||
            //m_log.DebugFormat("[FETCH INVENTORY HANDLER]: Received FetchInventory capability request {0}", request);
 | 
			
		||||
 | 
			
		||||
            OSDMap requestmap = (OSDMap)OSDParser.DeserializeLLSDXml(Utils.StringToBytes(request));
 | 
			
		||||
            OSDArray itemsRequested = (OSDArray)requestmap["items"];
 | 
			
		||||
 | 
			
		||||
            UUID[] itemIDs = new UUID[itemsRequested.Count];
 | 
			
		||||
            int i = 0;
 | 
			
		||||
 | 
			
		||||
            foreach (OSDMap osdItemId in itemsRequested)
 | 
			
		||||
            {
 | 
			
		||||
                itemIDs[i++] = osdItemId["item_id"].AsUUID();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            InventoryItemBase[] items = null;
 | 
			
		||||
 | 
			
		||||
            if (m_agentID != UUID.Zero)
 | 
			
		||||
            {
 | 
			
		||||
                items = m_inventoryService.GetMultipleItems(m_agentID, itemIDs);
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                items = new InventoryItemBase[itemsRequested.Count];
 | 
			
		||||
                foreach (UUID id in itemIDs)
 | 
			
		||||
                    items[i++] = m_inventoryService.GetItem(UUID.Zero, id);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            StringBuilder lsl = LLSDxmlEncode.Start(4096);
 | 
			
		||||
            LLSDxmlEncode.AddMap(lsl);
 | 
			
		||||
 | 
			
		||||
            if(m_agentID == UUID.Zero && items.Length > 0)
 | 
			
		||||
                LLSDxmlEncode.AddElem("agent_id", items[0].Owner, lsl);
 | 
			
		||||
            else
 | 
			
		||||
                LLSDxmlEncode.AddElem("agent_id", m_agentID, lsl);
 | 
			
		||||
 | 
			
		||||
            if(items == null || items.Length == 0)
 | 
			
		||||
            {
 | 
			
		||||
                LLSDxmlEncode.AddEmptyArray("items", lsl);
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                LLSDxmlEncode.AddArray("items", lsl);
 | 
			
		||||
                foreach (InventoryItemBase item in items)
 | 
			
		||||
                {
 | 
			
		||||
                    if (item != null)
 | 
			
		||||
                        item.ToLLSDxml(lsl, 0xff);
 | 
			
		||||
                }
 | 
			
		||||
                LLSDxmlEncode.AddEndArray(lsl);
 | 
			
		||||
            }            
 | 
			
		||||
 | 
			
		||||
            LLSDxmlEncode.AddEndMap(lsl);
 | 
			
		||||
            return LLSDxmlEncode.End(lsl);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void FetchInventorySimpleRequest(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, OSDMap requestmap, ExpiringKey<UUID> BadRequests)
 | 
			
		||||
        {
 | 
			
		||||
            //m_log.DebugFormat("[FETCH INVENTORY HANDLER]: Received FetchInventory capability request {0}", request);
 | 
			
		||||
 | 
			
		||||
            if(BadRequests == null)
 | 
			
		||||
            {
 | 
			
		||||
                httpResponse.StatusCode = (int)HttpStatusCode.NotFound;
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            OSDArray itemsRequested = (OSDArray)requestmap["items"];
 | 
			
		||||
 | 
			
		||||
            UUID[] itemIDs = new UUID[itemsRequested.Count];
 | 
			
		||||
            int i = 0;
 | 
			
		||||
            foreach (OSDMap osdItemId in itemsRequested)
 | 
			
		||||
            {
 | 
			
		||||
                UUID id = osdItemId["item_id"].AsUUID();
 | 
			
		||||
                if(!BadRequests.ContainsKey(id))
 | 
			
		||||
                    itemIDs[i++] = id;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            InventoryItemBase[] items = null;
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                // badrequests still not filled
 | 
			
		||||
                items = m_inventoryService.GetMultipleItems(m_agentID, itemIDs);
 | 
			
		||||
            }
 | 
			
		||||
            catch{ }
 | 
			
		||||
 | 
			
		||||
            StringBuilder lsl = LLSDxmlEncode.Start(4096);
 | 
			
		||||
            LLSDxmlEncode.AddMap(lsl);
 | 
			
		||||
 | 
			
		||||
            LLSDxmlEncode.AddElem("agent_id", m_agentID, lsl);
 | 
			
		||||
 | 
			
		||||
            if (items == null || items.Length == 0)
 | 
			
		||||
            {
 | 
			
		||||
                LLSDxmlEncode.AddEmptyArray("items", lsl);
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                LLSDxmlEncode.AddArray("items", lsl);
 | 
			
		||||
                foreach (InventoryItemBase item in items)
 | 
			
		||||
                {
 | 
			
		||||
                    if (item != null)
 | 
			
		||||
                        item.ToLLSDxml(lsl, 0xff);
 | 
			
		||||
                }
 | 
			
		||||
                LLSDxmlEncode.AddEndArray(lsl);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            LLSDxmlEncode.AddEndMap(lsl);
 | 
			
		||||
            httpResponse.RawBuffer = Util.UTF8.GetBytes(LLSDxmlEncode.End(lsl));
 | 
			
		||||
            httpResponse.StatusCode = (int)HttpStatusCode.OK;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,170 +0,0 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) Contributors, http://opensimulator.org/
 | 
			
		||||
 * See CONTRIBUTORS.TXT for a full list of copyright holders.
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 *     * Redistributions of source code must retain the above copyright
 | 
			
		||||
 *       notice, this list of conditions and the following disclaimer.
 | 
			
		||||
 *     * Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *       notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *       documentation and/or other materials provided with the distribution.
 | 
			
		||||
 *     * Neither the name of the OpenSimulator Project nor the
 | 
			
		||||
 *       names of its contributors may be used to endorse or promote products
 | 
			
		||||
 *       derived from this software without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
 | 
			
		||||
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 | 
			
		||||
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 | 
			
		||||
 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
 | 
			
		||||
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 | 
			
		||||
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 | 
			
		||||
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 | 
			
		||||
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
			
		||||
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 | 
			
		||||
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Net;
 | 
			
		||||
using System.Text.RegularExpressions;
 | 
			
		||||
using log4net;
 | 
			
		||||
using log4net.Config;
 | 
			
		||||
using NUnit.Framework;
 | 
			
		||||
using OpenMetaverse;
 | 
			
		||||
using OpenSim.Capabilities.Handlers;
 | 
			
		||||
using OpenSim.Framework;
 | 
			
		||||
using OpenSim.Framework.Servers.HttpServer;
 | 
			
		||||
using OpenSim.Region.Framework.Scenes;
 | 
			
		||||
using OpenSim.Services.Interfaces;
 | 
			
		||||
using OpenSim.Tests.Common;
 | 
			
		||||
 | 
			
		||||
namespace OpenSim.Capabilities.Handlers.FetchInventory.Tests
 | 
			
		||||
{
 | 
			
		||||
    [TestFixture]
 | 
			
		||||
    public class FetchInventory2HandlerTests : OpenSimTestCase
 | 
			
		||||
    {
 | 
			
		||||
        private UUID m_userID = UUID.Random();
 | 
			
		||||
        private Scene m_scene;
 | 
			
		||||
        private UUID m_rootFolderID;
 | 
			
		||||
        private UUID m_notecardsFolder;
 | 
			
		||||
        private UUID m_objectsFolder;
 | 
			
		||||
 | 
			
		||||
        private void Init()
 | 
			
		||||
        {
 | 
			
		||||
            // Create an inventory that looks like this:
 | 
			
		||||
            //
 | 
			
		||||
            // /My Inventory
 | 
			
		||||
            //   <other system folders>
 | 
			
		||||
            //   /Objects
 | 
			
		||||
            //      Object 1
 | 
			
		||||
            //      Object 2
 | 
			
		||||
            //      Object 3
 | 
			
		||||
            //   /Notecards
 | 
			
		||||
            //      Notecard 1
 | 
			
		||||
            //      Notecard 2
 | 
			
		||||
            //      Notecard 3
 | 
			
		||||
            //      Notecard 4
 | 
			
		||||
            //      Notecard 5
 | 
			
		||||
 | 
			
		||||
            m_scene = new SceneHelpers().SetupScene();
 | 
			
		||||
 | 
			
		||||
            m_scene.InventoryService.CreateUserInventory(m_userID);
 | 
			
		||||
 | 
			
		||||
            m_rootFolderID = m_scene.InventoryService.GetRootFolder(m_userID).ID;
 | 
			
		||||
 | 
			
		||||
            InventoryFolderBase of = m_scene.InventoryService.GetFolderForType(m_userID, FolderType.Object);
 | 
			
		||||
            m_objectsFolder = of.ID;
 | 
			
		||||
 | 
			
		||||
            // Add 3 objects
 | 
			
		||||
            InventoryItemBase item;
 | 
			
		||||
            for (int i = 1; i <= 3; i++)
 | 
			
		||||
            {
 | 
			
		||||
                item = new InventoryItemBase(new UUID("b0000000-0000-0000-0000-0000000000b" + i), m_userID);
 | 
			
		||||
                item.AssetID = UUID.Random();
 | 
			
		||||
                item.AssetType = (int)AssetType.Object;
 | 
			
		||||
                item.Folder = m_objectsFolder;
 | 
			
		||||
                item.Name = "Object " + i;
 | 
			
		||||
                m_scene.InventoryService.AddItem(item);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            InventoryFolderBase ncf = m_scene.InventoryService.GetFolderForType(m_userID, FolderType.Notecard);
 | 
			
		||||
            m_notecardsFolder = ncf.ID;
 | 
			
		||||
 | 
			
		||||
            // Add 5 notecards
 | 
			
		||||
            for (int i = 1; i <= 5; i++)
 | 
			
		||||
            {
 | 
			
		||||
                item = new InventoryItemBase(new UUID("10000000-0000-0000-0000-00000000000" + i), m_userID);
 | 
			
		||||
                item.AssetID = UUID.Random();
 | 
			
		||||
                item.AssetType = (int)AssetType.Notecard;
 | 
			
		||||
                item.Folder = m_notecardsFolder;
 | 
			
		||||
                item.Name = "Notecard " + i;
 | 
			
		||||
                m_scene.InventoryService.AddItem(item);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Test]
 | 
			
		||||
        public void Test_001_RequestOne()
 | 
			
		||||
        {
 | 
			
		||||
            TestHelpers.InMethod();
 | 
			
		||||
 | 
			
		||||
            Init();
 | 
			
		||||
 | 
			
		||||
            FetchInventory2Handler handler = new FetchInventory2Handler(m_scene.InventoryService, m_userID);
 | 
			
		||||
            TestOSHttpRequest req = new TestOSHttpRequest();
 | 
			
		||||
            TestOSHttpResponse resp = new TestOSHttpResponse();
 | 
			
		||||
 | 
			
		||||
            string request = "<llsd><map><key>items</key><array><map><key>item_id</key><uuid>";
 | 
			
		||||
            request += "10000000-0000-0000-0000-000000000001"; // Notecard 1
 | 
			
		||||
            request += "</uuid></map></array></map></llsd>";
 | 
			
		||||
 | 
			
		||||
            string llsdresponse = handler.FetchInventoryRequest(request, "/FETCH", string.Empty, req, resp);
 | 
			
		||||
 | 
			
		||||
            Assert.That(llsdresponse != null, Is.True, "Incorrect null response");
 | 
			
		||||
            Assert.That(llsdresponse != string.Empty, Is.True, "Incorrect empty response");
 | 
			
		||||
            Assert.That(llsdresponse.Contains(m_userID.ToString()), Is.True, "Response should contain userID");
 | 
			
		||||
 | 
			
		||||
            Assert.That(llsdresponse.Contains("10000000-0000-0000-0000-000000000001"), Is.True, "Response does not contain item uuid");
 | 
			
		||||
            Assert.That(llsdresponse.Contains("Notecard 1"), Is.True, "Response does not contain item Name");
 | 
			
		||||
            Console.WriteLine(llsdresponse);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Test]
 | 
			
		||||
        public void Test_002_RequestMany()
 | 
			
		||||
        {
 | 
			
		||||
            TestHelpers.InMethod();
 | 
			
		||||
 | 
			
		||||
            Init();
 | 
			
		||||
 | 
			
		||||
            FetchInventory2Handler handler = new FetchInventory2Handler(m_scene.InventoryService, m_userID);
 | 
			
		||||
            TestOSHttpRequest req = new TestOSHttpRequest();
 | 
			
		||||
            TestOSHttpResponse resp = new TestOSHttpResponse();
 | 
			
		||||
 | 
			
		||||
            string request = "<llsd><map><key>items</key><array>";
 | 
			
		||||
            request += "<map><key>item_id</key><uuid>10000000-0000-0000-0000-000000000001</uuid></map>"; // Notecard 1
 | 
			
		||||
            request += "<map><key>item_id</key><uuid>10000000-0000-0000-0000-000000000002</uuid></map>"; // Notecard 2
 | 
			
		||||
            request += "<map><key>item_id</key><uuid>10000000-0000-0000-0000-000000000003</uuid></map>"; // Notecard 3
 | 
			
		||||
            request += "<map><key>item_id</key><uuid>10000000-0000-0000-0000-000000000004</uuid></map>"; // Notecard 4
 | 
			
		||||
            request += "<map><key>item_id</key><uuid>10000000-0000-0000-0000-000000000005</uuid></map>"; // Notecard 5
 | 
			
		||||
            request += "</array></map></llsd>";
 | 
			
		||||
 | 
			
		||||
            string llsdresponse = handler.FetchInventoryRequest(request, "/FETCH", string.Empty, req, resp);
 | 
			
		||||
 | 
			
		||||
            Assert.That(llsdresponse != null, Is.True, "Incorrect null response");
 | 
			
		||||
            Assert.That(llsdresponse != string.Empty, Is.True, "Incorrect empty response");
 | 
			
		||||
            Assert.That(llsdresponse.Contains(m_userID.ToString()), Is.True, "Response should contain userID");
 | 
			
		||||
 | 
			
		||||
            Console.WriteLine(llsdresponse);
 | 
			
		||||
            Assert.That(llsdresponse.Contains("10000000-0000-0000-0000-000000000001"), Is.True, "Response does not contain notecard 1");
 | 
			
		||||
            Assert.That(llsdresponse.Contains("10000000-0000-0000-0000-000000000002"), Is.True, "Response does not contain notecard 2");
 | 
			
		||||
            Assert.That(llsdresponse.Contains("10000000-0000-0000-0000-000000000003"), Is.True, "Response does not contain notecard 3");
 | 
			
		||||
            Assert.That(llsdresponse.Contains("10000000-0000-0000-0000-000000000004"), Is.True, "Response does not contain notecard 4");
 | 
			
		||||
            Assert.That(llsdresponse.Contains("10000000-0000-0000-0000-000000000005"), Is.True, "Response does not contain notecard 5");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,300 +0,0 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) Contributors, http://opensimulator.org/
 | 
			
		||||
 * See CONTRIBUTORS.TXT for a full list of copyright holders.
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 *     * Redistributions of source code must retain the above copyright
 | 
			
		||||
 *       notice, this list of conditions and the following disclaimer.
 | 
			
		||||
 *     * Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *       notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *       documentation and/or other materials provided with the distribution.
 | 
			
		||||
 *     * Neither the name of the OpenSimulator Project nor the
 | 
			
		||||
 *       names of its contributors may be used to endorse or promote products
 | 
			
		||||
 *       derived from this software without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
 | 
			
		||||
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 | 
			
		||||
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 | 
			
		||||
 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
 | 
			
		||||
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 | 
			
		||||
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 | 
			
		||||
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 | 
			
		||||
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
			
		||||
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 | 
			
		||||
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Text.RegularExpressions;
 | 
			
		||||
using log4net;
 | 
			
		||||
using log4net.Config;
 | 
			
		||||
using NUnit.Framework;
 | 
			
		||||
using OpenMetaverse;
 | 
			
		||||
using OpenSim.Capabilities.Handlers;
 | 
			
		||||
using OpenSim.Framework;
 | 
			
		||||
using OpenSim.Framework.Servers.HttpServer;
 | 
			
		||||
using OpenSim.Region.Framework.Scenes;
 | 
			
		||||
using OpenSim.Services.Interfaces;
 | 
			
		||||
using OpenSim.Tests.Common;
 | 
			
		||||
 | 
			
		||||
namespace OpenSim.Capabilities.Handlers.FetchInventory.Tests
 | 
			
		||||
{
 | 
			
		||||
    [TestFixture]
 | 
			
		||||
    public class FetchInventoryDescendents2HandlerTests : OpenSimTestCase
 | 
			
		||||
    {
 | 
			
		||||
        private UUID m_userID = new UUID("00000000-0000-0000-0000-000000000001");
 | 
			
		||||
        private Scene m_scene;
 | 
			
		||||
        private UUID m_rootFolderID;
 | 
			
		||||
        private int m_rootDescendents;
 | 
			
		||||
        private UUID m_notecardsFolder;
 | 
			
		||||
        private UUID m_objectsFolder;
 | 
			
		||||
 | 
			
		||||
        private void Init()
 | 
			
		||||
        {
 | 
			
		||||
            // Create an inventory that looks like this:
 | 
			
		||||
            //
 | 
			
		||||
            // /My Inventory
 | 
			
		||||
            //   <other system folders>
 | 
			
		||||
            //   /Objects
 | 
			
		||||
            //      Some Object
 | 
			
		||||
            //   /Notecards
 | 
			
		||||
            //      Notecard 1
 | 
			
		||||
            //      Notecard 2
 | 
			
		||||
            //   /Test Folder
 | 
			
		||||
            //      Link to notecard  -> /Notecards/Notecard 2
 | 
			
		||||
            //      Link to Objects folder -> /Objects
 | 
			
		||||
 | 
			
		||||
            m_scene = new SceneHelpers().SetupScene();
 | 
			
		||||
 | 
			
		||||
            m_scene.InventoryService.CreateUserInventory(m_userID);
 | 
			
		||||
 | 
			
		||||
            m_rootFolderID = m_scene.InventoryService.GetRootFolder(m_userID).ID;
 | 
			
		||||
 | 
			
		||||
            InventoryFolderBase of = m_scene.InventoryService.GetFolderForType(m_userID, FolderType.Object);
 | 
			
		||||
            m_objectsFolder = of.ID;
 | 
			
		||||
 | 
			
		||||
            // Add an object
 | 
			
		||||
            InventoryItemBase item = new InventoryItemBase(new UUID("b0000000-0000-0000-0000-00000000000b"), m_userID);
 | 
			
		||||
            item.AssetID = UUID.Random();
 | 
			
		||||
            item.AssetType = (int)AssetType.Object;
 | 
			
		||||
            item.Folder = m_objectsFolder;
 | 
			
		||||
            item.Name = "Some Object";
 | 
			
		||||
            m_scene.InventoryService.AddItem(item);
 | 
			
		||||
 | 
			
		||||
            InventoryFolderBase ncf = m_scene.InventoryService.GetFolderForType(m_userID, FolderType.Notecard);
 | 
			
		||||
            m_notecardsFolder = ncf.ID;
 | 
			
		||||
 | 
			
		||||
            // Add a notecard
 | 
			
		||||
            item = new InventoryItemBase(new UUID("10000000-0000-0000-0000-000000000001"), m_userID);
 | 
			
		||||
            item.AssetID = UUID.Random();
 | 
			
		||||
            item.AssetType = (int)AssetType.Notecard;
 | 
			
		||||
            item.Folder = m_notecardsFolder;
 | 
			
		||||
            item.Name = "Test Notecard 1";
 | 
			
		||||
            m_scene.InventoryService.AddItem(item);
 | 
			
		||||
            // Add another notecard
 | 
			
		||||
            item.ID = new UUID("20000000-0000-0000-0000-000000000002");
 | 
			
		||||
            item.AssetID = new UUID("a0000000-0000-0000-0000-00000000000a");
 | 
			
		||||
            item.Name = "Test Notecard 2";
 | 
			
		||||
            m_scene.InventoryService.AddItem(item);
 | 
			
		||||
 | 
			
		||||
            // Add a folder
 | 
			
		||||
            InventoryFolderBase folder = new InventoryFolderBase(new UUID("f0000000-0000-0000-0000-00000000000f"), "Test Folder", m_userID, m_rootFolderID);
 | 
			
		||||
            folder.Type = (short)FolderType.None;
 | 
			
		||||
            m_scene.InventoryService.AddFolder(folder);
 | 
			
		||||
 | 
			
		||||
            // Add a link to notecard 2 in Test Folder
 | 
			
		||||
            item.AssetID = item.ID; // use item ID of notecard 2
 | 
			
		||||
            item.ID = new UUID("40000000-0000-0000-0000-000000000004");
 | 
			
		||||
            item.AssetType = (int)AssetType.Link;
 | 
			
		||||
            item.Folder = folder.ID;
 | 
			
		||||
            item.Name = "Link to notecard";
 | 
			
		||||
            m_scene.InventoryService.AddItem(item);
 | 
			
		||||
 | 
			
		||||
            // Add a link to the Objects folder in Test Folder
 | 
			
		||||
            item.AssetID = m_scene.InventoryService.GetFolderForType(m_userID, FolderType.Object).ID; // use item ID of Objects folder
 | 
			
		||||
            item.ID = new UUID("50000000-0000-0000-0000-000000000005");
 | 
			
		||||
            item.AssetType = (int)AssetType.LinkFolder;
 | 
			
		||||
            item.Folder = folder.ID;
 | 
			
		||||
            item.Name = "Link to Objects folder";
 | 
			
		||||
            m_scene.InventoryService.AddItem(item);
 | 
			
		||||
 | 
			
		||||
            InventoryCollection coll = m_scene.InventoryService.GetFolderContent(m_userID, m_rootFolderID);
 | 
			
		||||
            m_rootDescendents = coll.Items.Count + coll.Folders.Count;
 | 
			
		||||
            Console.WriteLine("Number of descendents: " + m_rootDescendents);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private string dorequest(FetchInvDescHandler handler, string request)
 | 
			
		||||
        {
 | 
			
		||||
            TestOSHttpRequest req = new TestOSHttpRequest();
 | 
			
		||||
            TestOSHttpResponse resp = new TestOSHttpResponse();
 | 
			
		||||
            using(ExpiringKey<UUID> bad = new ExpiringKey<UUID>(5000)) // bad but this is test
 | 
			
		||||
            using (MemoryStream ms = new MemoryStream(Utils.StringToBytes(request), false))
 | 
			
		||||
            {
 | 
			
		||||
                req.InputStream = ms;
 | 
			
		||||
                handler.FetchInventoryDescendentsRequest(req, resp, bad);
 | 
			
		||||
            }
 | 
			
		||||
            return Util.UTF8.GetString(resp.RawBuffer);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Test]
 | 
			
		||||
        public void Test_001_SimpleFolder()
 | 
			
		||||
        {
 | 
			
		||||
            TestHelpers.InMethod();
 | 
			
		||||
 | 
			
		||||
            Init();
 | 
			
		||||
 | 
			
		||||
            FetchInvDescHandler handler = new FetchInvDescHandler(m_scene.InventoryService, null, m_scene);
 | 
			
		||||
 | 
			
		||||
            string request = "<llsd><map><key>folders</key><array><map><key>fetch_folders</key><integer>1</integer><key>fetch_items</key><boolean>1</boolean><key>folder_id</key><uuid>";
 | 
			
		||||
            request += m_rootFolderID;
 | 
			
		||||
            request += "</uuid><key>owner_id</key><uuid>";
 | 
			
		||||
            request += m_userID.ToString();
 | 
			
		||||
            request += "</uuid><key>sort_order</key><integer>1</integer></map></array></map></llsd>";
 | 
			
		||||
 | 
			
		||||
            string llsdresponse = dorequest(handler, request);
 | 
			
		||||
 | 
			
		||||
            Assert.That(llsdresponse != null, Is.True, "Incorrect null response");
 | 
			
		||||
            Assert.That(llsdresponse != string.Empty, Is.True, "Incorrect empty response");
 | 
			
		||||
            Assert.That(llsdresponse.Contains(m_userID.ToString()), Is.True, "Response should contain userID");
 | 
			
		||||
 | 
			
		||||
            string descendents = "descendents</key><integer>" + m_rootDescendents + "</integer>";
 | 
			
		||||
            Assert.That(llsdresponse.Contains(descendents), Is.True, "Incorrect number of descendents");
 | 
			
		||||
            Console.WriteLine(llsdresponse);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Test]
 | 
			
		||||
        public void Test_002_MultipleFolders()
 | 
			
		||||
        {
 | 
			
		||||
            TestHelpers.InMethod();
 | 
			
		||||
 | 
			
		||||
            FetchInvDescHandler handler = new FetchInvDescHandler(m_scene.InventoryService, null, m_scene);
 | 
			
		||||
 | 
			
		||||
            string request = "<llsd><map><key>folders</key><array>";
 | 
			
		||||
            request += "<map><key>fetch_folders</key><integer>1</integer><key>fetch_items</key><boolean>1</boolean><key>folder_id</key><uuid>";
 | 
			
		||||
            request += m_rootFolderID;
 | 
			
		||||
            request += "</uuid><key>owner_id</key><uuid>00000000-0000-0000-0000-000000000001</uuid><key>sort_order</key><integer>1</integer></map>";
 | 
			
		||||
            request += "<map><key>fetch_folders</key><integer>1</integer><key>fetch_items</key><boolean>1</boolean><key>folder_id</key><uuid>";
 | 
			
		||||
            request += m_notecardsFolder;
 | 
			
		||||
            request += "</uuid><key>owner_id</key><uuid>00000000-0000-0000-0000-000000000001</uuid><key>sort_order</key><integer>1</integer></map>";
 | 
			
		||||
            request += "</array></map></llsd>";
 | 
			
		||||
 | 
			
		||||
            string llsdresponse = dorequest(handler, request);
 | 
			
		||||
            Console.WriteLine(llsdresponse);
 | 
			
		||||
 | 
			
		||||
            string descendents = "descendents</key><integer>" + m_rootDescendents + "</integer>";
 | 
			
		||||
            Assert.That(llsdresponse.Contains(descendents), Is.True, "Incorrect number of descendents for root folder");
 | 
			
		||||
            descendents = "descendents</key><integer>2</integer>";
 | 
			
		||||
            Assert.That(llsdresponse.Contains(descendents), Is.True, "Incorrect number of descendents for Notecard folder");
 | 
			
		||||
 | 
			
		||||
            Assert.That(llsdresponse.Contains("10000000-0000-0000-0000-000000000001"), Is.True, "Notecard 1 is missing from response");
 | 
			
		||||
            Assert.That(llsdresponse.Contains("20000000-0000-0000-0000-000000000002"), Is.True, "Notecard 2 is missing from response");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Test]
 | 
			
		||||
        public void Test_003_Links()
 | 
			
		||||
        {
 | 
			
		||||
            TestHelpers.InMethod();
 | 
			
		||||
 | 
			
		||||
            FetchInvDescHandler handler = new FetchInvDescHandler(m_scene.InventoryService, null, m_scene);
 | 
			
		||||
 | 
			
		||||
            string request = "<llsd><map><key>folders</key><array><map><key>fetch_folders</key><integer>1</integer><key>fetch_items</key><boolean>1</boolean><key>folder_id</key><uuid>";
 | 
			
		||||
            request += "f0000000-0000-0000-0000-00000000000f";
 | 
			
		||||
            request += "</uuid><key>owner_id</key><uuid>00000000-0000-0000-0000-000000000001</uuid><key>sort_order</key><integer>1</integer></map></array></map></llsd>";
 | 
			
		||||
 | 
			
		||||
            string llsdresponse = dorequest(handler, request);
 | 
			
		||||
            Console.WriteLine(llsdresponse);
 | 
			
		||||
 | 
			
		||||
            string descendents = "descendents</key><integer>2</integer>";
 | 
			
		||||
            Assert.That(llsdresponse.Contains(descendents), Is.True, "Incorrect number of descendents for Test Folder");
 | 
			
		||||
 | 
			
		||||
            // Make sure that the note card link is included
 | 
			
		||||
            Assert.That(llsdresponse.Contains("Link to notecard"), Is.True, "Link to notecard is missing");
 | 
			
		||||
 | 
			
		||||
            //Make sure the notecard item itself is included
 | 
			
		||||
            Assert.That(llsdresponse.Contains("Test Notecard 2"), Is.True, "Notecard 2 item (the source) is missing");
 | 
			
		||||
 | 
			
		||||
            // Make sure that the source item is before the link item
 | 
			
		||||
            int pos1 = llsdresponse.IndexOf("Test Notecard 2");
 | 
			
		||||
            int pos2 = llsdresponse.IndexOf("Link to notecard");
 | 
			
		||||
            Assert.Less(pos1, pos2, "Source of link is after link");
 | 
			
		||||
 | 
			
		||||
            // Make sure the folder link is included
 | 
			
		||||
            Assert.That(llsdresponse.Contains("Link to Objects folder"), Is.True, "Link to Objects folder is missing");
 | 
			
		||||
 | 
			
		||||
/* contents of link folder are not supposed to be listed
 | 
			
		||||
            // Make sure the objects inside the Objects folder are included
 | 
			
		||||
            // Note: I'm not entirely sure this is needed, but that's what I found in the implementation
 | 
			
		||||
            Assert.That(llsdresponse.Contains("Some Object"), Is.True, "Some Object item (contents of the source) is missing");
 | 
			
		||||
*/
 | 
			
		||||
            // Make sure that the source item is before the link item
 | 
			
		||||
            pos1 = llsdresponse.IndexOf("Some Object");
 | 
			
		||||
            pos2 = llsdresponse.IndexOf("Link to Objects folder");
 | 
			
		||||
            Assert.Less(pos1, pos2, "Contents of source of folder link is after folder link");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Test]
 | 
			
		||||
        public void Test_004_DuplicateFolders()
 | 
			
		||||
        {
 | 
			
		||||
            TestHelpers.InMethod();
 | 
			
		||||
 | 
			
		||||
            FetchInvDescHandler handler = new FetchInvDescHandler(m_scene.InventoryService, null, m_scene);
 | 
			
		||||
 | 
			
		||||
            string request = "<llsd><map><key>folders</key><array>";
 | 
			
		||||
            request += "<map><key>fetch_folders</key><integer>1</integer><key>fetch_items</key><boolean>1</boolean><key>folder_id</key><uuid>";
 | 
			
		||||
            request += m_rootFolderID;
 | 
			
		||||
            request += "</uuid><key>owner_id</key><uuid>00000000-0000-0000-0000-000000000000</uuid><key>sort_order</key><integer>1</integer></map>";
 | 
			
		||||
            request += "<map><key>fetch_folders</key><integer>1</integer><key>fetch_items</key><boolean>1</boolean><key>folder_id</key><uuid>";
 | 
			
		||||
            request += m_notecardsFolder;
 | 
			
		||||
            request += "</uuid><key>owner_id</key><uuid>00000000-0000-0000-0000-000000000000</uuid><key>sort_order</key><integer>1</integer></map>";
 | 
			
		||||
            request += "<map><key>fetch_folders</key><integer>1</integer><key>fetch_items</key><boolean>1</boolean><key>folder_id</key><uuid>";
 | 
			
		||||
            request += m_rootFolderID;
 | 
			
		||||
            request += "</uuid><key>owner_id</key><uuid>00000000-0000-0000-0000-000000000000</uuid><key>sort_order</key><integer>1</integer></map>";
 | 
			
		||||
            request += "<map><key>fetch_folders</key><integer>1</integer><key>fetch_items</key><boolean>1</boolean><key>folder_id</key><uuid>";
 | 
			
		||||
            request += m_notecardsFolder;
 | 
			
		||||
            request += "</uuid><key>owner_id</key><uuid>00000000-0000-0000-0000-000000000000</uuid><key>sort_order</key><integer>1</integer></map>";
 | 
			
		||||
            request += "</array></map></llsd>";
 | 
			
		||||
 | 
			
		||||
            string llsdresponse = dorequest(handler, request);
 | 
			
		||||
            Console.WriteLine(llsdresponse);
 | 
			
		||||
 | 
			
		||||
            string root_folder = "<key>folder_id</key><uuid>" + m_rootFolderID + "</uuid>";
 | 
			
		||||
            string notecards_folder = "<key>folder_id</key><uuid>" + m_notecardsFolder + "</uuid>";
 | 
			
		||||
 | 
			
		||||
            Assert.That(llsdresponse.Contains(root_folder), "Missing root folder");
 | 
			
		||||
            Assert.That(llsdresponse.Contains(notecards_folder), "Missing notecards folder");
 | 
			
		||||
            int count = Regex.Matches(llsdresponse, root_folder).Count;
 | 
			
		||||
            Assert.AreEqual(1, count, "More than 1 root folder in response");
 | 
			
		||||
            count = Regex.Matches(llsdresponse, notecards_folder).Count;
 | 
			
		||||
            Assert.AreEqual(2, count, "More than 1 notecards folder in response"); // Notecards will also be under root, so 2
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Test]
 | 
			
		||||
        public void Test_005_FolderZero()
 | 
			
		||||
        {
 | 
			
		||||
 | 
			
		||||
            TestHelpers.InMethod();
 | 
			
		||||
 | 
			
		||||
            Init();
 | 
			
		||||
 | 
			
		||||
            FetchInvDescHandler handler = new FetchInvDescHandler(m_scene.InventoryService, null, m_scene);
 | 
			
		||||
 | 
			
		||||
            string request = "<llsd><map><key>folders</key><array><map><key>fetch_folders</key><integer>1</integer><key>fetch_items</key><boolean>1</boolean><key>folder_id</key><uuid>";
 | 
			
		||||
            request += UUID.Zero;
 | 
			
		||||
            request += "</uuid><key>owner_id</key><uuid>00000000-0000-0000-0000-000000000000</uuid><key>sort_order</key><integer>1</integer></map></array></map></llsd>";
 | 
			
		||||
 | 
			
		||||
            string llsdresponse = dorequest(handler, request);
 | 
			
		||||
 | 
			
		||||
            Assert.That(llsdresponse != null, Is.True, "Incorrect null response");
 | 
			
		||||
            Assert.That(llsdresponse != string.Empty, Is.True, "Incorrect empty response");
 | 
			
		||||
            // we do return a answer now
 | 
			
		||||
            //Assert.That(llsdresponse.Contains("bad_folders</key><array><uuid>00000000-0000-0000-0000-000000000000"), Is.True, "Folder Zero should be a bad folder");
 | 
			
		||||
 | 
			
		||||
            Console.WriteLine(llsdresponse);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,124 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) Contributors, http://opensimulator.org/
 | 
			
		||||
 * See CONTRIBUTORS.TXT for a full list of copyright holders.
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 *     * Redistributions of source code must retain the above copyright
 | 
			
		||||
 *       notice, this list of conditions and the following disclaimer.
 | 
			
		||||
 *     * Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *       notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *       documentation and/or other materials provided with the distribution.
 | 
			
		||||
 *     * Neither the name of the OpenSimulator Project nor the
 | 
			
		||||
 *       names of its contributors may be used to endorse or promote products
 | 
			
		||||
 *       derived from this software without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
 | 
			
		||||
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 | 
			
		||||
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 | 
			
		||||
 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
 | 
			
		||||
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 | 
			
		||||
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 | 
			
		||||
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 | 
			
		||||
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
			
		||||
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 | 
			
		||||
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
using log4net;
 | 
			
		||||
using Nini.Config;
 | 
			
		||||
using OpenMetaverse;
 | 
			
		||||
using OpenMetaverse.StructuredData;
 | 
			
		||||
using OpenSim.Framework;
 | 
			
		||||
using OpenSim.Framework.Capabilities;
 | 
			
		||||
using OpenSim.Region.Framework.Interfaces;
 | 
			
		||||
using OpenSim.Framework.Servers.HttpServer;
 | 
			
		||||
using OpenSim.Services.Interfaces;
 | 
			
		||||
using Caps = OpenSim.Framework.Capabilities.Caps;
 | 
			
		||||
using OSDArray = OpenMetaverse.StructuredData.OSDArray;
 | 
			
		||||
using OSDMap = OpenMetaverse.StructuredData.OSDMap;
 | 
			
		||||
 | 
			
		||||
namespace OpenSim.Capabilities.Handlers
 | 
			
		||||
{
 | 
			
		||||
    public class FetchInventory2Handler
 | 
			
		||||
    {
 | 
			
		||||
//        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 | 
			
		||||
 | 
			
		||||
        private IInventoryService m_inventoryService;
 | 
			
		||||
 | 
			
		||||
        public FetchInventory2Handler(IInventoryService invService)
 | 
			
		||||
        {
 | 
			
		||||
            m_inventoryService = invService;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public string FetchInventoryRequest(string request, string path, string param, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
 | 
			
		||||
        {
 | 
			
		||||
//            m_log.DebugFormat("[FETCH INVENTORY HANDLER]: Received FetchInventory capabilty request");
 | 
			
		||||
 | 
			
		||||
            OSDMap requestmap = (OSDMap)OSDParser.DeserializeLLSDXml(Utils.StringToBytes(request));
 | 
			
		||||
            OSDArray itemsRequested = (OSDArray)requestmap["items"];
 | 
			
		||||
 | 
			
		||||
            string reply;
 | 
			
		||||
            LLSDFetchInventory llsdReply = new LLSDFetchInventory();
 | 
			
		||||
 | 
			
		||||
            foreach (OSDMap osdItemId in itemsRequested)
 | 
			
		||||
            {
 | 
			
		||||
                UUID itemId = osdItemId["item_id"].AsUUID();
 | 
			
		||||
 | 
			
		||||
                InventoryItemBase item = m_inventoryService.GetItem(new InventoryItemBase(itemId));
 | 
			
		||||
 | 
			
		||||
                if (item != null)
 | 
			
		||||
                {
 | 
			
		||||
                    // We don't know the agent that this request belongs to so we'll use the agent id of the item
 | 
			
		||||
                    // which will be the same for all items.
 | 
			
		||||
                    llsdReply.agent_id = item.Owner;
 | 
			
		||||
 | 
			
		||||
                    llsdReply.items.Array.Add(ConvertInventoryItem(item));
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            reply = LLSDHelpers.SerialiseLLSDReply(llsdReply);
 | 
			
		||||
 | 
			
		||||
            return reply;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Convert an internal inventory item object into an LLSD object.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="invItem"></param>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        private LLSDInventoryItem ConvertInventoryItem(InventoryItemBase invItem)
 | 
			
		||||
        {
 | 
			
		||||
            LLSDInventoryItem llsdItem = new LLSDInventoryItem();
 | 
			
		||||
            llsdItem.asset_id = invItem.AssetID;
 | 
			
		||||
            llsdItem.created_at = invItem.CreationDate;
 | 
			
		||||
            llsdItem.desc = invItem.Description;
 | 
			
		||||
            llsdItem.flags = (int)invItem.Flags;
 | 
			
		||||
            llsdItem.item_id = invItem.ID;
 | 
			
		||||
            llsdItem.name = invItem.Name;
 | 
			
		||||
            llsdItem.parent_id = invItem.Folder;
 | 
			
		||||
            llsdItem.type = invItem.AssetType;
 | 
			
		||||
            llsdItem.inv_type = invItem.InvType;
 | 
			
		||||
 | 
			
		||||
            llsdItem.permissions = new LLSDPermissions();
 | 
			
		||||
            llsdItem.permissions.creator_id = invItem.CreatorIdAsUuid;
 | 
			
		||||
            llsdItem.permissions.base_mask = (int)invItem.CurrentPermissions;
 | 
			
		||||
            llsdItem.permissions.everyone_mask = (int)invItem.EveryOnePermissions;
 | 
			
		||||
            llsdItem.permissions.group_id = invItem.GroupID;
 | 
			
		||||
            llsdItem.permissions.group_mask = (int)invItem.GroupPermissions;
 | 
			
		||||
            llsdItem.permissions.is_owner_group = invItem.GroupOwned;
 | 
			
		||||
            llsdItem.permissions.next_owner_mask = (int)invItem.NextPermissions;
 | 
			
		||||
            llsdItem.permissions.owner_id = invItem.Owner;
 | 
			
		||||
            llsdItem.permissions.owner_mask = (int)invItem.CurrentPermissions;
 | 
			
		||||
            llsdItem.sale_info = new LLSDSaleInfo();
 | 
			
		||||
            llsdItem.sale_info.sale_price = invItem.SalePrice;
 | 
			
		||||
            llsdItem.sale_info.sale_type = invItem.SaleType;
 | 
			
		||||
 | 
			
		||||
            return llsdItem;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -61,7 +61,7 @@ namespace OpenSim.Capabilities.Handlers
 | 
			
		|||
            if (m_InventoryService == null)
 | 
			
		||||
                throw new Exception(String.Format("Failed to load InventoryService from {0}; config is {1}", invService, m_ConfigName));
 | 
			
		||||
 | 
			
		||||
            FetchInventory2Handler fiHandler = new FetchInventory2Handler(m_InventoryService, UUID.Zero);
 | 
			
		||||
            FetchInventory2Handler fiHandler = new FetchInventory2Handler(m_InventoryService);
 | 
			
		||||
            IRequestHandler reqHandler
 | 
			
		||||
                = new RestStreamHandler(
 | 
			
		||||
                    "POST", "/CAPS/FetchInventory/", fiHandler.FetchInventoryRequest, "FetchInventory", null);
 | 
			
		||||
| 
						 | 
				
			
			@ -1,190 +0,0 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) Contributors, http://opensimulator.org/
 | 
			
		||||
 * See CONTRIBUTORS.TXT for a full list of copyright holders.
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 *     * Redistributions of source code must retain the above copyright
 | 
			
		||||
 *       notice, this list of conditions and the following disclaimer.
 | 
			
		||||
 *     * Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *       notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *       documentation and/or other materials provided with the distribution.
 | 
			
		||||
 *     * Neither the name of the OpenSimulator Project nor the
 | 
			
		||||
 *       names of its contributors may be used to endorse or promote products
 | 
			
		||||
 *       derived from this software without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
 | 
			
		||||
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 | 
			
		||||
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 | 
			
		||||
 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
 | 
			
		||||
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 | 
			
		||||
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 | 
			
		||||
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 | 
			
		||||
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
			
		||||
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 | 
			
		||||
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Net;
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
using log4net;
 | 
			
		||||
using Nini.Config;
 | 
			
		||||
using OpenMetaverse;
 | 
			
		||||
using OpenMetaverse.StructuredData;
 | 
			
		||||
using OpenSim.Framework;
 | 
			
		||||
using OpenSim.Framework.Servers;
 | 
			
		||||
using OpenSim.Framework.Servers.HttpServer;
 | 
			
		||||
using OpenSim.Services.Interfaces;
 | 
			
		||||
using Caps = OpenSim.Framework.Capabilities.Caps;
 | 
			
		||||
 | 
			
		||||
namespace OpenSim.Capabilities.Handlers
 | 
			
		||||
{
 | 
			
		||||
    public class GetAssetsHandler
 | 
			
		||||
    {
 | 
			
		||||
        private static readonly ILog m_log =
 | 
			
		||||
                   LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 | 
			
		||||
 | 
			
		||||
        private static readonly Dictionary<string, AssetType> queryTypes = new Dictionary<string, AssetType>()
 | 
			
		||||
        {
 | 
			
		||||
            {"texture_id", AssetType.Texture},
 | 
			
		||||
            {"sound_id", AssetType.Sound},
 | 
			
		||||
            {"callcard_id", AssetType.CallingCard},
 | 
			
		||||
            {"landmark_id", AssetType.Landmark},
 | 
			
		||||
            {"script_id", AssetType.LSLText},
 | 
			
		||||
            {"clothing_id", AssetType.Clothing},
 | 
			
		||||
            {"object_id", AssetType.Object},
 | 
			
		||||
            {"notecard_id", AssetType.Notecard},
 | 
			
		||||
            {"lsltext_id", AssetType.LSLText},
 | 
			
		||||
            {"lslbyte_id", AssetType.LSLBytecode},
 | 
			
		||||
            {"txtr_tga_id", AssetType.TextureTGA},
 | 
			
		||||
            {"bodypart_id", AssetType.Bodypart},
 | 
			
		||||
            {"snd_wav_id", AssetType.SoundWAV},
 | 
			
		||||
            {"img_tga_id", AssetType.ImageTGA},
 | 
			
		||||
            {"jpeg_id", AssetType.ImageJPEG},
 | 
			
		||||
            {"animatn_id", AssetType.Animation},
 | 
			
		||||
            {"gesture_id", AssetType.Gesture},
 | 
			
		||||
            {"mesh_id", AssetType.Mesh},
 | 
			
		||||
            {"settings_id", AssetType.Settings}
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        private IAssetService m_assetService;
 | 
			
		||||
 | 
			
		||||
        public GetAssetsHandler(IAssetService assService)
 | 
			
		||||
        {
 | 
			
		||||
            m_assetService = assService;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void Handle(OSHttpRequest req, OSHttpResponse response)
 | 
			
		||||
        {
 | 
			
		||||
            response.ContentType = "text/plain";
 | 
			
		||||
 | 
			
		||||
            if (m_assetService == null)
 | 
			
		||||
            {
 | 
			
		||||
                response.StatusCode = (int)HttpStatusCode.ServiceUnavailable;
 | 
			
		||||
                response.KeepAlive = false;
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            response.StatusCode = (int)HttpStatusCode.BadRequest;
 | 
			
		||||
 | 
			
		||||
            var queries = req.QueryAsDictionary;
 | 
			
		||||
            if(queries.Count == 0)
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
            AssetType type = AssetType.Unknown;
 | 
			
		||||
            string assetStr = string.Empty;
 | 
			
		||||
            foreach (KeyValuePair<string,string> kvp in queries)
 | 
			
		||||
            {
 | 
			
		||||
                if (queryTypes.ContainsKey(kvp.Key))
 | 
			
		||||
                {
 | 
			
		||||
                    type = queryTypes[kvp.Key];
 | 
			
		||||
                    assetStr = kvp.Value;
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if(type == AssetType.Unknown)
 | 
			
		||||
            {
 | 
			
		||||
                //m_log.Warn("[GETASSET]: Unknown type: " + query);
 | 
			
		||||
                m_log.Warn("[GETASSET]: Unknown type");
 | 
			
		||||
                response.StatusCode = (int)HttpStatusCode.NotFound;
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (String.IsNullOrEmpty(assetStr))
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
            UUID assetID = UUID.Zero;
 | 
			
		||||
            if(!UUID.TryParse(assetStr, out assetID))
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
            AssetBase asset = m_assetService.Get(assetID.ToString());
 | 
			
		||||
            if(asset == null)
 | 
			
		||||
            {
 | 
			
		||||
                // m_log.Warn("[GETASSET]: not found: " + query + " " + assetStr);
 | 
			
		||||
                response.StatusCode = (int)HttpStatusCode.NotFound;
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (asset.Type != (sbyte)type)
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
            int len = asset.Data.Length;
 | 
			
		||||
 | 
			
		||||
            string range = null;
 | 
			
		||||
            if (req.Headers["Range"] != null)
 | 
			
		||||
                range = req.Headers["Range"];
 | 
			
		||||
            else if (req.Headers["range"] != null)
 | 
			
		||||
                range = req.Headers["range"];
 | 
			
		||||
 | 
			
		||||
            // range request
 | 
			
		||||
            int start, end;
 | 
			
		||||
            if (Util.TryParseHttpRange(range, out start, out end))
 | 
			
		||||
            {
 | 
			
		||||
                // Before clamping start make sure we can satisfy it in order to avoid
 | 
			
		||||
                // sending back the last byte instead of an error status
 | 
			
		||||
                if (start >= asset.Data.Length)
 | 
			
		||||
                {
 | 
			
		||||
                    response.StatusCode = (int)HttpStatusCode.RequestedRangeNotSatisfiable;
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (end == -1)
 | 
			
		||||
                    end = asset.Data.Length - 1;
 | 
			
		||||
                else
 | 
			
		||||
                    end = Utils.Clamp(end, 0, asset.Data.Length - 1);
 | 
			
		||||
 | 
			
		||||
                start = Utils.Clamp(start, 0, end);
 | 
			
		||||
                len = end - start + 1;
 | 
			
		||||
 | 
			
		||||
                //m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID);
 | 
			
		||||
                response.AddHeader("Content-Range", String.Format("bytes {0}-{1}/{2}", start, end, asset.Data.Length));
 | 
			
		||||
                response.StatusCode = (int)HttpStatusCode.PartialContent;
 | 
			
		||||
                response.RawBufferStart = start;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
                response.StatusCode = (int)HttpStatusCode.OK;
 | 
			
		||||
 | 
			
		||||
            response.ContentType = asset.Metadata.ContentType;
 | 
			
		||||
            response.RawBuffer = asset.Data;
 | 
			
		||||
            response.RawBufferLen = len;
 | 
			
		||||
            if (type == AssetType.Mesh || type == AssetType.Texture)
 | 
			
		||||
            {
 | 
			
		||||
                if(len > 8196)
 | 
			
		||||
                {
 | 
			
		||||
                    //if(type == AssetType.Texture && ((asset.Flags & AssetFlags.AvatarBake)!= 0))
 | 
			
		||||
                    //    responsedata["prio"] = 1;
 | 
			
		||||
                    //else
 | 
			
		||||
                    response.Priority = 2;
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                    response.Priority = 1;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
                response.Priority = -1;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -45,110 +45,71 @@ namespace OpenSim.Capabilities.Handlers
 | 
			
		|||
{
 | 
			
		||||
    public class GetMeshHandler 
 | 
			
		||||
    {
 | 
			
		||||
        private static readonly ILog m_log =
 | 
			
		||||
                   LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 | 
			
		||||
//        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["int_response_code"] = 400; //501; //410; //404;
 | 
			
		||||
            responsedata["content_type"] = "text/plain";
 | 
			
		||||
            responsedata["int_bytes"] = 0;
 | 
			
		||||
            responsedata["keepalive"] = false;
 | 
			
		||||
            responsedata["str_response_string"] = "Request wasn't what was expected";
 | 
			
		||||
 | 
			
		||||
            string meshStr = string.Empty;
 | 
			
		||||
 | 
			
		||||
            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)
 | 
			
		||||
            if (!String.IsNullOrEmpty(meshStr) && UUID.TryParse(meshStr, out meshID))
 | 
			
		||||
            {
 | 
			
		||||
                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)
 | 
			
		||||
                if (m_assetService == null)
 | 
			
		||||
                {
 | 
			
		||||
                    responsedata["str_response_string"] = "This range doesnt exist.";
 | 
			
		||||
                    responsedata["int_response_code"] = 404; //501; //410; //404;
 | 
			
		||||
                    responsedata["content_type"] = "text/plain";
 | 
			
		||||
                    responsedata["keepalive"] = false;
 | 
			
		||||
                    responsedata["str_response_string"] = "The asset service is unavailable.  So is your mesh.";
 | 
			
		||||
                    return responsedata;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                end = Utils.Clamp(end, 0, mesh.Data.Length - 1);
 | 
			
		||||
                start = Utils.Clamp(start, 0, end);
 | 
			
		||||
                int len = end - start + 1;
 | 
			
		||||
                AssetBase mesh = m_assetService.Get(meshID.ToString());
 | 
			
		||||
 | 
			
		||||
                //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;
 | 
			
		||||
                if (mesh != null)
 | 
			
		||||
                {
 | 
			
		||||
                    if (mesh.Type == (SByte)AssetType.Mesh)
 | 
			
		||||
                    {
 | 
			
		||||
                        responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data);
 | 
			
		||||
                        responsedata["content_type"] = "application/vnd.ll.mesh";
 | 
			
		||||
                        responsedata["int_response_code"] = 200;
 | 
			
		||||
                    }
 | 
			
		||||
                    // Optionally add additional mesh types here
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        responsedata["int_response_code"] = 404; //501; //410; //404;
 | 
			
		||||
                        responsedata["content_type"] = "text/plain";
 | 
			
		||||
                        responsedata["keepalive"] = false;
 | 
			
		||||
                        responsedata["str_response_string"] = "Unfortunately, this asset isn't a mesh.";
 | 
			
		||||
                        return responsedata;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    responsedata["int_response_code"] = 404; //501; //410; //404;
 | 
			
		||||
                    responsedata["content_type"] = "text/plain";
 | 
			
		||||
                    responsedata["keepalive"] = false;
 | 
			
		||||
                    responsedata["str_response_string"] = "Your Mesh wasn't found.  Sorry!";
 | 
			
		||||
                    return responsedata;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            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;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -25,13 +25,16 @@
 | 
			
		|||
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
using Nini.Config;
 | 
			
		||||
using OpenMetaverse;
 | 
			
		||||
using OpenSim.Framework.Servers.HttpServer;
 | 
			
		||||
using OpenSim.Server.Base;
 | 
			
		||||
using OpenSim.Server.Handlers.Base;
 | 
			
		||||
using OpenSim.Services.Interfaces;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections;
 | 
			
		||||
using Nini.Config;
 | 
			
		||||
using OpenSim.Server.Base;
 | 
			
		||||
using OpenSim.Services.Interfaces;
 | 
			
		||||
using OpenSim.Framework.Servers.HttpServer;
 | 
			
		||||
using OpenSim.Server.Handlers.Base;
 | 
			
		||||
using OpenSim.Framework.Servers;
 | 
			
		||||
 | 
			
		||||
using OpenMetaverse;
 | 
			
		||||
 | 
			
		||||
namespace OpenSim.Capabilities.Handlers
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -62,17 +65,15 @@ namespace OpenSim.Capabilities.Handlers
 | 
			
		|||
            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(),
 | 
			
		||||
                    "/CAPS/" + UUID.Random(),
 | 
			
		||||
                    httpMethod => gmeshHandler.ProcessGetMesh(httpMethod, UUID.Zero, null),
 | 
			
		||||
                    "GetMesh",
 | 
			
		||||
                    null);
 | 
			
		||||
            server.AddStreamHandler(reqHandler); ;
 | 
			
		||||
            server.AddStreamHandler(reqHandler);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -47,34 +47,36 @@ using Caps = OpenSim.Framework.Capabilities.Caps;
 | 
			
		|||
 | 
			
		||||
namespace OpenSim.Capabilities.Handlers
 | 
			
		||||
{
 | 
			
		||||
    public class GetTextureHandler
 | 
			
		||||
    public class GetTextureHandler : BaseStreamHandler
 | 
			
		||||
    {
 | 
			
		||||
        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)
 | 
			
		||||
        // TODO: Change this to a config option
 | 
			
		||||
        const string REDIRECT_URL = null;
 | 
			
		||||
 | 
			
		||||
        public GetTextureHandler(string path, IAssetService assService, string name, string description)
 | 
			
		||||
            : base("GET", path, name, description)
 | 
			
		||||
        {
 | 
			
		||||
            m_assetService = assService;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Hashtable Handle(Hashtable request)
 | 
			
		||||
        protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
 | 
			
		||||
        {
 | 
			
		||||
            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"];
 | 
			
		||||
            // 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;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            UUID textureID;
 | 
			
		||||
| 
						 | 
				
			
			@ -89,39 +91,30 @@ namespace OpenSim.Capabilities.Handlers
 | 
			
		|||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    formats = new string[1] { DefaultFormat }; // default
 | 
			
		||||
                    if (((Hashtable)request["headers"])["Accept"] != null)
 | 
			
		||||
                        formats = WebUtil.GetPreferredImageTypes((string)((Hashtable)request["headers"])["Accept"]);
 | 
			
		||||
                    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
 | 
			
		||||
                bool foundtexture = false;
 | 
			
		||||
 | 
			
		||||
                httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
 | 
			
		||||
                foreach (string f in formats)
 | 
			
		||||
                {
 | 
			
		||||
                    foundtexture = FetchTexture(request, ret, textureID, f);
 | 
			
		||||
                    if (foundtexture)
 | 
			
		||||
                    if (FetchTexture(httpRequest, httpResponse, textureID, f))
 | 
			
		||||
                        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.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 ret;
 | 
			
		||||
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
| 
						 | 
				
			
			@ -132,7 +125,7 @@ namespace OpenSim.Capabilities.Handlers
 | 
			
		|||
        /// <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)
 | 
			
		||||
        private bool FetchTexture(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, UUID textureID, string format)
 | 
			
		||||
        {
 | 
			
		||||
//            m_log.DebugFormat("[GETTEXTURE]: {0} with requested format {1}", textureID, format);
 | 
			
		||||
            AssetBase texture;
 | 
			
		||||
| 
						 | 
				
			
			@ -141,76 +134,91 @@ namespace OpenSim.Capabilities.Handlers
 | 
			
		|||
            if (format != DefaultFormat)
 | 
			
		||||
                fullID = fullID + "-" + format;
 | 
			
		||||
 | 
			
		||||
            // try the cache
 | 
			
		||||
            texture = m_assetService.GetCached(fullID);
 | 
			
		||||
 | 
			
		||||
            if (texture == null)
 | 
			
		||||
            if (!String.IsNullOrEmpty(REDIRECT_URL))
 | 
			
		||||
            {
 | 
			
		||||
                //m_log.DebugFormat("[GETTEXTURE]: texture was not in the cache");
 | 
			
		||||
 | 
			
		||||
                // Fetch locally or remotely. Misses return a 404
 | 
			
		||||
                texture = m_assetService.Get(textureID.ToString());
 | 
			
		||||
                // Only try to fetch locally cached textures. Misses are redirected
 | 
			
		||||
                texture = m_assetService.GetCached(fullID);
 | 
			
		||||
 | 
			
		||||
                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);
 | 
			
		||||
                        httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
 | 
			
		||||
                        return true;
 | 
			
		||||
                    }
 | 
			
		||||
                    WriteTextureData(httpRequest, httpResponse, texture, format);
 | 
			
		||||
                }
 | 
			
		||||
           }
 | 
			
		||||
           else // it was on the cache
 | 
			
		||||
           {
 | 
			
		||||
               //m_log.DebugFormat("[GETTEXTURE]: texture was in the cache");
 | 
			
		||||
               WriteTextureData(request, response, texture, format);
 | 
			
		||||
               return true;
 | 
			
		||||
           }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    string textureUrl = REDIRECT_URL + textureID.ToString();
 | 
			
		||||
                    m_log.Debug("[GETTEXTURE]: Redirecting texture request to " + textureUrl);
 | 
			
		||||
                    httpResponse.RedirectLocation = textureUrl;
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else // no redirect
 | 
			
		||||
            {
 | 
			
		||||
                // try the cache
 | 
			
		||||
                texture = m_assetService.GetCached(fullID);
 | 
			
		||||
 | 
			
		||||
            //response = new Hashtable();
 | 
			
		||||
                if (texture == null)
 | 
			
		||||
                {
 | 
			
		||||
//                    m_log.DebugFormat("[GETTEXTURE]: texture was not in the cache");
 | 
			
		||||
 | 
			
		||||
                    // Fetch locally or remotely. Misses return a 404
 | 
			
		||||
                    texture = m_assetService.Get(textureID.ToString());
 | 
			
		||||
 | 
			
		||||
                    if (texture != null)
 | 
			
		||||
                    {
 | 
			
		||||
                        if (texture.Type != (sbyte)AssetType.Texture)
 | 
			
		||||
                        {
 | 
			
		||||
                            httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
 | 
			
		||||
                            return true;
 | 
			
		||||
                        }
 | 
			
		||||
                        if (format == DefaultFormat)
 | 
			
		||||
                        {
 | 
			
		||||
                            WriteTextureData(httpRequest, httpResponse, texture, format);
 | 
			
		||||
                            return true;
 | 
			
		||||
                        }
 | 
			
		||||
                        else
 | 
			
		||||
                        {
 | 
			
		||||
                            AssetBase newTexture = new AssetBase(texture.ID + "-" + format, texture.Name, (sbyte)AssetType.Texture, texture.Metadata.CreatorID);
 | 
			
		||||
                            newTexture.Data = ConvertTextureData(texture, format);
 | 
			
		||||
                            if (newTexture.Data.Length == 0)
 | 
			
		||||
                                return false; // !!! Caller try another codec, please!
 | 
			
		||||
 | 
			
		||||
                            newTexture.Flags = AssetFlags.Collectable;
 | 
			
		||||
                            newTexture.Temporary = true;
 | 
			
		||||
                            newTexture.Local = true;
 | 
			
		||||
                            m_assetService.Store(newTexture);
 | 
			
		||||
                            WriteTextureData(httpRequest, httpResponse, newTexture, format);
 | 
			
		||||
                            return true;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
               }
 | 
			
		||||
               else // it was on the cache
 | 
			
		||||
               {
 | 
			
		||||
//                   m_log.DebugFormat("[GETTEXTURE]: texture was in the cache");
 | 
			
		||||
                   WriteTextureData(httpRequest, httpResponse, texture, format);
 | 
			
		||||
                   return true;
 | 
			
		||||
               }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            //WriteTextureData(request,response,null,format);
 | 
			
		||||
            // not found
 | 
			
		||||
            //m_log.Warn("[GETTEXTURE]: Texture " + textureID + " not found");
 | 
			
		||||
            return false;
 | 
			
		||||
//            m_log.Warn("[GETTEXTURE]: Texture " + textureID + " not found");
 | 
			
		||||
            httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void WriteTextureData(Hashtable request, Hashtable response, AssetBase texture, string format)
 | 
			
		||||
        private void WriteTextureData(IOSHttpRequest request, IOSHttpResponse response, AssetBase texture, string format)
 | 
			
		||||
        {
 | 
			
		||||
            Hashtable headers = new Hashtable();
 | 
			
		||||
            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"];
 | 
			
		||||
            string range = request.Headers.GetOne("Range");
 | 
			
		||||
 | 
			
		||||
            if (!String.IsNullOrEmpty(range)) // JP2's only
 | 
			
		||||
            {
 | 
			
		||||
                // Range request
 | 
			
		||||
                int start, end;
 | 
			
		||||
                if (Util.TryParseHttpRange(range, out start, out end))
 | 
			
		||||
                if (TryParseRange(range, out start, out end))
 | 
			
		||||
                {
 | 
			
		||||
                    // Before clamping start make sure we can satisfy it in order to avoid
 | 
			
		||||
                    // sending back the last byte instead of an error status
 | 
			
		||||
| 
						 | 
				
			
			@ -232,8 +240,10 @@ namespace OpenSim.Capabilities.Handlers
 | 
			
		|||
                        // However, if we return PartialContent (or OK) instead, the viewer will display that resolution.
 | 
			
		||||
 | 
			
		||||
//                        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;
 | 
			
		||||
//                        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
 | 
			
		||||
                    {
 | 
			
		||||
| 
						 | 
				
			
			@ -248,35 +258,41 @@ namespace OpenSim.Capabilities.Handlers
 | 
			
		|||
 | 
			
		||||
//                        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);
 | 
			
		||||
                        // 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;
 | 
			
		||||
 | 
			
		||||
                        byte[] d = new byte[len];
 | 
			
		||||
                        Array.Copy(texture.Data, start, d, 0, len);
 | 
			
		||||
                        response["bin_response_data"] = d;
 | 
			
		||||
                        response["int_bytes"] = len;
 | 
			
		||||
                        response.ContentLength = len;
 | 
			
		||||
                        response.ContentType = texture.Metadata.ContentType;
 | 
			
		||||
                        response.AddHeader("Content-Range", String.Format("bytes {0}-{1}/{2}", start, end, texture.Data.Length));
 | 
			
		||||
    
 | 
			
		||||
                        response.Body.Write(texture.Data, start, len);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    m_log.Warn("[GETTEXTURE]: Malformed Range header: " + range);
 | 
			
		||||
                    response["int_response_code"] = (int)System.Net.HttpStatusCode.BadRequest;
 | 
			
		||||
                    response.StatusCode = (int)System.Net.HttpStatusCode.BadRequest;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else // JP2's or other formats
 | 
			
		||||
            {
 | 
			
		||||
                // Full content request
 | 
			
		||||
                response["int_response_code"] = (int)System.Net.HttpStatusCode.OK;
 | 
			
		||||
                response.StatusCode = (int)System.Net.HttpStatusCode.OK;
 | 
			
		||||
                response.ContentLength = texture.Data.Length;
 | 
			
		||||
                if (format == DefaultFormat)
 | 
			
		||||
                    response["content_type"] = texture.Metadata.ContentType;
 | 
			
		||||
                    response.ContentType = 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);
 | 
			
		||||
                    response.ContentType = "image/" + format;
 | 
			
		||||
                response.Body.Write(texture.Data, 0, texture.Data.Length);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
//            if (response.StatusCode < 200 || response.StatusCode > 299)
 | 
			
		||||
| 
						 | 
				
			
			@ -289,41 +305,86 @@ namespace OpenSim.Capabilities.Handlers
 | 
			
		|||
//                    texture.FullID, range, response.StatusCode, response.ContentLength, texture.Data.Length);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <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;
 | 
			
		||||
            Bitmap mTexture = new Bitmap(1, 1);
 | 
			
		||||
            ManagedImage managedImage;
 | 
			
		||||
            Image image = (Image)mTexture;
 | 
			
		||||
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                // Taking our jpeg2000 data, decoding it, then saving it to a byte array with regular data
 | 
			
		||||
 | 
			
		||||
                imgstream = new MemoryStream();
 | 
			
		||||
 | 
			
		||||
                // Decode image to System.Drawing.Image
 | 
			
		||||
                if (OpenJPEG.DecodeToImage(texture.Data, out managedImage, out image) && image != null)
 | 
			
		||||
                if (OpenJPEG.DecodeToImage(texture.Data, out managedImage, out image))
 | 
			
		||||
                {
 | 
			
		||||
                    // Save to bitmap
 | 
			
		||||
                    mTexture = new Bitmap(image);
 | 
			
		||||
 | 
			
		||||
                    using(EncoderParameters myEncoderParameters = new EncoderParameters())
 | 
			
		||||
                    {
 | 
			
		||||
                        myEncoderParameters.Param[0] = new EncoderParameter(Encoder.Quality,95L);
 | 
			
		||||
                    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);
 | 
			
		||||
                    // 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);
 | 
			
		||||
                        data = imgstream.ToArray();
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                        m_log.WarnFormat("[GETTEXTURE]: No such codec {0}", format);
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception e)
 | 
			
		||||
| 
						 | 
				
			
			@ -340,10 +401,11 @@ namespace OpenSim.Capabilities.Handlers
 | 
			
		|||
                if (image != null)
 | 
			
		||||
                    image.Dispose();
 | 
			
		||||
 | 
			
		||||
                if(managedImage != null)
 | 
			
		||||
                    managedImage.Clear();
 | 
			
		||||
                if (imgstream != null)
 | 
			
		||||
                {
 | 
			
		||||
                    imgstream.Close();
 | 
			
		||||
                    imgstream.Dispose();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return data;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,394 +0,0 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) Contributors, http://opensimulator.org/
 | 
			
		||||
 * See CONTRIBUTORS.TXT for a full list of copyright holders.
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 *     * Redistributions of source code must retain the above copyright
 | 
			
		||||
 *       notice, this list of conditions and the following disclaimer.
 | 
			
		||||
 *     * Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *       notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *       documentation and/or other materials provided with the distribution.
 | 
			
		||||
 *     * Neither the name of the OpenSimulator Project nor the
 | 
			
		||||
 *       names of its contributors may be used to endorse or promote products
 | 
			
		||||
 *       derived from this software without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
 | 
			
		||||
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 | 
			
		||||
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 | 
			
		||||
 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
 | 
			
		||||
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 | 
			
		||||
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 | 
			
		||||
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 | 
			
		||||
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
			
		||||
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 | 
			
		||||
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections;
 | 
			
		||||
using System.Collections.Specialized;
 | 
			
		||||
using System.Drawing;
 | 
			
		||||
using System.Drawing.Imaging;
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Net;
 | 
			
		||||
using System.Web;
 | 
			
		||||
using log4net;
 | 
			
		||||
using Nini.Config;
 | 
			
		||||
using OpenMetaverse;
 | 
			
		||||
using OpenMetaverse.StructuredData;
 | 
			
		||||
using OpenMetaverse.Imaging;
 | 
			
		||||
using OpenSim.Framework;
 | 
			
		||||
using OpenSim.Framework.Servers;
 | 
			
		||||
using OpenSim.Framework.Servers.HttpServer;
 | 
			
		||||
using OpenSim.Region.Framework.Interfaces;
 | 
			
		||||
using OpenSim.Services.Interfaces;
 | 
			
		||||
using Caps = OpenSim.Framework.Capabilities.Caps;
 | 
			
		||||
 | 
			
		||||
namespace OpenSim.Capabilities.Handlers
 | 
			
		||||
{
 | 
			
		||||
    public class GetTextureRobustHandler : BaseStreamHandler
 | 
			
		||||
    {
 | 
			
		||||
        private static readonly ILog m_log =
 | 
			
		||||
            LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 | 
			
		||||
        private IAssetService m_assetService;
 | 
			
		||||
 | 
			
		||||
        public const string DefaultFormat = "x-j2c";
 | 
			
		||||
 | 
			
		||||
        // TODO: Change this to a config option
 | 
			
		||||
        private string m_RedirectURL = null;
 | 
			
		||||
 | 
			
		||||
        public GetTextureRobustHandler(string path, IAssetService assService, string name, string description, string redirectURL)
 | 
			
		||||
            : base("GET", path, name, description)
 | 
			
		||||
        {
 | 
			
		||||
            m_assetService = assService;
 | 
			
		||||
            m_RedirectURL = redirectURL;
 | 
			
		||||
            if (m_RedirectURL != null && !m_RedirectURL.EndsWith("/"))
 | 
			
		||||
                m_RedirectURL += "/";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
 | 
			
		||||
        {
 | 
			
		||||
            // Try to parse the texture ID from the request URL
 | 
			
		||||
            NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query);
 | 
			
		||||
            string textureStr = query.GetOne("texture_id");
 | 
			
		||||
            string format = query.GetOne("format");
 | 
			
		||||
 | 
			
		||||
            //m_log.DebugFormat("[GETTEXTURE]: called {0}", textureStr);
 | 
			
		||||
 | 
			
		||||
            if (m_assetService == null)
 | 
			
		||||
            {
 | 
			
		||||
                m_log.Error("[GETTEXTURE]: Cannot fetch texture " + textureStr + " without an asset service");
 | 
			
		||||
                httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
 | 
			
		||||
                return null;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            UUID textureID;
 | 
			
		||||
            if (!String.IsNullOrEmpty(textureStr) && UUID.TryParse(textureStr, out textureID))
 | 
			
		||||
            {
 | 
			
		||||
//                m_log.DebugFormat("[GETTEXTURE]: Received request for texture id {0}", textureID);
 | 
			
		||||
 | 
			
		||||
                string[] formats;
 | 
			
		||||
                if (!string.IsNullOrEmpty(format))
 | 
			
		||||
                {
 | 
			
		||||
                    formats = new string[1] { format.ToLower() };
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    formats = WebUtil.GetPreferredImageTypes(httpRequest.Headers.Get("Accept"));
 | 
			
		||||
                    if (formats.Length == 0)
 | 
			
		||||
                        formats = new string[1] { DefaultFormat }; // default
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
                // OK, we have an array with preferred formats, possibly with only one entry
 | 
			
		||||
 | 
			
		||||
                httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
 | 
			
		||||
                foreach (string f in formats)
 | 
			
		||||
                {
 | 
			
		||||
                    if (FetchTexture(httpRequest, httpResponse, textureID, f))
 | 
			
		||||
                        break;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                m_log.Warn("[GETTEXTURE]: Failed to parse a texture_id from GetTexture request: " + httpRequest.Url);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
//            m_log.DebugFormat(
 | 
			
		||||
//                "[GETTEXTURE]: For texture {0} sending back response {1}, data length {2}",
 | 
			
		||||
//                textureID, httpResponse.StatusCode, httpResponse.ContentLength);
 | 
			
		||||
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        ///
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="httpRequest"></param>
 | 
			
		||||
        /// <param name="httpResponse"></param>
 | 
			
		||||
        /// <param name="textureID"></param>
 | 
			
		||||
        /// <param name="format"></param>
 | 
			
		||||
        /// <returns>False for "caller try another codec"; true otherwise</returns>
 | 
			
		||||
        private bool FetchTexture(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, UUID textureID, string format)
 | 
			
		||||
        {
 | 
			
		||||
            // m_log.DebugFormat("[GETTEXTURE]: {0} with requested format {1}", textureID, format);
 | 
			
		||||
            if(!String.IsNullOrEmpty(m_RedirectURL))
 | 
			
		||||
            {
 | 
			
		||||
                string textureUrl = m_RedirectURL + "?texture_id=" + textureID.ToString();
 | 
			
		||||
                m_log.Debug("[GETTEXTURE]: Redirecting texture request to " + textureUrl);
 | 
			
		||||
                httpResponse.StatusCode = (int)HttpStatusCode.Moved;
 | 
			
		||||
                httpResponse.AddHeader("Location:", textureUrl);
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Fetch,  Misses or invalid return a 404
 | 
			
		||||
            AssetBase texture = m_assetService.Get(textureID.ToString());
 | 
			
		||||
            if (texture != null)
 | 
			
		||||
            {
 | 
			
		||||
                if (texture.Type != (sbyte)AssetType.Texture)
 | 
			
		||||
                {
 | 
			
		||||
                    httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
                if (format == DefaultFormat)
 | 
			
		||||
                {
 | 
			
		||||
                    WriteTextureData(httpRequest, httpResponse, texture, format);
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // need to convert format
 | 
			
		||||
                AssetBase newTexture = new AssetBase(texture.ID + "-" + format, texture.Name, (sbyte)AssetType.Texture, texture.Metadata.CreatorID);
 | 
			
		||||
                newTexture.Data = ConvertTextureData(texture, format);
 | 
			
		||||
                if (newTexture.Data.Length == 0)
 | 
			
		||||
                    return false; // !!! Caller try another codec, please!
 | 
			
		||||
 | 
			
		||||
                newTexture.Flags = AssetFlags.Collectable;
 | 
			
		||||
                newTexture.Temporary = true;
 | 
			
		||||
                newTexture.Local = true;
 | 
			
		||||
                WriteTextureData(httpRequest, httpResponse, newTexture, format);
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // not found
 | 
			
		||||
            // m_log.Warn("[GETTEXTURE]: Texture " + textureID + " not found");
 | 
			
		||||
            httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void WriteTextureData(IOSHttpRequest request, IOSHttpResponse response, AssetBase texture, string format)
 | 
			
		||||
        {
 | 
			
		||||
            string range = request.Headers.GetOne("Range");
 | 
			
		||||
 | 
			
		||||
            if (!String.IsNullOrEmpty(range)) // JP2's only
 | 
			
		||||
            {
 | 
			
		||||
                // Range request
 | 
			
		||||
                int start, end;
 | 
			
		||||
                if (TryParseRange(range, out start, out end))
 | 
			
		||||
                {
 | 
			
		||||
                    // Before clamping start make sure we can satisfy it in order to avoid
 | 
			
		||||
                    // sending back the last byte instead of an error status
 | 
			
		||||
                    if (start >= texture.Data.Length)
 | 
			
		||||
                    {
 | 
			
		||||
//                        m_log.DebugFormat(
 | 
			
		||||
//                            "[GETTEXTURE]: Client requested range for texture {0} starting at {1} but texture has end of {2}",
 | 
			
		||||
//                            texture.ID, start, texture.Data.Length);
 | 
			
		||||
 | 
			
		||||
                        // Stricly speaking, as per http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html, we should be sending back
 | 
			
		||||
                        // Requested Range Not Satisfiable (416) here.  However, it appears that at least recent implementations
 | 
			
		||||
                        // of the Linden Lab viewer (3.2.1 and 3.3.4 and probably earlier), a viewer that has previously
 | 
			
		||||
                        // received a very small texture  may attempt to fetch bytes from the server past the
 | 
			
		||||
                        // range of data that it received originally.  Whether this happens appears to depend on whether
 | 
			
		||||
                        // the viewer's estimation of how large a request it needs to make for certain discard levels
 | 
			
		||||
                        // (http://wiki.secondlife.com/wiki/Image_System#Discard_Level_and_Mip_Mapping), chiefly discard
 | 
			
		||||
                        // level 2.  If this estimate is greater than the total texture size, returning a RequestedRangeNotSatisfiable
 | 
			
		||||
                        // here will cause the viewer to treat the texture as bad and never display the full resolution
 | 
			
		||||
                        // However, if we return PartialContent (or OK) instead, the viewer will display that resolution.
 | 
			
		||||
 | 
			
		||||
//                        response.StatusCode = (int)System.Net.HttpStatusCode.RequestedRangeNotSatisfiable;
 | 
			
		||||
//                        response.AddHeader("Content-Range", String.Format("bytes */{0}", texture.Data.Length));
 | 
			
		||||
//                        response.StatusCode = (int)System.Net.HttpStatusCode.OK;
 | 
			
		||||
                        response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent;
 | 
			
		||||
                        response.ContentType = texture.Metadata.ContentType;
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        // Handle the case where no second range value was given.  This is equivalent to requesting
 | 
			
		||||
                        // the rest of the entity.
 | 
			
		||||
                        if (end == -1)
 | 
			
		||||
                            end = int.MaxValue;
 | 
			
		||||
 | 
			
		||||
                        end = Utils.Clamp(end, 0, texture.Data.Length - 1);
 | 
			
		||||
                        start = Utils.Clamp(start, 0, end);
 | 
			
		||||
                        int len = end - start + 1;
 | 
			
		||||
 | 
			
		||||
//                        m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID);
 | 
			
		||||
 | 
			
		||||
                        // Always return PartialContent, even if the range covered the entire data length
 | 
			
		||||
                        // We were accidentally sending back 404 before in this situation
 | 
			
		||||
                        // https://issues.apache.org/bugzilla/show_bug.cgi?id=51878 supports sending 206 even if the
 | 
			
		||||
                        // entire range is requested, and viewer 3.2.2 (and very probably earlier) seems fine with this.
 | 
			
		||||
                        //
 | 
			
		||||
                        // We also do not want to send back OK even if the whole range was satisfiable since this causes
 | 
			
		||||
                        // HTTP textures on at least Imprudence 1.4.0-beta2 to never display the final texture quality.
 | 
			
		||||
//                        if (end > maxEnd)
 | 
			
		||||
//                            response.StatusCode = (int)System.Net.HttpStatusCode.OK;
 | 
			
		||||
//                        else
 | 
			
		||||
                        response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent;
 | 
			
		||||
 | 
			
		||||
                        response.ContentLength = len;
 | 
			
		||||
                        response.ContentType = texture.Metadata.ContentType;
 | 
			
		||||
                        response.AddHeader("Content-Range", String.Format("bytes {0}-{1}/{2}", start, end, texture.Data.Length));
 | 
			
		||||
                        response.RawBuffer = texture.Data;
 | 
			
		||||
                        response.RawBufferStart = start;
 | 
			
		||||
                        response.RawBufferLen = len;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    m_log.Warn("[GETTEXTURE]: Malformed Range header: " + range);
 | 
			
		||||
                    response.StatusCode = (int)System.Net.HttpStatusCode.BadRequest;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else // JP2's or other formats
 | 
			
		||||
            {
 | 
			
		||||
                // Full content request
 | 
			
		||||
                response.StatusCode = (int)System.Net.HttpStatusCode.OK;
 | 
			
		||||
                response.ContentLength = texture.Data.Length;
 | 
			
		||||
                if (format == DefaultFormat)
 | 
			
		||||
                    response.ContentType = texture.Metadata.ContentType;
 | 
			
		||||
                else
 | 
			
		||||
                    response.ContentType = "image/" + format;
 | 
			
		||||
                response.RawBuffer = texture.Data;
 | 
			
		||||
                response.RawBufferStart = 0;
 | 
			
		||||
                response.RawBufferLen = texture.Data.Length;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            //            if (response.StatusCode < 200 || response.StatusCode > 299)
 | 
			
		||||
            //                m_log.WarnFormat(
 | 
			
		||||
            //                    "[GETTEXTURE]: For texture {0} requested range {1} responded {2} with content length {3} (actual {4})",
 | 
			
		||||
            //                    texture.FullID, range, response.StatusCode, response.ContentLength, texture.Data.Length);
 | 
			
		||||
            //            else
 | 
			
		||||
            //                m_log.DebugFormat(
 | 
			
		||||
            //                    "[GETTEXTURE]: For texture {0} requested range {1} responded {2} with content length {3} (actual {4})",
 | 
			
		||||
            //                    texture.FullID, range, response.StatusCode, response.ContentLength, texture.Data.Length);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Parse a range header.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <remarks>
 | 
			
		||||
        /// As per http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html,
 | 
			
		||||
        /// this obeys range headers with two values (e.g. 533-4165) and no second value (e.g. 533-).
 | 
			
		||||
        /// Where there is no value, -1 is returned.
 | 
			
		||||
        /// FIXME: Need to cover the case where only a second value is specified (e.g. -4165), probably by returning -1
 | 
			
		||||
        /// for start.</remarks>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        /// <param name='header'></param>
 | 
			
		||||
        /// <param name='start'>Start of the range.  Undefined if this was not a number.</param>
 | 
			
		||||
        /// <param name='end'>End of the range.  Will be -1 if no end specified.  Undefined if there was a raw string but this was not a number.</param>
 | 
			
		||||
        private bool TryParseRange(string header, out int start, out int end)
 | 
			
		||||
        {
 | 
			
		||||
            start = end = 0;
 | 
			
		||||
 | 
			
		||||
            if (header.StartsWith("bytes="))
 | 
			
		||||
            {
 | 
			
		||||
                string[] rangeValues = header.Substring(6).Split('-');
 | 
			
		||||
 | 
			
		||||
                if (rangeValues.Length == 2)
 | 
			
		||||
                {
 | 
			
		||||
                    if (!Int32.TryParse(rangeValues[0], out start))
 | 
			
		||||
                        return false;
 | 
			
		||||
 | 
			
		||||
                    string rawEnd = rangeValues[1];
 | 
			
		||||
 | 
			
		||||
                    if (rawEnd == "")
 | 
			
		||||
                    {
 | 
			
		||||
                        end = -1;
 | 
			
		||||
                        return true;
 | 
			
		||||
                    }
 | 
			
		||||
                    else if (Int32.TryParse(rawEnd, out end))
 | 
			
		||||
                    {
 | 
			
		||||
                        return true;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            start = end = 0;
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private byte[] ConvertTextureData(AssetBase texture, string format)
 | 
			
		||||
        {
 | 
			
		||||
            m_log.DebugFormat("[GETTEXTURE]: Converting texture {0} to {1}", texture.ID, format);
 | 
			
		||||
            byte[] data = new byte[0];
 | 
			
		||||
 | 
			
		||||
            MemoryStream imgstream = new MemoryStream();
 | 
			
		||||
            Bitmap mTexture = null;
 | 
			
		||||
            ManagedImage managedImage = null;
 | 
			
		||||
            Image image = null;
 | 
			
		||||
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                // Taking our jpeg2000 data, decoding it, then saving it to a byte array with regular data
 | 
			
		||||
                // Decode image to System.Drawing.Image
 | 
			
		||||
                if (OpenJPEG.DecodeToImage(texture.Data, out managedImage, out image) && image != null)
 | 
			
		||||
                {
 | 
			
		||||
                    // Save to bitmap
 | 
			
		||||
                    mTexture = new Bitmap(image);
 | 
			
		||||
 | 
			
		||||
                    using(EncoderParameters myEncoderParameters = new EncoderParameters())
 | 
			
		||||
                    {
 | 
			
		||||
                        myEncoderParameters.Param[0] = new EncoderParameter(Encoder.Quality,95L);
 | 
			
		||||
 | 
			
		||||
                        // Save bitmap to stream
 | 
			
		||||
                        ImageCodecInfo codec = GetEncoderInfo("image/" + format);
 | 
			
		||||
                        if (codec != null)
 | 
			
		||||
                        {
 | 
			
		||||
                            mTexture.Save(imgstream, codec, myEncoderParameters);
 | 
			
		||||
                            // Write the stream to a byte array for output
 | 
			
		||||
                            data = imgstream.ToArray();
 | 
			
		||||
                        }
 | 
			
		||||
                        else
 | 
			
		||||
                            m_log.WarnFormat("[GETTEXTURE]: No such codec {0}", format);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception e)
 | 
			
		||||
            {
 | 
			
		||||
                m_log.WarnFormat("[GETTEXTURE]: Unable to convert texture {0} to {1}: {2}", texture.ID, format, e.Message);
 | 
			
		||||
            }
 | 
			
		||||
            finally
 | 
			
		||||
            {
 | 
			
		||||
                // Reclaim memory, these are unmanaged resources
 | 
			
		||||
                // If we encountered an exception, one or more of these will be null
 | 
			
		||||
                if (mTexture != null)
 | 
			
		||||
                    mTexture.Dispose();
 | 
			
		||||
 | 
			
		||||
                if (image != null)
 | 
			
		||||
                    image.Dispose();
 | 
			
		||||
 | 
			
		||||
                if(managedImage != null)
 | 
			
		||||
                    managedImage.Clear();
 | 
			
		||||
 | 
			
		||||
                if (imgstream != null)
 | 
			
		||||
                    imgstream.Dispose();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return data;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // From msdn
 | 
			
		||||
        private static ImageCodecInfo GetEncoderInfo(String mimeType)
 | 
			
		||||
        {
 | 
			
		||||
            ImageCodecInfo[] encoders;
 | 
			
		||||
            encoders = ImageCodecInfo.GetImageEncoders();
 | 
			
		||||
            for (int j = 0; j < encoders.Length; ++j)
 | 
			
		||||
            {
 | 
			
		||||
                if (encoders[j].MimeType == mimeType)
 | 
			
		||||
                    return encoders[j];
 | 
			
		||||
            }
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -33,7 +33,6 @@ using OpenSim.Framework.Servers.HttpServer;
 | 
			
		|||
using OpenSim.Server.Handlers.Base;
 | 
			
		||||
using OpenMetaverse;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
namespace OpenSim.Capabilities.Handlers
 | 
			
		||||
{
 | 
			
		||||
    public class GetTextureServerConnector : ServiceConnector
 | 
			
		||||
| 
						 | 
				
			
			@ -63,11 +62,8 @@ namespace OpenSim.Capabilities.Handlers
 | 
			
		|||
            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));
 | 
			
		||||
                new GetTextureHandler("/CAPS/GetTexture/" /*+ UUID.Random() */, m_AssetService, "GetTexture", null));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -37,8 +37,8 @@ using OpenSim.Framework;
 | 
			
		|||
using OpenSim.Framework.Servers.HttpServer;
 | 
			
		||||
using OpenSim.Region.Framework.Scenes;
 | 
			
		||||
using OpenSim.Tests.Common;
 | 
			
		||||
using OpenSim.Tests.Common.Mock;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
namespace OpenSim.Capabilities.Handlers.GetTexture.Tests
 | 
			
		||||
{
 | 
			
		||||
    [TestFixture]
 | 
			
		||||
| 
						 | 
				
			
			@ -52,7 +52,7 @@ namespace OpenSim.Capabilities.Handlers.GetTexture.Tests
 | 
			
		|||
            // 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);
 | 
			
		||||
            GetTextureHandler handler = new GetTextureHandler(null, scene.AssetService, "TestGetTexture", null);
 | 
			
		||||
            TestOSHttpRequest req = new TestOSHttpRequest();
 | 
			
		||||
            TestOSHttpResponse resp = new TestOSHttpResponse();
 | 
			
		||||
            req.Url = new Uri("http://localhost/?texture_id=00000000-0000-1111-9999-000000000012");
 | 
			
		||||
| 
						 | 
				
			
			@ -61,4 +61,3 @@ namespace OpenSim.Capabilities.Handlers.GetTexture.Tests
 | 
			
		|||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
*/
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
 | 
			
		|||
//      Build Number
 | 
			
		||||
//      Revision
 | 
			
		||||
//
 | 
			
		||||
[assembly: AssemblyVersion(OpenSim.VersionInfo.AssemblyVersionNumber)]
 | 
			
		||||
[assembly: AssemblyVersion("0.8.0.*")]
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,181 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) Contributors, http://opensimulator.org/
 | 
			
		||||
 * See CONTRIBUTORS.TXT for a full list of copyright holders.
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 *     * Redistributions of source code must retain the above copyright
 | 
			
		||||
 *       notice, this list of conditions and the following disclaimer.
 | 
			
		||||
 *     * Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *       notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *       documentation and/or other materials provided with the distribution.
 | 
			
		||||
 *     * Neither the name of the OpenSimulator Project nor the
 | 
			
		||||
 *       names of its contributors may be used to endorse or promote products
 | 
			
		||||
 *       derived from this software without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
 | 
			
		||||
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 | 
			
		||||
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 | 
			
		||||
 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
 | 
			
		||||
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 | 
			
		||||
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 | 
			
		||||
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 | 
			
		||||
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
			
		||||
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 | 
			
		||||
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections;
 | 
			
		||||
using System.Collections.Specialized;
 | 
			
		||||
using System.Drawing;
 | 
			
		||||
using System.Drawing.Imaging;
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Web;
 | 
			
		||||
using log4net;
 | 
			
		||||
using Nini.Config;
 | 
			
		||||
using OpenMetaverse;
 | 
			
		||||
using OpenMetaverse.StructuredData;
 | 
			
		||||
using OpenMetaverse.Imaging;
 | 
			
		||||
using OpenSim.Framework;
 | 
			
		||||
using OpenSim.Framework.Capabilities;
 | 
			
		||||
using OpenSim.Framework.Servers;
 | 
			
		||||
using OpenSim.Framework.Servers.HttpServer;
 | 
			
		||||
using OpenSim.Region.Framework.Interfaces;
 | 
			
		||||
using OpenSim.Services.Interfaces;
 | 
			
		||||
using Caps = OpenSim.Framework.Capabilities.Caps;
 | 
			
		||||
 | 
			
		||||
namespace OpenSim.Capabilities.Handlers
 | 
			
		||||
{
 | 
			
		||||
    public class UploadBakedTextureHandler
 | 
			
		||||
    {
 | 
			
		||||
        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 | 
			
		||||
 | 
			
		||||
        private Caps m_HostCapsObj;
 | 
			
		||||
        private IAssetService m_assetService;
 | 
			
		||||
        private bool m_persistBakedTextures;
 | 
			
		||||
 | 
			
		||||
        public UploadBakedTextureHandler(Caps caps, IAssetService assetService, bool persistBakedTextures)
 | 
			
		||||
        {
 | 
			
		||||
            m_HostCapsObj = caps;
 | 
			
		||||
            m_assetService = assetService;
 | 
			
		||||
            m_persistBakedTextures = persistBakedTextures;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Handle a request from the client for a Uri to upload a baked texture.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="request"></param>
 | 
			
		||||
        /// <param name="path"></param>
 | 
			
		||||
        /// <param name="param"></param>
 | 
			
		||||
        /// <param name="httpRequest"></param>
 | 
			
		||||
        /// <param name="httpResponse"></param>
 | 
			
		||||
        /// <returns>The upload response if the request is successful, null otherwise.</returns>
 | 
			
		||||
        public string UploadBakedTexture(
 | 
			
		||||
            string request, string path, string param, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
 | 
			
		||||
        {
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                string capsBase = "/CAPS/" + m_HostCapsObj.CapsObjectPath;
 | 
			
		||||
                string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000");
 | 
			
		||||
 | 
			
		||||
                BakedTextureUploader uploader =
 | 
			
		||||
                    new BakedTextureUploader(capsBase + uploaderPath, m_HostCapsObj.HttpListener);
 | 
			
		||||
                uploader.OnUpLoad += BakedTextureUploaded;
 | 
			
		||||
 | 
			
		||||
                m_HostCapsObj.HttpListener.AddStreamHandler(
 | 
			
		||||
                    new BinaryStreamHandler(
 | 
			
		||||
                        "POST", capsBase + uploaderPath, uploader.uploaderCaps, "UploadBakedTexture", null));
 | 
			
		||||
 | 
			
		||||
                string protocol = "http://";
 | 
			
		||||
 | 
			
		||||
                if (m_HostCapsObj.SSLCaps)
 | 
			
		||||
                    protocol = "https://";
 | 
			
		||||
 | 
			
		||||
                string uploaderURL = protocol + m_HostCapsObj.HostName + ":" +
 | 
			
		||||
                        m_HostCapsObj.Port.ToString() + capsBase + uploaderPath;
 | 
			
		||||
 | 
			
		||||
                LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse();
 | 
			
		||||
                uploadResponse.uploader = uploaderURL;
 | 
			
		||||
                uploadResponse.state = "upload";
 | 
			
		||||
 | 
			
		||||
                return LLSDHelpers.SerialiseLLSDReply(uploadResponse);
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception e)
 | 
			
		||||
            {
 | 
			
		||||
                m_log.ErrorFormat("[UPLOAD BAKED TEXTURE HANDLER]: {0}{1}", e.Message, e.StackTrace);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Called when a baked texture has been successfully uploaded by a client.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="assetID"></param>
 | 
			
		||||
        /// <param name="data"></param>
 | 
			
		||||
        private void BakedTextureUploaded(UUID assetID, byte[] data)
 | 
			
		||||
        {
 | 
			
		||||
//            m_log.DebugFormat("[UPLOAD BAKED TEXTURE HANDLER]: Received baked texture {0}", assetID.ToString());
 | 
			
		||||
 | 
			
		||||
            AssetBase asset;
 | 
			
		||||
            asset = new AssetBase(assetID, "Baked Texture", (sbyte)AssetType.Texture, m_HostCapsObj.AgentID.ToString());
 | 
			
		||||
            asset.Data = data;
 | 
			
		||||
            asset.Temporary = true;
 | 
			
		||||
            asset.Local = !m_persistBakedTextures; // Local assets aren't persisted, non-local are
 | 
			
		||||
            m_assetService.Store(asset);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    class BakedTextureUploader
 | 
			
		||||
    {
 | 
			
		||||
//        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 | 
			
		||||
 | 
			
		||||
        public event Action<UUID, byte[]> OnUpLoad;
 | 
			
		||||
 | 
			
		||||
        private string uploaderPath = String.Empty;
 | 
			
		||||
        private UUID newAssetID;
 | 
			
		||||
        private IHttpServer httpListener;
 | 
			
		||||
 | 
			
		||||
        public BakedTextureUploader(string path, IHttpServer httpServer)
 | 
			
		||||
        {
 | 
			
		||||
            newAssetID = UUID.Random();
 | 
			
		||||
            uploaderPath = path;
 | 
			
		||||
            httpListener = httpServer;
 | 
			
		||||
            //                m_log.InfoFormat("[CAPS] baked texture upload starting for {0}",newAssetID);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Handle raw uploaded baked texture data.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="data"></param>
 | 
			
		||||
        /// <param name="path"></param>
 | 
			
		||||
        /// <param name="param"></param>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        public string uploaderCaps(byte[] data, string path, string param)
 | 
			
		||||
        {
 | 
			
		||||
            Action<UUID, byte[]> handlerUpLoad = OnUpLoad;
 | 
			
		||||
 | 
			
		||||
            // Don't do this asynchronously, otherwise it's possible for the client to send set appearance information
 | 
			
		||||
            // on another thread which might send out avatar updates before the asset has been put into the asset
 | 
			
		||||
            // service.
 | 
			
		||||
            if (handlerUpLoad != null)
 | 
			
		||||
                handlerUpLoad(newAssetID, data);
 | 
			
		||||
 | 
			
		||||
            string res = String.Empty;
 | 
			
		||||
            LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete();
 | 
			
		||||
            uploadComplete.new_asset = newAssetID.ToString();
 | 
			
		||||
            uploadComplete.new_inventory_item = UUID.Zero;
 | 
			
		||||
            uploadComplete.state = "complete";
 | 
			
		||||
 | 
			
		||||
            res = LLSDHelpers.SerialiseLLSDReply(uploadComplete);
 | 
			
		||||
 | 
			
		||||
            httpListener.RemoveStreamHandler("POST", uploaderPath);
 | 
			
		||||
 | 
			
		||||
//            m_log.DebugFormat("[BAKED TEXTURE UPLOADER]: baked texture upload completed for {0}", newAssetID);
 | 
			
		||||
 | 
			
		||||
            return res;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -29,18 +29,18 @@ using System;
 | 
			
		|||
using Nini.Config;
 | 
			
		||||
using OpenSim.Server.Base;
 | 
			
		||||
using OpenSim.Services.Interfaces;
 | 
			
		||||
using OpenSim.Framework.ServiceAuth;
 | 
			
		||||
using OpenSim.Framework.Servers.HttpServer;
 | 
			
		||||
using OpenSim.Server.Handlers.Base;
 | 
			
		||||
using OpenMetaverse;
 | 
			
		||||
 | 
			
		||||
namespace OpenSim.Server.Handlers.BakedTextures
 | 
			
		||||
namespace OpenSim.Capabilities.Handlers
 | 
			
		||||
{
 | 
			
		||||
    public class XBakesConnector : ServiceConnector
 | 
			
		||||
    public class UploadBakedTextureServerConnector : ServiceConnector
 | 
			
		||||
    {
 | 
			
		||||
        private IBakedTextureService m_BakesService;
 | 
			
		||||
        private string m_ConfigName = "BakedTextureService";
 | 
			
		||||
        private IAssetService m_AssetService;
 | 
			
		||||
        private string m_ConfigName = "CapsService";
 | 
			
		||||
 | 
			
		||||
        public XBakesConnector(IConfigSource config, IHttpServer server, string configName) :
 | 
			
		||||
        public UploadBakedTextureServerConnector(IConfigSource config, IHttpServer server, string configName) :
 | 
			
		||||
                base(config, server, configName)
 | 
			
		||||
        {
 | 
			
		||||
            if (configName != String.Empty)
 | 
			
		||||
| 
						 | 
				
			
			@ -50,20 +50,27 @@ namespace OpenSim.Server.Handlers.BakedTextures
 | 
			
		|||
            if (serverConfig == null)
 | 
			
		||||
                throw new Exception(String.Format("No section '{0}' in config file", m_ConfigName));
 | 
			
		||||
 | 
			
		||||
            string assetService = serverConfig.GetString("LocalServiceModule",
 | 
			
		||||
                    String.Empty);
 | 
			
		||||
            string assetService = serverConfig.GetString("AssetService", String.Empty);
 | 
			
		||||
 | 
			
		||||
            if (assetService == String.Empty)
 | 
			
		||||
                throw new Exception("No BakedTextureService in config file");
 | 
			
		||||
                throw new Exception("No AssetService in config file");
 | 
			
		||||
 | 
			
		||||
            Object[] args = new Object[] { config };
 | 
			
		||||
            m_BakesService =
 | 
			
		||||
                    ServerUtils.LoadPlugin<IBakedTextureService>(assetService, args);
 | 
			
		||||
            m_AssetService =
 | 
			
		||||
                    ServerUtils.LoadPlugin<IAssetService>(assetService, args);
 | 
			
		||||
 | 
			
		||||
            IServiceAuth auth = ServiceAuth.Create(config, m_ConfigName);
 | 
			
		||||
            if (m_AssetService == null)
 | 
			
		||||
                throw new Exception(String.Format("Failed to load AssetService from {0}; config is {1}", assetService, m_ConfigName));
 | 
			
		||||
 | 
			
		||||
            server.AddStreamHandler(new BakesServerGetHandler(m_BakesService, auth));
 | 
			
		||||
            server.AddStreamHandler(new BakesServerPostHandler(m_BakesService, auth));
 | 
			
		||||
        }
 | 
			
		||||
            // NEED TO FIX THIS
 | 
			
		||||
            OpenSim.Framework.Capabilities.Caps caps = new OpenSim.Framework.Capabilities.Caps(server, "", server.Port, "", UUID.Zero, "");
 | 
			
		||||
            server.AddStreamHandler(new RestStreamHandler(
 | 
			
		||||
                        "POST",
 | 
			
		||||
                        "/CAPS/UploadBakedTexture/",
 | 
			
		||||
                        new UploadBakedTextureHandler(caps, m_AssetService, true).UploadBakedTexture,
 | 
			
		||||
                        "UploadBakedTexture",
 | 
			
		||||
                        "Upload Baked Texture Capability"));
 | 
			
		||||
 | 
			
		||||
         }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,438 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) Contributors, http://opensimulator.org/
 | 
			
		||||
 * See CONTRIBUTORS.TXT for a full list of copyright holders.
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 *     * Redistributions of source code must retain the above copyright
 | 
			
		||||
 *       notice, this list of conditions and the following disclaimer.
 | 
			
		||||
 *     * Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *       notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *       documentation and/or other materials provided with the distribution.
 | 
			
		||||
 *     * Neither the name of the OpenSimulator Project nor the
 | 
			
		||||
 *       names of its contributors may be used to endorse or promote products
 | 
			
		||||
 *       derived from this software without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
 | 
			
		||||
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 | 
			
		||||
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 | 
			
		||||
 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
 | 
			
		||||
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 | 
			
		||||
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 | 
			
		||||
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 | 
			
		||||
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
			
		||||
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 | 
			
		||||
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
using log4net;
 | 
			
		||||
using Nini.Config;
 | 
			
		||||
using OpenMetaverse;
 | 
			
		||||
using OpenMetaverse.StructuredData;
 | 
			
		||||
using OpenSim.Framework;
 | 
			
		||||
using OpenSim.Framework.Capabilities;
 | 
			
		||||
using OpenSim.Region.Framework.Interfaces;
 | 
			
		||||
using OpenSim.Framework.Servers.HttpServer;
 | 
			
		||||
using OpenSim.Services.Interfaces;
 | 
			
		||||
using Caps = OpenSim.Framework.Capabilities.Caps;
 | 
			
		||||
 | 
			
		||||
namespace OpenSim.Capabilities.Handlers
 | 
			
		||||
{
 | 
			
		||||
    public class WebFetchInvDescHandler 
 | 
			
		||||
    {
 | 
			
		||||
        private static readonly ILog m_log =
 | 
			
		||||
            LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 | 
			
		||||
 | 
			
		||||
        private IInventoryService m_InventoryService;
 | 
			
		||||
        private ILibraryService m_LibraryService;
 | 
			
		||||
//        private object m_fetchLock = new Object();
 | 
			
		||||
 | 
			
		||||
        public WebFetchInvDescHandler(IInventoryService invService, ILibraryService libService) 
 | 
			
		||||
        {
 | 
			
		||||
            m_InventoryService = invService;
 | 
			
		||||
            m_LibraryService = libService;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public string FetchInventoryDescendentsRequest(string request, string path, string param, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
 | 
			
		||||
        {
 | 
			
		||||
//            lock (m_fetchLock)
 | 
			
		||||
//            {
 | 
			
		||||
//                m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Received request {0}", request);
 | 
			
		||||
    
 | 
			
		||||
                // nasty temporary hack here, the linden client falsely
 | 
			
		||||
                // identifies the uuid 00000000-0000-0000-0000-000000000000
 | 
			
		||||
                // as a string which breaks us
 | 
			
		||||
                //
 | 
			
		||||
                // correctly mark it as a uuid
 | 
			
		||||
                //
 | 
			
		||||
                request = request.Replace("<string>00000000-0000-0000-0000-000000000000</string>", "<uuid>00000000-0000-0000-0000-000000000000</uuid>");
 | 
			
		||||
    
 | 
			
		||||
                // another hack <integer>1</integer> results in a
 | 
			
		||||
                // System.ArgumentException: Object type System.Int32 cannot
 | 
			
		||||
                // be converted to target type: System.Boolean
 | 
			
		||||
                //
 | 
			
		||||
                request = request.Replace("<key>fetch_folders</key><integer>0</integer>", "<key>fetch_folders</key><boolean>0</boolean>");
 | 
			
		||||
                request = request.Replace("<key>fetch_folders</key><integer>1</integer>", "<key>fetch_folders</key><boolean>1</boolean>");
 | 
			
		||||
    
 | 
			
		||||
                Hashtable hash = new Hashtable();
 | 
			
		||||
                try
 | 
			
		||||
                {
 | 
			
		||||
                    hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request));
 | 
			
		||||
                }
 | 
			
		||||
                catch (LLSD.LLSDParseException e)
 | 
			
		||||
                {
 | 
			
		||||
                    m_log.ErrorFormat("[WEB FETCH INV DESC HANDLER]: Fetch error: {0}{1}" + e.Message, e.StackTrace);
 | 
			
		||||
                    m_log.Error("Request: " + request);
 | 
			
		||||
                }
 | 
			
		||||
    
 | 
			
		||||
                ArrayList foldersrequested = (ArrayList)hash["folders"];
 | 
			
		||||
    
 | 
			
		||||
                string response = "";
 | 
			
		||||
 | 
			
		||||
                for (int i = 0; i < foldersrequested.Count; i++)
 | 
			
		||||
                {
 | 
			
		||||
                    string inventoryitemstr = "";
 | 
			
		||||
                    Hashtable inventoryhash = (Hashtable)foldersrequested[i];
 | 
			
		||||
 | 
			
		||||
                    LLSDFetchInventoryDescendents llsdRequest = new LLSDFetchInventoryDescendents();
 | 
			
		||||
 | 
			
		||||
                    try
 | 
			
		||||
                    {
 | 
			
		||||
                        LLSDHelpers.DeserialiseOSDMap(inventoryhash, llsdRequest);
 | 
			
		||||
                    }
 | 
			
		||||
                    catch (Exception e)
 | 
			
		||||
                    {
 | 
			
		||||
                        m_log.Debug("[WEB FETCH INV DESC HANDLER]: caught exception doing OSD deserialize" + e);
 | 
			
		||||
                    }
 | 
			
		||||
                    LLSDInventoryDescendents reply = FetchInventoryReply(llsdRequest);
 | 
			
		||||
 | 
			
		||||
                    inventoryitemstr = LLSDHelpers.SerialiseLLSDReply(reply);
 | 
			
		||||
                    inventoryitemstr = inventoryitemstr.Replace("<llsd><map><key>folders</key><array>", "");
 | 
			
		||||
                    inventoryitemstr = inventoryitemstr.Replace("</array></map></llsd>", "");
 | 
			
		||||
 | 
			
		||||
                    response += inventoryitemstr;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (response.Length == 0)
 | 
			
		||||
                {
 | 
			
		||||
                    // Ter-guess: If requests fail a lot, the client seems to stop requesting descendants.
 | 
			
		||||
                    // Therefore, I'm concluding that the client only has so many threads available to do requests
 | 
			
		||||
                    // and when a thread stalls..   is stays stalled.
 | 
			
		||||
                    // Therefore we need to return something valid
 | 
			
		||||
                    response = "<llsd><map><key>folders</key><array /></map></llsd>";
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    response = "<llsd><map><key>folders</key><array>" + response + "</array></map></llsd>";
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
//                m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Replying to CAPS fetch inventory request");
 | 
			
		||||
                //m_log.Debug("[WEB FETCH INV DESC HANDLER] "+response);
 | 
			
		||||
 | 
			
		||||
                return response;
 | 
			
		||||
 | 
			
		||||
//            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Construct an LLSD reply packet to a CAPS inventory request
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="invFetch"></param>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        private LLSDInventoryDescendents FetchInventoryReply(LLSDFetchInventoryDescendents invFetch)
 | 
			
		||||
        {
 | 
			
		||||
            LLSDInventoryDescendents reply = new LLSDInventoryDescendents();
 | 
			
		||||
            LLSDInventoryFolderContents contents = new LLSDInventoryFolderContents();
 | 
			
		||||
            contents.agent_id = invFetch.owner_id;
 | 
			
		||||
            contents.owner_id = invFetch.owner_id;
 | 
			
		||||
            contents.folder_id = invFetch.folder_id;
 | 
			
		||||
 | 
			
		||||
            reply.folders.Array.Add(contents);
 | 
			
		||||
            InventoryCollection inv = new InventoryCollection();
 | 
			
		||||
            inv.Folders = new List<InventoryFolderBase>();
 | 
			
		||||
            inv.Items = new List<InventoryItemBase>();
 | 
			
		||||
            int version = 0;
 | 
			
		||||
            int descendents = 0;
 | 
			
		||||
 | 
			
		||||
            inv
 | 
			
		||||
                = Fetch(
 | 
			
		||||
                    invFetch.owner_id, invFetch.folder_id, invFetch.owner_id,
 | 
			
		||||
                    invFetch.fetch_folders, invFetch.fetch_items, invFetch.sort_order, out version, out descendents);
 | 
			
		||||
 | 
			
		||||
            if (inv != null && inv.Folders != null)
 | 
			
		||||
            {
 | 
			
		||||
                foreach (InventoryFolderBase invFolder in inv.Folders)
 | 
			
		||||
                {
 | 
			
		||||
                    contents.categories.Array.Add(ConvertInventoryFolder(invFolder));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                descendents += inv.Folders.Count;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (inv != null && inv.Items != null)
 | 
			
		||||
            {
 | 
			
		||||
                foreach (InventoryItemBase invItem in inv.Items)
 | 
			
		||||
                {
 | 
			
		||||
                    contents.items.Array.Add(ConvertInventoryItem(invItem));
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            contents.descendents = descendents;
 | 
			
		||||
            contents.version = version;
 | 
			
		||||
 | 
			
		||||
//            m_log.DebugFormat(
 | 
			
		||||
//                "[WEB FETCH INV DESC HANDLER]: Replying to request for folder {0} (fetch items {1}, fetch folders {2}) with {3} items and {4} folders for agent {5}",
 | 
			
		||||
//                invFetch.folder_id,
 | 
			
		||||
//                invFetch.fetch_items,
 | 
			
		||||
//                invFetch.fetch_folders,
 | 
			
		||||
//                contents.items.Array.Count,
 | 
			
		||||
//                contents.categories.Array.Count,
 | 
			
		||||
//                invFetch.owner_id);
 | 
			
		||||
 | 
			
		||||
            return reply;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Handle the caps inventory descendents fetch.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="agentID"></param>
 | 
			
		||||
        /// <param name="folderID"></param>
 | 
			
		||||
        /// <param name="ownerID"></param>
 | 
			
		||||
        /// <param name="fetchFolders"></param>
 | 
			
		||||
        /// <param name="fetchItems"></param>
 | 
			
		||||
        /// <param name="sortOrder"></param>
 | 
			
		||||
        /// <param name="version"></param>
 | 
			
		||||
        /// <returns>An empty InventoryCollection if the inventory look up failed</returns>
 | 
			
		||||
        private InventoryCollection Fetch(
 | 
			
		||||
            UUID agentID, UUID folderID, UUID ownerID,
 | 
			
		||||
            bool fetchFolders, bool fetchItems, int sortOrder, out int version, out int descendents)
 | 
			
		||||
        {
 | 
			
		||||
//            m_log.DebugFormat(
 | 
			
		||||
//                "[WEB FETCH INV DESC HANDLER]: Fetching folders ({0}), items ({1}) from {2} for agent {3}",
 | 
			
		||||
//                fetchFolders, fetchItems, folderID, agentID);
 | 
			
		||||
 | 
			
		||||
            // FIXME MAYBE: We're not handling sortOrder!
 | 
			
		||||
 | 
			
		||||
            version = 0;
 | 
			
		||||
            descendents = 0;
 | 
			
		||||
 | 
			
		||||
            InventoryFolderImpl fold;
 | 
			
		||||
            if (m_LibraryService != null && m_LibraryService.LibraryRootFolder != null && agentID == m_LibraryService.LibraryRootFolder.Owner)
 | 
			
		||||
            {
 | 
			
		||||
                if ((fold = m_LibraryService.LibraryRootFolder.FindFolder(folderID)) != null)
 | 
			
		||||
                {
 | 
			
		||||
                    InventoryCollection ret = new InventoryCollection();
 | 
			
		||||
                    ret.Folders = new List<InventoryFolderBase>();
 | 
			
		||||
                    ret.Items = fold.RequestListOfItems();
 | 
			
		||||
                    descendents = ret.Folders.Count + ret.Items.Count;
 | 
			
		||||
 | 
			
		||||
                    return ret;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            InventoryCollection contents = new InventoryCollection();
 | 
			
		||||
 | 
			
		||||
            if (folderID != UUID.Zero)
 | 
			
		||||
            {
 | 
			
		||||
                contents = m_InventoryService.GetFolderContent(agentID, folderID);
 | 
			
		||||
                InventoryFolderBase containingFolder = new InventoryFolderBase();
 | 
			
		||||
                containingFolder.ID = folderID;
 | 
			
		||||
                containingFolder.Owner = agentID;
 | 
			
		||||
                containingFolder = m_InventoryService.GetFolder(containingFolder);
 | 
			
		||||
 | 
			
		||||
                if (containingFolder != null)
 | 
			
		||||
                {
 | 
			
		||||
//                    m_log.DebugFormat(
 | 
			
		||||
//                        "[WEB FETCH INV DESC HANDLER]: Retrieved folder {0} {1} for agent id {2}",
 | 
			
		||||
//                        containingFolder.Name, containingFolder.ID, agentID);
 | 
			
		||||
 | 
			
		||||
                    version = containingFolder.Version;
 | 
			
		||||
 | 
			
		||||
                    if (fetchItems)
 | 
			
		||||
                    {
 | 
			
		||||
                        List<InventoryItemBase> itemsToReturn = contents.Items;
 | 
			
		||||
                        List<InventoryItemBase> originalItems = new List<InventoryItemBase>(itemsToReturn);
 | 
			
		||||
 | 
			
		||||
                        // descendents must only include the links, not the linked items we add
 | 
			
		||||
                        descendents = originalItems.Count;
 | 
			
		||||
 | 
			
		||||
                        // Add target items for links in this folder before the links themselves.
 | 
			
		||||
                        foreach (InventoryItemBase item in originalItems)
 | 
			
		||||
                        {
 | 
			
		||||
                            if (item.AssetType == (int)AssetType.Link)
 | 
			
		||||
                            {
 | 
			
		||||
                                InventoryItemBase linkedItem = m_InventoryService.GetItem(new InventoryItemBase(item.AssetID));
 | 
			
		||||
 | 
			
		||||
                                // Take care of genuinely broken links where the target doesn't exist
 | 
			
		||||
                                // HACK: Also, don't follow up links that just point to other links.  In theory this is legitimate,
 | 
			
		||||
                                // but no viewer has been observed to set these up and this is the lazy way of avoiding cycles
 | 
			
		||||
                                // rather than having to keep track of every folder requested in the recursion.
 | 
			
		||||
                                if (linkedItem != null && linkedItem.AssetType != (int)AssetType.Link)
 | 
			
		||||
                                    itemsToReturn.Insert(0, linkedItem);
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        // Now scan for folder links and insert the items they target and those links at the head of the return data
 | 
			
		||||
                        foreach (InventoryItemBase item in originalItems)
 | 
			
		||||
                        {
 | 
			
		||||
                            if (item.AssetType == (int)AssetType.LinkFolder)
 | 
			
		||||
                            {
 | 
			
		||||
                                InventoryCollection linkedFolderContents = m_InventoryService.GetFolderContent(ownerID, item.AssetID);
 | 
			
		||||
                                List<InventoryItemBase> links = linkedFolderContents.Items;
 | 
			
		||||
 | 
			
		||||
                                itemsToReturn.InsertRange(0, links);
 | 
			
		||||
 | 
			
		||||
                                foreach (InventoryItemBase link in linkedFolderContents.Items)
 | 
			
		||||
                                {
 | 
			
		||||
                                    // Take care of genuinely broken links where the target doesn't exist
 | 
			
		||||
                                    // HACK: Also, don't follow up links that just point to other links.  In theory this is legitimate,
 | 
			
		||||
                                    // but no viewer has been observed to set these up and this is the lazy way of avoiding cycles
 | 
			
		||||
                                    // rather than having to keep track of every folder requested in the recursion.
 | 
			
		||||
                                    if (link != null)
 | 
			
		||||
                                    {
 | 
			
		||||
//                                        m_log.DebugFormat(
 | 
			
		||||
//                                            "[WEB FETCH INV DESC HANDLER]: Adding item {0} {1} from folder {2} linked from {3}",
 | 
			
		||||
//                                            link.Name, (AssetType)link.AssetType, item.AssetID, containingFolder.Name);
 | 
			
		||||
 | 
			
		||||
                                        InventoryItemBase linkedItem
 | 
			
		||||
                                            = m_InventoryService.GetItem(new InventoryItemBase(link.AssetID));
 | 
			
		||||
 | 
			
		||||
                                        if (linkedItem != null)
 | 
			
		||||
                                            itemsToReturn.Insert(0, linkedItem);
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
//                    foreach (InventoryItemBase item in contents.Items)
 | 
			
		||||
//                    {
 | 
			
		||||
//                        m_log.DebugFormat(
 | 
			
		||||
//                            "[WEB FETCH INV DESC HANDLER]: Returning item {0}, type {1}, parent {2} in {3} {4}",
 | 
			
		||||
//                            item.Name, (AssetType)item.AssetType, item.Folder, containingFolder.Name, containingFolder.ID);
 | 
			
		||||
//                    }
 | 
			
		||||
 | 
			
		||||
                    // =====
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//                        foreach (InventoryItemBase linkedItem in linkedItemsToAdd)
 | 
			
		||||
//                        {
 | 
			
		||||
//                            m_log.DebugFormat(
 | 
			
		||||
//                                "[WEB FETCH INV DESC HANDLER]: Inserted linked item {0} for link in folder {1} for agent {2}",
 | 
			
		||||
//                                linkedItem.Name, folderID, agentID);
 | 
			
		||||
//
 | 
			
		||||
//                            contents.Items.Add(linkedItem);
 | 
			
		||||
//                        }
 | 
			
		||||
//
 | 
			
		||||
//                        // If the folder requested contains links, then we need to send those folders first, otherwise the links
 | 
			
		||||
//                        // will be broken in the viewer.
 | 
			
		||||
//                        HashSet<UUID> linkedItemFolderIdsToSend = new HashSet<UUID>();
 | 
			
		||||
//                        foreach (InventoryItemBase item in contents.Items)
 | 
			
		||||
//                        {
 | 
			
		||||
//                            if (item.AssetType == (int)AssetType.Link)
 | 
			
		||||
//                            {
 | 
			
		||||
//                                InventoryItemBase linkedItem = m_InventoryService.GetItem(new InventoryItemBase(item.AssetID));
 | 
			
		||||
//
 | 
			
		||||
//                                // Take care of genuinely broken links where the target doesn't exist
 | 
			
		||||
//                                // HACK: Also, don't follow up links that just point to other links.  In theory this is legitimate,
 | 
			
		||||
//                                // but no viewer has been observed to set these up and this is the lazy way of avoiding cycles
 | 
			
		||||
//                                // rather than having to keep track of every folder requested in the recursion.
 | 
			
		||||
//                                if (linkedItem != null && linkedItem.AssetType != (int)AssetType.Link)
 | 
			
		||||
//                                {
 | 
			
		||||
//                                    // We don't need to send the folder if source and destination of the link are in the same
 | 
			
		||||
//                                    // folder.
 | 
			
		||||
//                                    if (linkedItem.Folder != containingFolder.ID)
 | 
			
		||||
//                                        linkedItemFolderIdsToSend.Add(linkedItem.Folder);
 | 
			
		||||
//                                }
 | 
			
		||||
//                            }
 | 
			
		||||
//                        }
 | 
			
		||||
//    
 | 
			
		||||
//                        foreach (UUID linkedItemFolderId in linkedItemFolderIdsToSend)
 | 
			
		||||
//                        {
 | 
			
		||||
//                            m_log.DebugFormat(
 | 
			
		||||
//                                "[WEB FETCH INV DESC HANDLER]: Recursively fetching folder {0} linked by item in folder {1} for agent {2}",
 | 
			
		||||
//                                linkedItemFolderId, folderID, agentID);
 | 
			
		||||
//
 | 
			
		||||
//                            int dummyVersion;
 | 
			
		||||
//                            InventoryCollection linkedCollection
 | 
			
		||||
//                                = Fetch(
 | 
			
		||||
//                                    agentID, linkedItemFolderId, ownerID, fetchFolders, fetchItems, sortOrder, out dummyVersion);
 | 
			
		||||
//
 | 
			
		||||
//                            InventoryFolderBase linkedFolder = new InventoryFolderBase(linkedItemFolderId);
 | 
			
		||||
//                            linkedFolder.Owner = agentID;
 | 
			
		||||
//                            linkedFolder = m_InventoryService.GetFolder(linkedFolder);
 | 
			
		||||
//
 | 
			
		||||
////                            contents.Folders.AddRange(linkedCollection.Folders);
 | 
			
		||||
//
 | 
			
		||||
//                            contents.Folders.Add(linkedFolder);
 | 
			
		||||
//                            contents.Items.AddRange(linkedCollection.Items);
 | 
			
		||||
//                        }
 | 
			
		||||
//                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                // Lost items don't really need a version
 | 
			
		||||
                version = 1;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return contents;
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Convert an internal inventory folder object into an LLSD object.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="invFolder"></param>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        private LLSDInventoryFolder ConvertInventoryFolder(InventoryFolderBase invFolder)
 | 
			
		||||
        {
 | 
			
		||||
            LLSDInventoryFolder llsdFolder = new LLSDInventoryFolder();
 | 
			
		||||
            llsdFolder.folder_id = invFolder.ID;
 | 
			
		||||
            llsdFolder.parent_id = invFolder.ParentID;
 | 
			
		||||
            llsdFolder.name = invFolder.Name;
 | 
			
		||||
            llsdFolder.type = invFolder.Type;
 | 
			
		||||
            llsdFolder.preferred_type = -1;
 | 
			
		||||
 | 
			
		||||
            return llsdFolder;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Convert an internal inventory item object into an LLSD object.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="invItem"></param>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        private LLSDInventoryItem ConvertInventoryItem(InventoryItemBase invItem)
 | 
			
		||||
        {
 | 
			
		||||
            LLSDInventoryItem llsdItem = new LLSDInventoryItem();
 | 
			
		||||
            llsdItem.asset_id = invItem.AssetID;
 | 
			
		||||
            llsdItem.created_at = invItem.CreationDate;
 | 
			
		||||
            llsdItem.desc = invItem.Description;
 | 
			
		||||
            llsdItem.flags = (int)invItem.Flags;
 | 
			
		||||
            llsdItem.item_id = invItem.ID;
 | 
			
		||||
            llsdItem.name = invItem.Name;
 | 
			
		||||
            llsdItem.parent_id = invItem.Folder;
 | 
			
		||||
            llsdItem.type = invItem.AssetType;
 | 
			
		||||
            llsdItem.inv_type = invItem.InvType;
 | 
			
		||||
 | 
			
		||||
            llsdItem.permissions = new LLSDPermissions();
 | 
			
		||||
            llsdItem.permissions.creator_id = invItem.CreatorIdAsUuid;
 | 
			
		||||
            llsdItem.permissions.base_mask = (int)invItem.CurrentPermissions;
 | 
			
		||||
            llsdItem.permissions.everyone_mask = (int)invItem.EveryOnePermissions;
 | 
			
		||||
            llsdItem.permissions.group_id = invItem.GroupID;
 | 
			
		||||
            llsdItem.permissions.group_mask = (int)invItem.GroupPermissions;
 | 
			
		||||
            llsdItem.permissions.is_owner_group = invItem.GroupOwned;
 | 
			
		||||
            llsdItem.permissions.next_owner_mask = (int)invItem.NextPermissions;
 | 
			
		||||
            llsdItem.permissions.owner_id = invItem.Owner;
 | 
			
		||||
            llsdItem.permissions.owner_mask = (int)invItem.CurrentPermissions;
 | 
			
		||||
            llsdItem.sale_info = new LLSDSaleInfo();
 | 
			
		||||
            llsdItem.sale_info.sale_price = invItem.SalePrice;
 | 
			
		||||
            llsdItem.sale_info.sale_type = invItem.SaleType;
 | 
			
		||||
 | 
			
		||||
            return llsdItem;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -29,22 +29,19 @@ using System;
 | 
			
		|||
using Nini.Config;
 | 
			
		||||
using 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
 | 
			
		||||
    public class WebFetchInvDescServerConnector : ServiceConnector
 | 
			
		||||
    {
 | 
			
		||||
        private IInventoryService m_InventoryService;
 | 
			
		||||
        private ILibraryService m_LibraryService;
 | 
			
		||||
        private string m_ConfigName = "CapsService";
 | 
			
		||||
 | 
			
		||||
        public FetchInvDescServerConnector(IConfigSource config, IHttpServer server, string configName) :
 | 
			
		||||
        public WebFetchInvDescServerConnector(IConfigSource config, IHttpServer server, string configName) :
 | 
			
		||||
                base(config, server, configName)
 | 
			
		||||
        {
 | 
			
		||||
            if (configName != String.Empty)
 | 
			
		||||
| 
						 | 
				
			
			@ -70,16 +67,16 @@ namespace OpenSim.Capabilities.Handlers
 | 
			
		|||
            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);
 | 
			
		||||
            WebFetchInvDescHandler webFetchHandler = new WebFetchInvDescHandler(m_InventoryService, m_LibraryService);
 | 
			
		||||
            IRequestHandler reqHandler
 | 
			
		||||
                = new RestStreamHandler(
 | 
			
		||||
                    "POST",
 | 
			
		||||
                    "/CAPS/WebFetchInvDesc/" /*+ UUID.Random()*/,
 | 
			
		||||
                    webFetchHandler.FetchInventoryDescendentsRequest,
 | 
			
		||||
                    "WebFetchInvDesc",
 | 
			
		||||
                    null);
 | 
			
		||||
            server.AddStreamHandler(reqHandler);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -68,10 +68,7 @@ namespace OpenSim.Framework.Capabilities
 | 
			
		|||
        /// <returns></returns>
 | 
			
		||||
        public static object LLSDDeserialize(byte[] b)
 | 
			
		||||
        {
 | 
			
		||||
            using (MemoryStream ms = new MemoryStream(b, false))
 | 
			
		||||
            {
 | 
			
		||||
                return LLSDDeserialize(ms);
 | 
			
		||||
            }
 | 
			
		||||
            return LLSDDeserialize(new MemoryStream(b, false));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
| 
						 | 
				
			
			@ -81,23 +78,21 @@ namespace OpenSim.Framework.Capabilities
 | 
			
		|||
        /// <returns></returns>
 | 
			
		||||
        public static object LLSDDeserialize(Stream st)
 | 
			
		||||
        {
 | 
			
		||||
            using (XmlTextReader reader = new XmlTextReader(st))
 | 
			
		||||
            {
 | 
			
		||||
                reader.Read();
 | 
			
		||||
                SkipWS(reader);
 | 
			
		||||
            XmlTextReader reader = new XmlTextReader(st);
 | 
			
		||||
            reader.Read();
 | 
			
		||||
            SkipWS(reader);
 | 
			
		||||
 | 
			
		||||
                if (reader.NodeType != XmlNodeType.Element || reader.LocalName != "llsd")
 | 
			
		||||
                    throw new LLSDParseException("Expected <llsd>");
 | 
			
		||||
            if (reader.NodeType != XmlNodeType.Element || reader.LocalName != "llsd")
 | 
			
		||||
                throw new LLSDParseException("Expected <llsd>");
 | 
			
		||||
 | 
			
		||||
                reader.Read();
 | 
			
		||||
                object ret = LLSDParseOne(reader);
 | 
			
		||||
                SkipWS(reader);
 | 
			
		||||
            reader.Read();
 | 
			
		||||
            object ret = LLSDParseOne(reader);
 | 
			
		||||
            SkipWS(reader);
 | 
			
		||||
 | 
			
		||||
                if (reader.NodeType != XmlNodeType.EndElement || reader.LocalName != "llsd")
 | 
			
		||||
                    throw new LLSDParseException("Expected </llsd>");
 | 
			
		||||
            if (reader.NodeType != XmlNodeType.EndElement || reader.LocalName != "llsd")
 | 
			
		||||
                throw new LLSDParseException("Expected </llsd>");
 | 
			
		||||
 | 
			
		||||
                return ret;
 | 
			
		||||
            }
 | 
			
		||||
            return ret;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
| 
						 | 
				
			
			@ -107,17 +102,17 @@ namespace OpenSim.Framework.Capabilities
 | 
			
		|||
        /// <returns></returns>
 | 
			
		||||
        public static byte[] LLSDSerialize(object obj)
 | 
			
		||||
        {
 | 
			
		||||
            using(StringWriter sw = new StringWriter())
 | 
			
		||||
            using(XmlTextWriter writer = new XmlTextWriter(sw))
 | 
			
		||||
            {
 | 
			
		||||
                writer.Formatting = Formatting.None;
 | 
			
		||||
            StringWriter sw = new StringWriter();
 | 
			
		||||
            XmlTextWriter writer = new XmlTextWriter(sw);
 | 
			
		||||
            writer.Formatting = Formatting.None;
 | 
			
		||||
 | 
			
		||||
                writer.WriteStartElement(String.Empty, "llsd", String.Empty);
 | 
			
		||||
                LLSDWriteOne(writer, obj);
 | 
			
		||||
                writer.WriteEndElement();
 | 
			
		||||
                writer.Flush();
 | 
			
		||||
                return Util.UTF8.GetBytes(sw.ToString());
 | 
			
		||||
            }           
 | 
			
		||||
            writer.WriteStartElement(String.Empty, "llsd", String.Empty);
 | 
			
		||||
            LLSDWriteOne(writer, obj);
 | 
			
		||||
            writer.WriteEndElement();
 | 
			
		||||
 | 
			
		||||
            writer.Close();
 | 
			
		||||
 | 
			
		||||
            return Util.UTF8.GetBytes(sw.ToString());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
| 
						 | 
				
			
			@ -566,7 +561,7 @@ namespace OpenSim.Framework.Capabilities
 | 
			
		|||
                        endPos = FindEnd(llsd, 1);
 | 
			
		||||
 | 
			
		||||
                        if (Double.TryParse(llsd.Substring(1, endPos - 1), NumberStyles.Float,
 | 
			
		||||
                                            Culture.NumberFormatInfo, out value))
 | 
			
		||||
                                            Utils.EnUsCulture.NumberFormat, out value))
 | 
			
		||||
                            return value;
 | 
			
		||||
                        else
 | 
			
		||||
                            throw new LLSDParseException("Failed to parse double value type");
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,20 +30,13 @@ 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()
 | 
			
		||||
        {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,28 +30,15 @@ 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()
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,51 +26,20 @@
 | 
			
		|||
 */
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,68 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) Contributors, http://opensimulator.org/
 | 
			
		||||
 * See CONTRIBUTORS.TXT for a full list of copyright holders.
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 *     * Redistributions of source code must retain the above copyright
 | 
			
		||||
 *       notice, this list of conditions and the following disclaimer.
 | 
			
		||||
 *     * Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *       notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *       documentation and/or other materials provided with the distribution.
 | 
			
		||||
 *     * Neither the name of the OpenSimulator Project nor the
 | 
			
		||||
 *       names of its contributors may be used to endorse or promote products
 | 
			
		||||
 *       derived from this software without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
 | 
			
		||||
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 | 
			
		||||
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 | 
			
		||||
 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
 | 
			
		||||
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 | 
			
		||||
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 | 
			
		||||
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 | 
			
		||||
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
			
		||||
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 | 
			
		||||
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using OpenMetaverse;
 | 
			
		||||
 | 
			
		||||
namespace OpenSim.Framework.Capabilities
 | 
			
		||||
{
 | 
			
		||||
    [OSDMap]
 | 
			
		||||
    public class LLSDEnvironmentRequest
 | 
			
		||||
    {
 | 
			
		||||
        public UUID messageID;
 | 
			
		||||
        public UUID regionID;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [OSDMap]
 | 
			
		||||
    public class LLSDEnvironmentSetResponse
 | 
			
		||||
    {
 | 
			
		||||
        public UUID regionID;
 | 
			
		||||
        public UUID messageID;
 | 
			
		||||
        public Boolean success;
 | 
			
		||||
        public String fail_reason;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class EnvironmentSettings
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// generates a empty llsd settings response for viewer
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="messageID">the message UUID</param>
 | 
			
		||||
        /// <param name="regionID">the region UUID</param>
 | 
			
		||||
        public static string EmptySettings(UUID messageID, UUID regionID)
 | 
			
		||||
        {
 | 
			
		||||
            OSDArray arr = new OSDArray();
 | 
			
		||||
            LLSDEnvironmentRequest msg = new LLSDEnvironmentRequest();
 | 
			
		||||
            msg.messageID = messageID;
 | 
			
		||||
            msg.regionID = regionID;
 | 
			
		||||
            arr.Array.Add(msg);
 | 
			
		||||
            return LLSDHelpers.SerialiseLLSDReply(arr);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -30,7 +30,6 @@ using System.Collections;
 | 
			
		|||
using System.IO;
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
using System.Xml;
 | 
			
		||||
using OpenMetaverse;
 | 
			
		||||
 | 
			
		||||
namespace OpenSim.Framework.Capabilities
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -41,32 +40,17 @@ namespace OpenSim.Framework.Capabilities
 | 
			
		|||
 | 
			
		||||
        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();
 | 
			
		||||
            StringWriter sw = new StringWriter();
 | 
			
		||||
            XmlTextWriter writer = new XmlTextWriter(sw);
 | 
			
		||||
            writer.Formatting = Formatting.None;
 | 
			
		||||
            writer.WriteStartElement(String.Empty, "llsd", String.Empty);
 | 
			
		||||
            SerializeOSDType(writer, obj);
 | 
			
		||||
            writer.WriteEndElement();
 | 
			
		||||
            writer.Close();
 | 
			
		||||
 | 
			
		||||
            //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();
 | 
			
		||||
            }
 | 
			
		||||
            return sw.ToString();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static void SerializeOSDType(XmlTextWriter writer, object obj)
 | 
			
		||||
| 
						 | 
				
			
			@ -173,22 +157,6 @@ namespace OpenSim.Framework.Capabilities
 | 
			
		|||
                                    // the LLSD map/array types in the array need to be deserialised
 | 
			
		||||
                                    // 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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -37,6 +37,5 @@ namespace OpenSim.Framework.Capabilities
 | 
			
		|||
        public string name;
 | 
			
		||||
        public int type;
 | 
			
		||||
        public int preferred_type;
 | 
			
		||||
        public int version;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -25,15 +25,17 @@
 | 
			
		|||
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using OpenMetaverse;
 | 
			
		||||
 | 
			
		||||
namespace Robust32
 | 
			
		||||
namespace OpenSim.Framework.Capabilities
 | 
			
		||||
{
 | 
			
		||||
    class Program
 | 
			
		||||
    [OSDMap]
 | 
			
		||||
    public class LLSDItemUpdate
 | 
			
		||||
    {
 | 
			
		||||
        static void Main(string[] args)
 | 
			
		||||
        public UUID item_id;
 | 
			
		||||
 | 
			
		||||
        public LLSDItemUpdate()
 | 
			
		||||
        {
 | 
			
		||||
                global::OpenSim.Server.OpenSimServer.Main(args);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,51 @@
 | 
			
		|||
/*
 | 
			
		||||
* Copyright (c) Contributors, http://opensimulator.org/
 | 
			
		||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
 | 
			
		||||
*
 | 
			
		||||
* Redistribution and use in source and binary forms, with or without
 | 
			
		||||
* modification, are permitted provided that the following conditions are met:
 | 
			
		||||
*     * Redistributions of source code must retain the above copyright
 | 
			
		||||
*       notice, this list of conditions and the following disclaimer.
 | 
			
		||||
*     * Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
*       notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
*       documentation and/or other materials provided with the distribution.
 | 
			
		||||
*     * Neither the name of the OpenSimulator Project nor the
 | 
			
		||||
*       names of its contributors may be used to endorse or promote products
 | 
			
		||||
*       derived from this software without specific prior written permission.
 | 
			
		||||
*
 | 
			
		||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
 | 
			
		||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 | 
			
		||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 | 
			
		||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
 | 
			
		||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 | 
			
		||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 | 
			
		||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 | 
			
		||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
			
		||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 | 
			
		||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
*
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System.Collections;
 | 
			
		||||
 | 
			
		||||
namespace OpenSim.Framework.Capabilities
 | 
			
		||||
{
 | 
			
		||||
    [OSDMap]
 | 
			
		||||
    public class LLSDParcelVoiceInfoResponse
 | 
			
		||||
    {
 | 
			
		||||
        public int parcel_local_id;
 | 
			
		||||
        public string region_name;
 | 
			
		||||
        public Hashtable voice_credentials;
 | 
			
		||||
 | 
			
		||||
        public LLSDParcelVoiceInfoResponse()
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public LLSDParcelVoiceInfoResponse(string region, int localID, Hashtable creds)
 | 
			
		||||
        {
 | 
			
		||||
            region_name = region;
 | 
			
		||||
            parcel_local_id = localID;
 | 
			
		||||
            voice_credentials = creds;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,42 @@
 | 
			
		|||
/*
 | 
			
		||||
* Copyright (c) Contributors, http://opensimulator.org/
 | 
			
		||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
 | 
			
		||||
*
 | 
			
		||||
* Redistribution and use in source and binary forms, with or without
 | 
			
		||||
* modification, are permitted provided that the following conditions are met:
 | 
			
		||||
*     * Redistributions of source code must retain the above copyright
 | 
			
		||||
*       notice, this list of conditions and the following disclaimer.
 | 
			
		||||
*     * Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
*       notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
*       documentation and/or other materials provided with the distribution.
 | 
			
		||||
*     * Neither the name of the OpenSimulator Project nor the
 | 
			
		||||
*       names of its contributors may be used to endorse or promote products
 | 
			
		||||
*       derived from this software without specific prior written permission.
 | 
			
		||||
*
 | 
			
		||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
 | 
			
		||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 | 
			
		||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 | 
			
		||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
 | 
			
		||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 | 
			
		||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 | 
			
		||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 | 
			
		||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
			
		||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 | 
			
		||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
*
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using OpenMetaverse;
 | 
			
		||||
 | 
			
		||||
namespace OpenSim.Framework.Capabilities
 | 
			
		||||
{
 | 
			
		||||
    [LLSDType("MAP")]
 | 
			
		||||
    public class LLSDRemoteParcelResponse
 | 
			
		||||
    {
 | 
			
		||||
        public UUID parcel_id;
 | 
			
		||||
 | 
			
		||||
        public LLSDRemoteParcelResponse()
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -61,9 +61,6 @@ namespace OpenSim.Framework.Capabilities
 | 
			
		|||
            //    OpenMetaverse.StructuredData.LLSDParser.DeserializeXml(new XmlTextReader(request));
 | 
			
		||||
 | 
			
		||||
            Hashtable hash = (Hashtable) LLSD.LLSDDeserialize(request);
 | 
			
		||||
            if(hash == null)
 | 
			
		||||
                return new byte[0];
 | 
			
		||||
 | 
			
		||||
            TRequest llsdRequest = new TRequest();
 | 
			
		||||
            LLSDHelpers.DeserialiseOSDMap(hash, llsdRequest);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,50 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) Contributors, http://opensimulator.org/
 | 
			
		||||
 * See CONTRIBUTORS.TXT for a full list of copyright holders.
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 *     * Redistributions of source code must retain the above copyright
 | 
			
		||||
 *       notice, this list of conditions and the following disclaimer.
 | 
			
		||||
 *     * Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *       notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *       documentation and/or other materials provided with the distribution.
 | 
			
		||||
 *     * Neither the name of the OpenSimulator Project nor the
 | 
			
		||||
 *       names of its contributors may be used to endorse or promote products
 | 
			
		||||
 *       derived from this software without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
 | 
			
		||||
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 | 
			
		||||
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 | 
			
		||||
 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
 | 
			
		||||
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 | 
			
		||||
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 | 
			
		||||
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 | 
			
		||||
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
			
		||||
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 | 
			
		||||
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
using OpenMetaverse;
 | 
			
		||||
 | 
			
		||||
namespace OpenSim.Framework.Capabilities
 | 
			
		||||
{
 | 
			
		||||
    [OSDMap]
 | 
			
		||||
    public class LLSDTaskScriptUpdate
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// The item containing the script to update
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public UUID item_id;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// The task containing the script
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public UUID task_id;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Signals whether the script is currently active
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public int is_script_running;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,57 @@
 | 
			
		|||
/*
 | 
			
		||||
* Copyright (c) Contributors, http://opensimulator.org/
 | 
			
		||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
 | 
			
		||||
*
 | 
			
		||||
* Redistribution and use in source and binary forms, with or without
 | 
			
		||||
* modification, are permitted provided that the following conditions are met:
 | 
			
		||||
*     * Redistributions of source code must retain the above copyright
 | 
			
		||||
*       notice, this list of conditions and the following disclaimer.
 | 
			
		||||
*     * Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
*       notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
*       documentation and/or other materials provided with the distribution.
 | 
			
		||||
*     * Neither the name of the OpenSimulator Project nor the
 | 
			
		||||
*       names of its contributors may be used to endorse or promote products
 | 
			
		||||
*       derived from this software without specific prior written permission.
 | 
			
		||||
*
 | 
			
		||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
 | 
			
		||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 | 
			
		||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 | 
			
		||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
 | 
			
		||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 | 
			
		||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 | 
			
		||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 | 
			
		||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
			
		||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 | 
			
		||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
*
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
namespace OpenSim.Framework.Capabilities
 | 
			
		||||
{
 | 
			
		||||
    [OSDMap]
 | 
			
		||||
    public class LLSDVoiceAccountResponse
 | 
			
		||||
    {
 | 
			
		||||
        public string username;
 | 
			
		||||
        public string password;
 | 
			
		||||
        public string voice_sip_uri_hostname;
 | 
			
		||||
        public string voice_account_server_name;
 | 
			
		||||
 | 
			
		||||
        public LLSDVoiceAccountResponse()
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public LLSDVoiceAccountResponse(string user, string pass)
 | 
			
		||||
        {
 | 
			
		||||
            username = user;
 | 
			
		||||
            password = pass;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public LLSDVoiceAccountResponse(string user, string pass, string sipUriHost, string accountServer)
 | 
			
		||||
        {
 | 
			
		||||
            username = user;
 | 
			
		||||
            password = pass;
 | 
			
		||||
            voice_sip_uri_hostname = sipUriHost;
 | 
			
		||||
            voice_account_server_name = accountServer;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -80,7 +80,7 @@ namespace OpenSim.ConsoleClient
 | 
			
		|||
            while (m_Server.Running)
 | 
			
		||||
            {
 | 
			
		||||
                System.Threading.Thread.Sleep(500);
 | 
			
		||||
                MainConsole.Instance.Prompt();
 | 
			
		||||
                // MainConsole.Instance.Prompt();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (pidFile != String.Empty)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -37,8 +37,9 @@ 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 void StoreAsset(AssetBase asset);
 | 
			
		||||
        public abstract bool ExistsAsset(UUID uuid);
 | 
			
		||||
 | 
			
		||||
        public abstract List<AssetMetadata> FetchAssetMetadataSet(int start, int count);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -47,25 +47,24 @@ namespace OpenSim.Data
 | 
			
		|||
            if ((id == null) || (id == DBNull.Value))
 | 
			
		||||
                return UUID.Zero;
 | 
			
		||||
 | 
			
		||||
            Type idtype = id.GetType();
 | 
			
		||||
 | 
			
		||||
            if (idtype == typeof(Guid))
 | 
			
		||||
            if (id.GetType() == typeof(Guid))
 | 
			
		||||
                return new UUID((Guid)id);
 | 
			
		||||
 | 
			
		||||
            if (id.GetType() == typeof(string))
 | 
			
		||||
            if (id.GetType() == typeof(byte[]))
 | 
			
		||||
            {
 | 
			
		||||
                Guid gg; 
 | 
			
		||||
                if (Guid.TryParse((string)id, out gg))
 | 
			
		||||
                    return new UUID(gg);
 | 
			
		||||
                return UUID.Zero;
 | 
			
		||||
                if (((byte[])id).Length == 0)
 | 
			
		||||
                    return UUID.Zero;
 | 
			
		||||
                else if (((byte[])id).Length == 16)
 | 
			
		||||
                    return new UUID((byte[])id, 0);
 | 
			
		||||
            }
 | 
			
		||||
            else if (id.GetType() == typeof(string))
 | 
			
		||||
            {
 | 
			
		||||
                if (((string)id).Length == 0)
 | 
			
		||||
                    return UUID.Zero;
 | 
			
		||||
                else if (((string)id).Length == 36)
 | 
			
		||||
                    return new UUID((string)id);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (idtype == typeof(byte[]))
 | 
			
		||||
            {
 | 
			
		||||
                if (((byte[])id).Length < 16)
 | 
			
		||||
                    return UUID.Zero;
 | 
			
		||||
                return new UUID((byte[])id, 0);
 | 
			
		||||
            }
 | 
			
		||||
            throw new Exception("Failed to convert db value to UUID: " + id.ToString());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -34,8 +34,8 @@ namespace OpenSim.Data
 | 
			
		|||
    public interface IAssetDataPlugin : IPlugin
 | 
			
		||||
    {
 | 
			
		||||
        AssetBase GetAsset(UUID uuid);
 | 
			
		||||
        bool StoreAsset(AssetBase asset);
 | 
			
		||||
        bool[] AssetsExist(UUID[] uuids);
 | 
			
		||||
        void StoreAsset(AssetBase asset);
 | 
			
		||||
        bool ExistsAsset(UUID uuid);
 | 
			
		||||
        List<AssetMetadata> FetchAssetMetadataSet(int start, int count);
 | 
			
		||||
        void Initialise(string connect);
 | 
			
		||||
        bool Delete(string id);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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,4 +1,4 @@
 | 
			
		|||
/*
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) Contributors, http://opensimulator.org/
 | 
			
		||||
 * See CONTRIBUTORS.TXT for a full list of copyright holders.
 | 
			
		||||
 *
 | 
			
		||||
| 
						 | 
				
			
			@ -34,7 +34,6 @@ namespace OpenSim.Data
 | 
			
		|||
    public class OfflineIMData
 | 
			
		||||
    {
 | 
			
		||||
        public UUID PrincipalID;
 | 
			
		||||
        public UUID FromID;
 | 
			
		||||
        public Dictionary<string, string> Data;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -48,8 +48,6 @@ namespace OpenSim.Data
 | 
			
		|||
        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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -52,14 +52,14 @@ namespace OpenSim.Data
 | 
			
		|||
        public int sizeY;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Return the x-coordinate of this region in region units.
 | 
			
		||||
        /// Return the x-coordinate of this region.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public int coordX { get { return (int)Util.WorldToRegionLoc((uint)posX); } }
 | 
			
		||||
        public int coordX { get { return posX / (int)Constants.RegionSize; } }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Return the y-coordinate of this region in region units.
 | 
			
		||||
        /// Return the y-coordinate of this region.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public int coordY { get { return (int)Util.WorldToRegionLoc((uint)posY); } }
 | 
			
		||||
        public int coordY { get { return posY / (int)Constants.RegionSize; } }
 | 
			
		||||
 | 
			
		||||
        public Dictionary<string, object> Data;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -71,8 +71,6 @@ namespace OpenSim.Data
 | 
			
		|||
    {
 | 
			
		||||
        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);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -50,6 +50,5 @@ namespace OpenSim.Data
 | 
			
		|||
        bool Store(UserAccountData data);
 | 
			
		||||
        bool Delete(string field, string val);
 | 
			
		||||
        UserAccountData[] GetUsers(UUID scopeID, string query);
 | 
			
		||||
        UserAccountData[] GetUsersWhere(UUID scopeID, string where);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -39,7 +39,7 @@ namespace OpenSim.Data
 | 
			
		|||
    {
 | 
			
		||||
        AssetBase GetAsset(UUID uuid);
 | 
			
		||||
        void StoreAsset(AssetBase asset);
 | 
			
		||||
        bool[] AssetsExist(UUID[] uuids);
 | 
			
		||||
        bool ExistsAsset(UUID uuid);
 | 
			
		||||
        List<AssetMetadata> FetchAssetMetadataSet(int start, int count);
 | 
			
		||||
        void Initialise(string connect);
 | 
			
		||||
        bool Delete(string id);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -48,57 +48,9 @@ namespace OpenSim.Data
 | 
			
		|||
        public ulong everyonePowers;
 | 
			
		||||
        public ulong ownersPowers;
 | 
			
		||||
 | 
			
		||||
        public Dictionary<UUID, XGroupMember> members = new Dictionary<UUID, XGroupMember>();
 | 
			
		||||
        public Dictionary<UUID, XGroupNotice> notices = new Dictionary<UUID, XGroupNotice>();
 | 
			
		||||
 | 
			
		||||
        public XGroup Clone()
 | 
			
		||||
        {
 | 
			
		||||
            XGroup clone = (XGroup)MemberwiseClone();
 | 
			
		||||
            clone.members = new Dictionary<UUID, XGroupMember>();
 | 
			
		||||
            clone.notices = new Dictionary<UUID, XGroupNotice>();
 | 
			
		||||
 | 
			
		||||
            foreach (KeyValuePair<UUID, XGroupMember> kvp in members)
 | 
			
		||||
                clone.members[kvp.Key] = kvp.Value.Clone();
 | 
			
		||||
 | 
			
		||||
            foreach (KeyValuePair<UUID, XGroupNotice> kvp in notices)
 | 
			
		||||
                clone.notices[kvp.Key] = kvp.Value.Clone();
 | 
			
		||||
 | 
			
		||||
            return clone;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class XGroupMember
 | 
			
		||||
    {
 | 
			
		||||
        public UUID agentID;
 | 
			
		||||
        public UUID groupID;
 | 
			
		||||
        public UUID roleID;
 | 
			
		||||
        public bool acceptNotices = true;
 | 
			
		||||
        public bool listInProfile = true;
 | 
			
		||||
 | 
			
		||||
        public XGroupMember Clone()
 | 
			
		||||
        {
 | 
			
		||||
            return (XGroupMember)MemberwiseClone();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class XGroupNotice
 | 
			
		||||
    {
 | 
			
		||||
        public UUID groupID;
 | 
			
		||||
        public UUID noticeID;
 | 
			
		||||
        public uint timestamp;
 | 
			
		||||
        public string fromName;
 | 
			
		||||
        public string subject;
 | 
			
		||||
        public string message;
 | 
			
		||||
        public byte[] binaryBucket;
 | 
			
		||||
        public bool hasAttachment;
 | 
			
		||||
        public int assetType;
 | 
			
		||||
 | 
			
		||||
        public XGroupNotice Clone()
 | 
			
		||||
        {
 | 
			
		||||
            XGroupNotice clone = (XGroupNotice)MemberwiseClone();
 | 
			
		||||
            clone.binaryBucket = (byte[])binaryBucket.Clone();
 | 
			
		||||
 | 
			
		||||
            return clone;
 | 
			
		||||
            return (XGroup)MemberwiseClone();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -106,13 +58,14 @@ namespace OpenSim.Data
 | 
			
		|||
    /// Early stub interface for groups data, not final.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <remarks>
 | 
			
		||||
    /// Currently in-use only for regression test purposes.
 | 
			
		||||
    /// Currently in-use only for regression test purposes.  Needs to be filled out over time.
 | 
			
		||||
    /// </remarks>
 | 
			
		||||
    public interface IXGroupData
 | 
			
		||||
    {
 | 
			
		||||
        bool StoreGroup(XGroup group);
 | 
			
		||||
        XGroup GetGroup(UUID groupID);
 | 
			
		||||
        Dictionary<UUID, XGroup> GetGroups();
 | 
			
		||||
        bool DeleteGroup(UUID groupID);
 | 
			
		||||
        XGroup[] GetGroups(string field, string val);
 | 
			
		||||
        XGroup[] GetGroups(string[] fields, string[] vals);
 | 
			
		||||
        bool DeleteGroups(string field, string val);
 | 
			
		||||
        bool DeleteGroups(string[] fields, string[] vals);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,293 @@
 | 
			
		|||
/*
 | 
			
		||||
 * 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.Data;
 | 
			
		||||
using System.Data.SqlClient;
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using OpenMetaverse;
 | 
			
		||||
using log4net;
 | 
			
		||||
using OpenSim.Framework;
 | 
			
		||||
 | 
			
		||||
namespace OpenSim.Data.MSSQL
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// A MSSQL Interface for the Asset server
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class MSSQLAssetData : AssetDataBase
 | 
			
		||||
    {
 | 
			
		||||
        private const string _migrationStore = "AssetStore";
 | 
			
		||||
 | 
			
		||||
        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 | 
			
		||||
        private long m_ticksToEpoch;
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Database manager
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        private MSSQLManager m_database;
 | 
			
		||||
        private string m_connectionString;
 | 
			
		||||
 | 
			
		||||
        #region IPlugin Members
 | 
			
		||||
 | 
			
		||||
        override public void Dispose() { }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// <para>Initialises asset interface</para>
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        // [Obsolete("Cannot be default-initialized!")]
 | 
			
		||||
        override public void Initialise()
 | 
			
		||||
        {
 | 
			
		||||
            m_log.Info("[MSSQLAssetData]: " + Name + " cannot be default-initialized!");
 | 
			
		||||
            throw new PluginNotInitialisedException(Name);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Initialises asset interface
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <para>
 | 
			
		||||
        /// a string instead of file, if someone writes the support
 | 
			
		||||
        /// </para>
 | 
			
		||||
        /// <param name="connectionString">connect string</param>
 | 
			
		||||
        override public void Initialise(string connectionString)
 | 
			
		||||
        {
 | 
			
		||||
            m_ticksToEpoch = new System.DateTime(1970, 1, 1).Ticks;
 | 
			
		||||
 | 
			
		||||
            m_database = new MSSQLManager(connectionString);
 | 
			
		||||
            m_connectionString = connectionString;
 | 
			
		||||
 | 
			
		||||
            //New migration to check for DB changes
 | 
			
		||||
            m_database.CheckMigration(_migrationStore);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Database provider version.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        override public string Version
 | 
			
		||||
        {
 | 
			
		||||
            get { return m_database.getVersion(); }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// The name of this DB provider.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        override public string Name
 | 
			
		||||
        {
 | 
			
		||||
            get { return "MSSQL Asset storage engine"; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        #endregion
 | 
			
		||||
 | 
			
		||||
        #region IAssetDataPlugin Members
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Fetch Asset from m_database
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="assetID">the asset UUID</param>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        override public AssetBase GetAsset(UUID assetID)
 | 
			
		||||
        {
 | 
			
		||||
            string sql = "SELECT * FROM assets WHERE id = @id";
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_connectionString))
 | 
			
		||||
            using (SqlCommand cmd = new SqlCommand(sql, conn))
 | 
			
		||||
            {
 | 
			
		||||
                cmd.Parameters.Add(m_database.CreateParameter("id", assetID));
 | 
			
		||||
                conn.Open();
 | 
			
		||||
                using (SqlDataReader reader = cmd.ExecuteReader())
 | 
			
		||||
                {
 | 
			
		||||
                    if (reader.Read())
 | 
			
		||||
                    {
 | 
			
		||||
                        AssetBase asset = new AssetBase(
 | 
			
		||||
                            DBGuid.FromDB(reader["id"]),
 | 
			
		||||
                            (string)reader["name"],
 | 
			
		||||
                            Convert.ToSByte(reader["assetType"]),
 | 
			
		||||
                            reader["creatorid"].ToString()
 | 
			
		||||
                        );
 | 
			
		||||
                        // Region Main
 | 
			
		||||
                        asset.Description = (string)reader["description"];
 | 
			
		||||
                        asset.Local = Convert.ToBoolean(reader["local"]);
 | 
			
		||||
                        asset.Temporary = Convert.ToBoolean(reader["temporary"]);
 | 
			
		||||
                        asset.Flags = (AssetFlags)(Convert.ToInt32(reader["asset_flags"]));
 | 
			
		||||
                        asset.Data = (byte[])reader["data"];
 | 
			
		||||
                        return asset;
 | 
			
		||||
                    }
 | 
			
		||||
                    return null; // throw new Exception("No rows to return");
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Create asset in m_database
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="asset">the asset</param>
 | 
			
		||||
        override public void StoreAsset(AssetBase asset)
 | 
			
		||||
        {
 | 
			
		||||
           
 | 
			
		||||
            string sql =
 | 
			
		||||
                @"IF EXISTS(SELECT * FROM assets WHERE id=@id) 
 | 
			
		||||
                    UPDATE assets set name = @name, description = @description, assetType = @assetType,
 | 
			
		||||
                            local = @local, temporary = @temporary, creatorid = @creatorid, data = @data
 | 
			
		||||
                           WHERE id=@id
 | 
			
		||||
                   ELSE
 | 
			
		||||
                    INSERT INTO assets
 | 
			
		||||
                    ([id], [name], [description], [assetType], [local], 
 | 
			
		||||
                     [temporary], [create_time], [access_time], [creatorid], [asset_flags], [data])
 | 
			
		||||
                    VALUES
 | 
			
		||||
                    (@id, @name, @description, @assetType, @local, 
 | 
			
		||||
                     @temporary, @create_time, @access_time, @creatorid, @asset_flags, @data)";
 | 
			
		||||
            
 | 
			
		||||
            string assetName = asset.Name;
 | 
			
		||||
            if (asset.Name.Length > 64)
 | 
			
		||||
            {
 | 
			
		||||
                assetName = asset.Name.Substring(0, 64);
 | 
			
		||||
                m_log.WarnFormat(
 | 
			
		||||
                    "[ASSET DB]: Name '{0}' for asset {1} truncated from {2} to {3} characters on add", 
 | 
			
		||||
                    asset.Name, asset.ID, asset.Name.Length, assetName.Length);
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            string assetDescription = asset.Description;
 | 
			
		||||
            if (asset.Description.Length > 64)
 | 
			
		||||
            {
 | 
			
		||||
                assetDescription = asset.Description.Substring(0, 64);
 | 
			
		||||
                m_log.WarnFormat(
 | 
			
		||||
                    "[ASSET DB]: Description '{0}' for asset {1} truncated from {2} to {3} characters on add", 
 | 
			
		||||
                    asset.Description, asset.ID, asset.Description.Length, assetDescription.Length);
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_connectionString))
 | 
			
		||||
            using (SqlCommand command = new SqlCommand(sql, conn))
 | 
			
		||||
            {
 | 
			
		||||
                int now = (int)((System.DateTime.Now.Ticks - m_ticksToEpoch) / 10000000);
 | 
			
		||||
                command.Parameters.Add(m_database.CreateParameter("id", asset.FullID));
 | 
			
		||||
                command.Parameters.Add(m_database.CreateParameter("name", assetName));
 | 
			
		||||
                command.Parameters.Add(m_database.CreateParameter("description", assetDescription));
 | 
			
		||||
                command.Parameters.Add(m_database.CreateParameter("assetType", asset.Type));
 | 
			
		||||
                command.Parameters.Add(m_database.CreateParameter("local", asset.Local));
 | 
			
		||||
                command.Parameters.Add(m_database.CreateParameter("temporary", asset.Temporary));
 | 
			
		||||
                command.Parameters.Add(m_database.CreateParameter("access_time", now));
 | 
			
		||||
                command.Parameters.Add(m_database.CreateParameter("create_time", now));
 | 
			
		||||
                command.Parameters.Add(m_database.CreateParameter("asset_flags", (int)asset.Flags));
 | 
			
		||||
                command.Parameters.Add(m_database.CreateParameter("creatorid", asset.Metadata.CreatorID));
 | 
			
		||||
                command.Parameters.Add(m_database.CreateParameter("data", asset.Data));
 | 
			
		||||
                conn.Open();
 | 
			
		||||
                try
 | 
			
		||||
                {
 | 
			
		||||
                    command.ExecuteNonQuery();
 | 
			
		||||
                }
 | 
			
		||||
                catch(Exception e)
 | 
			
		||||
                {
 | 
			
		||||
                    m_log.Error("[ASSET DB]: Error storing item :" + e.Message);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Commented out since currently unused - this probably should be called in GetAsset()
 | 
			
		||||
//        private void UpdateAccessTime(AssetBase asset)
 | 
			
		||||
//        {
 | 
			
		||||
//            using (AutoClosingSqlCommand cmd = m_database.Query("UPDATE assets SET access_time = @access_time WHERE id=@id"))
 | 
			
		||||
//            {
 | 
			
		||||
//                int now = (int)((System.DateTime.Now.Ticks - m_ticksToEpoch) / 10000000);
 | 
			
		||||
//                cmd.Parameters.AddWithValue("@id", asset.FullID.ToString());
 | 
			
		||||
//                cmd.Parameters.AddWithValue("@access_time", now);
 | 
			
		||||
//                try
 | 
			
		||||
//                {
 | 
			
		||||
//                    cmd.ExecuteNonQuery();
 | 
			
		||||
//                }
 | 
			
		||||
//                catch (Exception e)
 | 
			
		||||
//                {
 | 
			
		||||
//                    m_log.Error(e.ToString());
 | 
			
		||||
//                }
 | 
			
		||||
//            }
 | 
			
		||||
//        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Check if asset exist in m_database
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="uuid"></param>
 | 
			
		||||
        /// <returns>true if exist.</returns>
 | 
			
		||||
        override public bool ExistsAsset(UUID uuid)
 | 
			
		||||
        {
 | 
			
		||||
            if (GetAsset(uuid) != null)
 | 
			
		||||
            {
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Returns a list of AssetMetadata objects. The list is a subset of
 | 
			
		||||
        /// the entire data set offset by <paramref name="start" /> containing
 | 
			
		||||
        /// <paramref name="count" /> elements.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="start">The number of results to discard from the total data set.</param>
 | 
			
		||||
        /// <param name="count">The number of rows the returned list should contain.</param>
 | 
			
		||||
        /// <returns>A list of AssetMetadata objects.</returns>
 | 
			
		||||
        public override List<AssetMetadata> FetchAssetMetadataSet(int start, int count)
 | 
			
		||||
        {
 | 
			
		||||
            List<AssetMetadata> retList = new List<AssetMetadata>(count);
 | 
			
		||||
            string sql = @"WITH OrderedAssets AS
 | 
			
		||||
                (
 | 
			
		||||
                    SELECT id, name, description, assetType, temporary, creatorid,
 | 
			
		||||
                    RowNumber = ROW_NUMBER() OVER (ORDER BY id)
 | 
			
		||||
                    FROM assets 
 | 
			
		||||
                ) 
 | 
			
		||||
                SELECT * 
 | 
			
		||||
                FROM OrderedAssets
 | 
			
		||||
                WHERE RowNumber BETWEEN @start AND @stop;";
 | 
			
		||||
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_connectionString))
 | 
			
		||||
            using (SqlCommand cmd = new SqlCommand(sql, conn))
 | 
			
		||||
            {
 | 
			
		||||
                cmd.Parameters.Add(m_database.CreateParameter("start", start));
 | 
			
		||||
                cmd.Parameters.Add(m_database.CreateParameter("stop", start + count - 1));
 | 
			
		||||
                conn.Open();
 | 
			
		||||
                using (SqlDataReader reader = cmd.ExecuteReader())
 | 
			
		||||
                {
 | 
			
		||||
                    while (reader.Read())
 | 
			
		||||
                    {
 | 
			
		||||
                        AssetMetadata metadata = new AssetMetadata();
 | 
			
		||||
                        metadata.FullID = DBGuid.FromDB(reader["id"]);
 | 
			
		||||
                        metadata.Name = (string)reader["name"];
 | 
			
		||||
                        metadata.Description = (string)reader["description"];
 | 
			
		||||
                        metadata.Type = Convert.ToSByte(reader["assetType"]);
 | 
			
		||||
                        metadata.Temporary = Convert.ToBoolean(reader["temporary"]);
 | 
			
		||||
                        metadata.CreatorID = (string)reader["creatorid"];
 | 
			
		||||
                        retList.Add(metadata);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return retList;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override bool Delete(string id)
 | 
			
		||||
        {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        #endregion
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,227 @@
 | 
			
		|||
/*
 | 
			
		||||
 * 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.Data;
 | 
			
		||||
using OpenMetaverse;
 | 
			
		||||
using OpenSim.Framework;
 | 
			
		||||
using System.Data.SqlClient;
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
using System.Text;
 | 
			
		||||
 | 
			
		||||
namespace OpenSim.Data.MSSQL
 | 
			
		||||
{
 | 
			
		||||
    public class MSSQLAuthenticationData : IAuthenticationData
 | 
			
		||||
    {
 | 
			
		||||
        private string m_Realm;
 | 
			
		||||
        private List<string> m_ColumnNames = null;
 | 
			
		||||
        private int m_LastExpire = 0;
 | 
			
		||||
        private string m_ConnectionString;
 | 
			
		||||
        private MSSQLManager m_database;
 | 
			
		||||
 | 
			
		||||
        public MSSQLAuthenticationData(string connectionString, string realm)
 | 
			
		||||
        {
 | 
			
		||||
            m_Realm = realm;
 | 
			
		||||
            m_ConnectionString = connectionString;
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_ConnectionString))
 | 
			
		||||
            {
 | 
			
		||||
                conn.Open();
 | 
			
		||||
                Migration m = new Migration(conn, GetType().Assembly, "AuthStore");
 | 
			
		||||
                m_database = new MSSQLManager(m_ConnectionString);
 | 
			
		||||
                m.Update();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public AuthenticationData Get(UUID principalID)
 | 
			
		||||
        {
 | 
			
		||||
            AuthenticationData ret = new AuthenticationData();
 | 
			
		||||
            ret.Data = new Dictionary<string, object>();
 | 
			
		||||
 | 
			
		||||
            string sql = string.Format("select * from {0} where UUID = @principalID", m_Realm);
 | 
			
		||||
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_ConnectionString))
 | 
			
		||||
            using (SqlCommand cmd = new SqlCommand(sql, conn))
 | 
			
		||||
            {
 | 
			
		||||
                cmd.Parameters.Add(m_database.CreateParameter("@principalID", principalID));
 | 
			
		||||
                conn.Open();
 | 
			
		||||
                using (SqlDataReader result = cmd.ExecuteReader())
 | 
			
		||||
                {
 | 
			
		||||
                    if (result.Read())
 | 
			
		||||
                    {
 | 
			
		||||
                        ret.PrincipalID = principalID;
 | 
			
		||||
 | 
			
		||||
                        if (m_ColumnNames == null)
 | 
			
		||||
                        {
 | 
			
		||||
                            m_ColumnNames = new List<string>();
 | 
			
		||||
 | 
			
		||||
                            DataTable schemaTable = result.GetSchemaTable();
 | 
			
		||||
                            foreach (DataRow row in schemaTable.Rows)
 | 
			
		||||
                                m_ColumnNames.Add(row["ColumnName"].ToString());
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        foreach (string s in m_ColumnNames)
 | 
			
		||||
                        {
 | 
			
		||||
                            if (s == "UUID")
 | 
			
		||||
                                continue;
 | 
			
		||||
 | 
			
		||||
                            ret.Data[s] = result[s].ToString();
 | 
			
		||||
                        }
 | 
			
		||||
                        return ret;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool Store(AuthenticationData data)
 | 
			
		||||
        {
 | 
			
		||||
            if (data.Data.ContainsKey("UUID"))
 | 
			
		||||
                data.Data.Remove("UUID");
 | 
			
		||||
 | 
			
		||||
            string[] fields = new List<string>(data.Data.Keys).ToArray();
 | 
			
		||||
            StringBuilder updateBuilder = new StringBuilder();
 | 
			
		||||
           
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_ConnectionString))
 | 
			
		||||
            using (SqlCommand cmd = new SqlCommand())
 | 
			
		||||
            {
 | 
			
		||||
                updateBuilder.AppendFormat("update {0} set ", m_Realm);
 | 
			
		||||
 | 
			
		||||
                bool first = true;
 | 
			
		||||
                foreach (string field in fields)
 | 
			
		||||
                {
 | 
			
		||||
                    if (!first)
 | 
			
		||||
                        updateBuilder.Append(", ");
 | 
			
		||||
                    updateBuilder.AppendFormat("{0} = @{0}",field);
 | 
			
		||||
 | 
			
		||||
                    first = false;
 | 
			
		||||
                    cmd.Parameters.Add(m_database.CreateParameter("@" + field, data.Data[field]));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                updateBuilder.Append(" where UUID = @principalID");
 | 
			
		||||
 | 
			
		||||
                cmd.CommandText = updateBuilder.ToString();
 | 
			
		||||
                cmd.Connection = conn;
 | 
			
		||||
                cmd.Parameters.Add(m_database.CreateParameter("@principalID", data.PrincipalID));
 | 
			
		||||
                
 | 
			
		||||
                conn.Open();
 | 
			
		||||
                if (cmd.ExecuteNonQuery() < 1)
 | 
			
		||||
                {
 | 
			
		||||
                    StringBuilder insertBuilder = new StringBuilder();
 | 
			
		||||
 | 
			
		||||
                    insertBuilder.AppendFormat("insert into {0} (UUID, ", m_Realm);
 | 
			
		||||
                    insertBuilder.Append(String.Join(", ", fields));
 | 
			
		||||
                    insertBuilder.Append(") values (@principalID, @");
 | 
			
		||||
                    insertBuilder.Append(String.Join(", @", fields));
 | 
			
		||||
                    insertBuilder.Append(")");
 | 
			
		||||
 | 
			
		||||
                    cmd.CommandText = insertBuilder.ToString();
 | 
			
		||||
 | 
			
		||||
                    if (cmd.ExecuteNonQuery() < 1)
 | 
			
		||||
                    {
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool SetDataItem(UUID principalID, string item, string value)
 | 
			
		||||
        {
 | 
			
		||||
            string sql = string.Format("update {0} set {1} = @{1} where UUID = @UUID", m_Realm, item);
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_ConnectionString))
 | 
			
		||||
            using (SqlCommand cmd = new SqlCommand(sql, conn))
 | 
			
		||||
            {
 | 
			
		||||
                cmd.Parameters.Add(m_database.CreateParameter("@" + item, value));
 | 
			
		||||
                conn.Open();
 | 
			
		||||
                if (cmd.ExecuteNonQuery() > 0)
 | 
			
		||||
                    return true;
 | 
			
		||||
            }
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool SetToken(UUID principalID, string token, int lifetime)
 | 
			
		||||
        {
 | 
			
		||||
            if (System.Environment.TickCount - m_LastExpire > 30000)
 | 
			
		||||
                DoExpire();
 | 
			
		||||
            
 | 
			
		||||
            string sql = "insert into tokens (UUID, token, validity) values (@principalID, @token, @lifetime)";
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_ConnectionString))
 | 
			
		||||
            using (SqlCommand cmd = new SqlCommand(sql, conn))
 | 
			
		||||
            {
 | 
			
		||||
                cmd.Parameters.Add(m_database.CreateParameter("@principalID", principalID));
 | 
			
		||||
                cmd.Parameters.Add(m_database.CreateParameter("@token", token));
 | 
			
		||||
                cmd.Parameters.Add(m_database.CreateParameter("@lifetime", DateTime.Now.AddMinutes(lifetime)));
 | 
			
		||||
                conn.Open();
 | 
			
		||||
 | 
			
		||||
                if (cmd.ExecuteNonQuery() > 0)
 | 
			
		||||
                {
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool CheckToken(UUID principalID, string token, int lifetime)
 | 
			
		||||
        {
 | 
			
		||||
            if (System.Environment.TickCount - m_LastExpire > 30000)
 | 
			
		||||
                DoExpire();
 | 
			
		||||
 | 
			
		||||
            DateTime validDate = DateTime.Now.AddMinutes(lifetime);
 | 
			
		||||
            string sql = "update tokens set validity = @validDate where UUID = @principalID and token = @token and validity > GetDate()";
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_ConnectionString))
 | 
			
		||||
            using (SqlCommand cmd = new SqlCommand(sql, conn))
 | 
			
		||||
            {
 | 
			
		||||
                cmd.Parameters.Add(m_database.CreateParameter("@principalID", principalID));
 | 
			
		||||
                cmd.Parameters.Add(m_database.CreateParameter("@token", token));
 | 
			
		||||
                cmd.Parameters.Add(m_database.CreateParameter("@validDate", validDate));
 | 
			
		||||
                conn.Open();
 | 
			
		||||
 | 
			
		||||
                if (cmd.ExecuteNonQuery() > 0)
 | 
			
		||||
                {
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void DoExpire()
 | 
			
		||||
        {
 | 
			
		||||
            DateTime currentDateTime = DateTime.Now;
 | 
			
		||||
            string sql = "delete from tokens where validity < @currentDateTime";
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_ConnectionString))
 | 
			
		||||
            using (SqlCommand cmd = new SqlCommand(sql, conn))
 | 
			
		||||
            {
 | 
			
		||||
                conn.Open();
 | 
			
		||||
                cmd.Parameters.Add(m_database.CreateParameter("@currentDateTime", currentDateTime));
 | 
			
		||||
                cmd.ExecuteNonQuery();
 | 
			
		||||
            }
 | 
			
		||||
            m_LastExpire = System.Environment.TickCount;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -25,50 +25,47 @@
 | 
			
		|||
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
using Nini.Config;
 | 
			
		||||
using log4net;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Data;
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Net;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Text.RegularExpressions;
 | 
			
		||||
using System.Xml;
 | 
			
		||||
using System.Xml.Serialization;
 | 
			
		||||
using OpenSim.Server.Base;
 | 
			
		||||
using OpenSim.Services.Interfaces;
 | 
			
		||||
using System.Threading;
 | 
			
		||||
using log4net;
 | 
			
		||||
using OpenMetaverse;
 | 
			
		||||
using OpenSim.Framework;
 | 
			
		||||
using OpenSim.Framework.ServiceAuth;
 | 
			
		||||
using OpenSim.Framework.Servers.HttpServer;
 | 
			
		||||
using System.Data.SqlClient;
 | 
			
		||||
 | 
			
		||||
namespace OpenSim.Server.Handlers.BakedTextures
 | 
			
		||||
namespace OpenSim.Data.MSSQL
 | 
			
		||||
{
 | 
			
		||||
    public class BakesServerPostHandler : BaseStreamHandler
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// A MSSQL Interface for Avatar Storage
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class MSSQLAvatarData : MSSQLGenericTableHandler<AvatarBaseData>,
 | 
			
		||||
            IAvatarData
 | 
			
		||||
    {
 | 
			
		||||
//        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 | 
			
		||||
        
 | 
			
		||||
        private IBakedTextureService m_BakesService;
 | 
			
		||||
 | 
			
		||||
        public BakesServerPostHandler(IBakedTextureService service, IServiceAuth auth) :
 | 
			
		||||
                base("POST", "/bakes", auth)
 | 
			
		||||
        public MSSQLAvatarData(string connectionString, string realm) :
 | 
			
		||||
                base(connectionString, realm, "Avatar")
 | 
			
		||||
        {
 | 
			
		||||
            m_BakesService = service;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected override byte[] ProcessRequest(
 | 
			
		||||
            string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
 | 
			
		||||
        public bool Delete(UUID principalID, string name)
 | 
			
		||||
        {
 | 
			
		||||
            string[] p = SplitParams(path);
 | 
			
		||||
 | 
			
		||||
            if (p.Length == 0)
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_ConnectionString))
 | 
			
		||||
            using (SqlCommand cmd = new SqlCommand())
 | 
			
		||||
            {
 | 
			
		||||
                return new byte[0];
 | 
			
		||||
 | 
			
		||||
                cmd.CommandText = String.Format("DELETE FROM {0} where [PrincipalID] = @PrincipalID and [Name] = @Name", m_Realm);
 | 
			
		||||
                cmd.Parameters.Add(m_database.CreateParameter("@PrincipalID", principalID.ToString()));
 | 
			
		||||
                cmd.Parameters.Add(m_database.CreateParameter("@Name", name));
 | 
			
		||||
                cmd.Connection = conn;
 | 
			
		||||
                conn.Open();
 | 
			
		||||
                if (cmd.ExecuteNonQuery() > 0)
 | 
			
		||||
                    return true;
 | 
			
		||||
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            using(StreamReader sr = new StreamReader(request))
 | 
			
		||||
                m_BakesService.Store(p[0],sr.ReadToEnd());
 | 
			
		||||
 | 
			
		||||
            return new byte[0];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,577 @@
 | 
			
		|||
/*
 | 
			
		||||
 * 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.Data;
 | 
			
		||||
using System.Data.SqlClient;
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
using log4net;
 | 
			
		||||
using OpenMetaverse;
 | 
			
		||||
using OpenSim.Framework;
 | 
			
		||||
using OpenSim.Region.Framework.Interfaces;
 | 
			
		||||
 | 
			
		||||
namespace OpenSim.Data.MSSQL
 | 
			
		||||
{
 | 
			
		||||
    public class MSSQLEstateStore : IEstateDataStore
 | 
			
		||||
    {
 | 
			
		||||
        private const string _migrationStore = "EstateStore";
 | 
			
		||||
 | 
			
		||||
        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 | 
			
		||||
 | 
			
		||||
        private MSSQLManager _Database;
 | 
			
		||||
        private string m_connectionString;
 | 
			
		||||
        private FieldInfo[] _Fields;
 | 
			
		||||
        private Dictionary<string, FieldInfo> _FieldMap = new Dictionary<string, FieldInfo>();
 | 
			
		||||
 | 
			
		||||
        #region Public methods
 | 
			
		||||
 | 
			
		||||
        public MSSQLEstateStore()
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public MSSQLEstateStore(string connectionString)
 | 
			
		||||
        {
 | 
			
		||||
            Initialise(connectionString);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Initialises the estatedata class.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="connectionString">connectionString.</param>
 | 
			
		||||
        public void Initialise(string connectionString)
 | 
			
		||||
        {
 | 
			
		||||
            if (!string.IsNullOrEmpty(connectionString))
 | 
			
		||||
            {
 | 
			
		||||
                m_connectionString = connectionString;
 | 
			
		||||
                _Database = new MSSQLManager(connectionString);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            //Migration settings
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_connectionString))
 | 
			
		||||
            {
 | 
			
		||||
                conn.Open();
 | 
			
		||||
                Migration m = new Migration(conn, GetType().Assembly, "EstateStore");
 | 
			
		||||
                m.Update();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            //Interesting way to get parameters! Maybe implement that also with other types
 | 
			
		||||
            Type t = typeof(EstateSettings);
 | 
			
		||||
            _Fields = t.GetFields(BindingFlags.NonPublic |
 | 
			
		||||
                                  BindingFlags.Instance |
 | 
			
		||||
                                  BindingFlags.DeclaredOnly);
 | 
			
		||||
 | 
			
		||||
            foreach (FieldInfo f in _Fields)
 | 
			
		||||
            {
 | 
			
		||||
                if (f.Name.Substring(0, 2) == "m_")
 | 
			
		||||
                    _FieldMap[f.Name.Substring(2)] = f;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Loads the estate settings.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="regionID">region ID.</param>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        public EstateSettings LoadEstateSettings(UUID regionID, bool create)
 | 
			
		||||
        {
 | 
			
		||||
            EstateSettings es = new EstateSettings();
 | 
			
		||||
 | 
			
		||||
            string sql = "select estate_settings." + String.Join(",estate_settings.", FieldList) + " from estate_map left join estate_settings on estate_map.EstateID = estate_settings.EstateID where estate_settings.EstateID is not null and RegionID = @RegionID";
 | 
			
		||||
 | 
			
		||||
            bool insertEstate = false;
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_connectionString))
 | 
			
		||||
            using (SqlCommand cmd = new SqlCommand(sql, conn))
 | 
			
		||||
            {
 | 
			
		||||
                cmd.Parameters.Add(_Database.CreateParameter("@RegionID", regionID));
 | 
			
		||||
                conn.Open();
 | 
			
		||||
                using (SqlDataReader reader = cmd.ExecuteReader())
 | 
			
		||||
                {
 | 
			
		||||
                    if (reader.Read())
 | 
			
		||||
                    {
 | 
			
		||||
                        foreach (string name in FieldList)
 | 
			
		||||
                        {
 | 
			
		||||
                            FieldInfo f = _FieldMap[name];
 | 
			
		||||
                            object v = reader[name];
 | 
			
		||||
                            if (f.FieldType == typeof(bool))
 | 
			
		||||
                            {
 | 
			
		||||
                                f.SetValue(es, Convert.ToInt32(v) != 0);
 | 
			
		||||
                            }
 | 
			
		||||
                            else if (f.FieldType == typeof(UUID))
 | 
			
		||||
                            {
 | 
			
		||||
                                f.SetValue(es, new UUID((Guid)v)); // uuid);
 | 
			
		||||
                            }
 | 
			
		||||
                            else if (f.FieldType == typeof(string))
 | 
			
		||||
                            {
 | 
			
		||||
                                f.SetValue(es, v.ToString());
 | 
			
		||||
                            }
 | 
			
		||||
                            else if (f.FieldType == typeof(UInt32))
 | 
			
		||||
                            {
 | 
			
		||||
                                f.SetValue(es, Convert.ToUInt32(v));
 | 
			
		||||
                            }
 | 
			
		||||
                            else if (f.FieldType == typeof(Single))
 | 
			
		||||
                            {
 | 
			
		||||
                                f.SetValue(es, Convert.ToSingle(v));
 | 
			
		||||
                            }
 | 
			
		||||
                            else
 | 
			
		||||
                                f.SetValue(es, v);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        insertEstate = true;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (insertEstate && create)
 | 
			
		||||
            {
 | 
			
		||||
                DoCreate(es);
 | 
			
		||||
                LinkRegion(regionID, (int)es.EstateID);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            LoadBanList(es);
 | 
			
		||||
 | 
			
		||||
            es.EstateManagers = LoadUUIDList(es.EstateID, "estate_managers");
 | 
			
		||||
            es.EstateAccess = LoadUUIDList(es.EstateID, "estate_users");
 | 
			
		||||
            es.EstateGroups = LoadUUIDList(es.EstateID, "estate_groups");
 | 
			
		||||
 | 
			
		||||
            //Set event
 | 
			
		||||
            es.OnSave += StoreEstateSettings;
 | 
			
		||||
            return es;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public EstateSettings CreateNewEstate()
 | 
			
		||||
        {
 | 
			
		||||
            EstateSettings es = new EstateSettings();
 | 
			
		||||
            es.OnSave += StoreEstateSettings;
 | 
			
		||||
 | 
			
		||||
            DoCreate(es);
 | 
			
		||||
 | 
			
		||||
            LoadBanList(es);
 | 
			
		||||
 | 
			
		||||
            es.EstateManagers = LoadUUIDList(es.EstateID, "estate_managers");
 | 
			
		||||
            es.EstateAccess = LoadUUIDList(es.EstateID, "estate_users");
 | 
			
		||||
            es.EstateGroups = LoadUUIDList(es.EstateID, "estate_groups");
 | 
			
		||||
 | 
			
		||||
            return es;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void DoCreate(EstateSettings es)
 | 
			
		||||
        {
 | 
			
		||||
            List<string> names = new List<string>(FieldList);
 | 
			
		||||
 | 
			
		||||
            names.Remove("EstateID");
 | 
			
		||||
 | 
			
		||||
            string sql = string.Format("insert into estate_settings ({0}) values ( @{1})", String.Join(",", names.ToArray()), String.Join(", @", names.ToArray()));
 | 
			
		||||
 | 
			
		||||
            //_Log.Debug("[DB ESTATE]: SQL: " + sql);
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_connectionString))
 | 
			
		||||
            using (SqlCommand insertCommand = new SqlCommand(sql, conn))
 | 
			
		||||
            {
 | 
			
		||||
                insertCommand.CommandText = sql + " SET @ID = SCOPE_IDENTITY()";
 | 
			
		||||
 | 
			
		||||
                foreach (string name in names)
 | 
			
		||||
                {
 | 
			
		||||
                    insertCommand.Parameters.Add(_Database.CreateParameter("@" + name, _FieldMap[name].GetValue(es)));
 | 
			
		||||
                }
 | 
			
		||||
                SqlParameter idParameter = new SqlParameter("@ID", SqlDbType.Int);
 | 
			
		||||
                idParameter.Direction = ParameterDirection.Output;
 | 
			
		||||
                insertCommand.Parameters.Add(idParameter);
 | 
			
		||||
                conn.Open();
 | 
			
		||||
                insertCommand.ExecuteNonQuery();
 | 
			
		||||
 | 
			
		||||
                es.EstateID = Convert.ToUInt32(idParameter.Value);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            //TODO check if this is needed??
 | 
			
		||||
            es.Save();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Stores the estate settings.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="es">estate settings</param>
 | 
			
		||||
        public void StoreEstateSettings(EstateSettings es)
 | 
			
		||||
        {
 | 
			
		||||
            List<string> names = new List<string>(FieldList);
 | 
			
		||||
 | 
			
		||||
            names.Remove("EstateID");
 | 
			
		||||
 | 
			
		||||
            string sql = string.Format("UPDATE estate_settings SET ");
 | 
			
		||||
            foreach (string name in names)
 | 
			
		||||
            {
 | 
			
		||||
                sql += name + " = @" + name + ", ";
 | 
			
		||||
            }
 | 
			
		||||
            sql = sql.Remove(sql.LastIndexOf(","));
 | 
			
		||||
            sql += " WHERE EstateID = @EstateID";
 | 
			
		||||
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_connectionString))
 | 
			
		||||
            using (SqlCommand cmd = new SqlCommand(sql, conn))
 | 
			
		||||
            {
 | 
			
		||||
                foreach (string name in names)
 | 
			
		||||
                {
 | 
			
		||||
                    cmd.Parameters.Add(_Database.CreateParameter("@" + name, _FieldMap[name].GetValue(es)));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                cmd.Parameters.Add(_Database.CreateParameter("@EstateID", es.EstateID));
 | 
			
		||||
                conn.Open();
 | 
			
		||||
                cmd.ExecuteNonQuery();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            SaveBanList(es);
 | 
			
		||||
            SaveUUIDList(es.EstateID, "estate_managers", es.EstateManagers);
 | 
			
		||||
            SaveUUIDList(es.EstateID, "estate_users", es.EstateAccess);
 | 
			
		||||
            SaveUUIDList(es.EstateID, "estate_groups", es.EstateGroups);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        #endregion
 | 
			
		||||
 | 
			
		||||
        #region Private methods
 | 
			
		||||
 | 
			
		||||
        private string[] FieldList
 | 
			
		||||
        {
 | 
			
		||||
            get { return new List<string>(_FieldMap.Keys).ToArray(); }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void LoadBanList(EstateSettings es)
 | 
			
		||||
        {
 | 
			
		||||
            es.ClearBans();
 | 
			
		||||
 | 
			
		||||
            string sql = "select bannedUUID from estateban where EstateID = @EstateID";
 | 
			
		||||
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_connectionString))
 | 
			
		||||
            using (SqlCommand cmd = new SqlCommand(sql, conn))
 | 
			
		||||
            {
 | 
			
		||||
                SqlParameter idParameter = new SqlParameter("@EstateID", SqlDbType.Int);
 | 
			
		||||
                idParameter.Value = es.EstateID;
 | 
			
		||||
                cmd.Parameters.Add(idParameter);
 | 
			
		||||
                conn.Open();
 | 
			
		||||
                using (SqlDataReader reader = cmd.ExecuteReader())
 | 
			
		||||
                {
 | 
			
		||||
                    while (reader.Read())
 | 
			
		||||
                    {
 | 
			
		||||
                        EstateBan eb = new EstateBan();
 | 
			
		||||
 | 
			
		||||
                        eb.BannedUserID = new UUID((Guid)reader["bannedUUID"]); //uuid;
 | 
			
		||||
                        eb.BannedHostAddress = "0.0.0.0";
 | 
			
		||||
                        eb.BannedHostIPMask = "0.0.0.0";
 | 
			
		||||
                        es.AddBan(eb);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private UUID[] LoadUUIDList(uint estateID, string table)
 | 
			
		||||
        {
 | 
			
		||||
            List<UUID> uuids = new List<UUID>();
 | 
			
		||||
 | 
			
		||||
            string sql = string.Format("select uuid from {0} where EstateID = @EstateID", table);
 | 
			
		||||
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_connectionString))
 | 
			
		||||
            using (SqlCommand cmd = new SqlCommand(sql, conn))
 | 
			
		||||
            {
 | 
			
		||||
                cmd.Parameters.Add(_Database.CreateParameter("@EstateID", estateID));
 | 
			
		||||
                conn.Open();
 | 
			
		||||
                using (SqlDataReader reader = cmd.ExecuteReader())
 | 
			
		||||
                {
 | 
			
		||||
                    while (reader.Read())
 | 
			
		||||
                    {
 | 
			
		||||
                        uuids.Add(new UUID((Guid)reader["uuid"])); //uuid);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return uuids.ToArray();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void SaveBanList(EstateSettings es)
 | 
			
		||||
        {
 | 
			
		||||
            //Delete first
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_connectionString))
 | 
			
		||||
            {
 | 
			
		||||
                conn.Open();
 | 
			
		||||
                using (SqlCommand cmd = conn.CreateCommand())
 | 
			
		||||
                {
 | 
			
		||||
                    cmd.CommandText = "delete from estateban where EstateID = @EstateID";
 | 
			
		||||
                    cmd.Parameters.AddWithValue("@EstateID", (int)es.EstateID);
 | 
			
		||||
                    cmd.ExecuteNonQuery();
 | 
			
		||||
 | 
			
		||||
                    //Insert after
 | 
			
		||||
                    cmd.CommandText = "insert into estateban (EstateID, bannedUUID,bannedIp, bannedIpHostMask, bannedNameMask) values ( @EstateID, @bannedUUID, '','','' )";
 | 
			
		||||
                    cmd.Parameters.AddWithValue("@bannedUUID", Guid.Empty);
 | 
			
		||||
                    foreach (EstateBan b in es.EstateBans)
 | 
			
		||||
                    {
 | 
			
		||||
                        cmd.Parameters["@bannedUUID"].Value = b.BannedUserID.Guid;
 | 
			
		||||
                        cmd.ExecuteNonQuery();
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void SaveUUIDList(uint estateID, string table, UUID[] data)
 | 
			
		||||
        {
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_connectionString))
 | 
			
		||||
            {
 | 
			
		||||
                conn.Open();
 | 
			
		||||
                using (SqlCommand cmd = conn.CreateCommand())
 | 
			
		||||
                {
 | 
			
		||||
                    cmd.Parameters.AddWithValue("@EstateID", (int)estateID);
 | 
			
		||||
                    cmd.CommandText = string.Format("delete from {0} where EstateID = @EstateID", table);
 | 
			
		||||
                    cmd.ExecuteNonQuery();
 | 
			
		||||
 | 
			
		||||
                    cmd.CommandText = string.Format("insert into {0} (EstateID, uuid) values ( @EstateID, @uuid )", table);
 | 
			
		||||
                    cmd.Parameters.AddWithValue("@uuid", Guid.Empty);
 | 
			
		||||
                    foreach (UUID uuid in data)
 | 
			
		||||
                    {
 | 
			
		||||
                        cmd.Parameters["@uuid"].Value = uuid.Guid; //.ToString(); //TODO check if this works
 | 
			
		||||
                        cmd.ExecuteNonQuery();
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public EstateSettings LoadEstateSettings(int estateID)
 | 
			
		||||
        {
 | 
			
		||||
            EstateSettings es = new EstateSettings();
 | 
			
		||||
            string sql = "select estate_settings." + String.Join(",estate_settings.", FieldList) + " from estate_settings where EstateID = @EstateID";
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_connectionString))
 | 
			
		||||
            {
 | 
			
		||||
                conn.Open();
 | 
			
		||||
                using (SqlCommand cmd = new SqlCommand(sql, conn))
 | 
			
		||||
                {
 | 
			
		||||
                    cmd.Parameters.AddWithValue("@EstateID", (int)estateID);
 | 
			
		||||
                    using (SqlDataReader reader = cmd.ExecuteReader())
 | 
			
		||||
                    {
 | 
			
		||||
                        if (reader.Read())
 | 
			
		||||
                        {
 | 
			
		||||
                            foreach (string name in FieldList)
 | 
			
		||||
                            {
 | 
			
		||||
                                FieldInfo f = _FieldMap[name];
 | 
			
		||||
                                object v = reader[name];
 | 
			
		||||
                                if (f.FieldType == typeof(bool))
 | 
			
		||||
                                {
 | 
			
		||||
                                    f.SetValue(es, Convert.ToInt32(v) != 0);
 | 
			
		||||
                                }
 | 
			
		||||
                                else if (f.FieldType == typeof(UUID))
 | 
			
		||||
                                {
 | 
			
		||||
                                    f.SetValue(es, new UUID((Guid)v)); // uuid);
 | 
			
		||||
                                }
 | 
			
		||||
                                else if (f.FieldType == typeof(string))
 | 
			
		||||
                                {
 | 
			
		||||
                                    f.SetValue(es, v.ToString());
 | 
			
		||||
                                }
 | 
			
		||||
                                else if (f.FieldType == typeof(UInt32))
 | 
			
		||||
                                {
 | 
			
		||||
                                    f.SetValue(es, Convert.ToUInt32(v));
 | 
			
		||||
                                }
 | 
			
		||||
                                else if (f.FieldType == typeof(Single))
 | 
			
		||||
                                {
 | 
			
		||||
                                    f.SetValue(es, Convert.ToSingle(v));
 | 
			
		||||
                                }
 | 
			
		||||
                                else
 | 
			
		||||
                                    f.SetValue(es, v);
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            LoadBanList(es);
 | 
			
		||||
 | 
			
		||||
            es.EstateManagers = LoadUUIDList(es.EstateID, "estate_managers");
 | 
			
		||||
            es.EstateAccess = LoadUUIDList(es.EstateID, "estate_users");
 | 
			
		||||
            es.EstateGroups = LoadUUIDList(es.EstateID, "estate_groups");
 | 
			
		||||
 | 
			
		||||
            //Set event
 | 
			
		||||
            es.OnSave += StoreEstateSettings;
 | 
			
		||||
            return es;
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public List<EstateSettings> LoadEstateSettingsAll()
 | 
			
		||||
        {
 | 
			
		||||
            List<EstateSettings> allEstateSettings = new List<EstateSettings>();
 | 
			
		||||
 | 
			
		||||
            List<int> allEstateIds = GetEstatesAll();
 | 
			
		||||
 | 
			
		||||
            foreach (int estateId in allEstateIds)
 | 
			
		||||
                allEstateSettings.Add(LoadEstateSettings(estateId));
 | 
			
		||||
 | 
			
		||||
            return allEstateSettings;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public List<int> GetEstates(string search)
 | 
			
		||||
        {
 | 
			
		||||
            List<int> result = new List<int>();
 | 
			
		||||
            string sql = "select estateID from estate_settings where EstateName = @EstateName";
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_connectionString))
 | 
			
		||||
            {
 | 
			
		||||
                conn.Open();
 | 
			
		||||
                using (SqlCommand cmd = new SqlCommand(sql, conn))
 | 
			
		||||
                {
 | 
			
		||||
                    cmd.Parameters.AddWithValue("@EstateName", search);
 | 
			
		||||
 | 
			
		||||
                    using (IDataReader reader = cmd.ExecuteReader())
 | 
			
		||||
                    {
 | 
			
		||||
                        while (reader.Read())
 | 
			
		||||
                        {
 | 
			
		||||
                            result.Add(Convert.ToInt32(reader["EstateID"]));
 | 
			
		||||
                        }
 | 
			
		||||
                        reader.Close();
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return result;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public List<int> GetEstatesAll()
 | 
			
		||||
        {
 | 
			
		||||
            List<int> result = new List<int>();
 | 
			
		||||
            string sql = "select estateID from estate_settings";
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_connectionString))
 | 
			
		||||
            {
 | 
			
		||||
                conn.Open();
 | 
			
		||||
                using (SqlCommand cmd = new SqlCommand(sql, conn))
 | 
			
		||||
                {
 | 
			
		||||
                    using (IDataReader reader = cmd.ExecuteReader())
 | 
			
		||||
                    {
 | 
			
		||||
                        while (reader.Read())
 | 
			
		||||
                        {
 | 
			
		||||
                            result.Add(Convert.ToInt32(reader["EstateID"]));
 | 
			
		||||
                        }
 | 
			
		||||
                        reader.Close();
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return result;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public List<int> GetEstatesByOwner(UUID ownerID)
 | 
			
		||||
        {
 | 
			
		||||
            List<int> result = new List<int>();
 | 
			
		||||
            string sql = "select estateID from estate_settings where EstateOwner = @EstateOwner";
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_connectionString))
 | 
			
		||||
            {
 | 
			
		||||
                conn.Open();
 | 
			
		||||
                using (SqlCommand cmd = new SqlCommand(sql, conn))
 | 
			
		||||
                {
 | 
			
		||||
                    cmd.Parameters.AddWithValue("@EstateOwner", ownerID);
 | 
			
		||||
 | 
			
		||||
                    using (IDataReader reader = cmd.ExecuteReader())
 | 
			
		||||
                    {
 | 
			
		||||
                        while (reader.Read())
 | 
			
		||||
                        {
 | 
			
		||||
                            result.Add(Convert.ToInt32(reader["EstateID"]));
 | 
			
		||||
                        }
 | 
			
		||||
                        reader.Close();
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return result;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool LinkRegion(UUID regionID, int estateID)
 | 
			
		||||
        {
 | 
			
		||||
            string deleteSQL = "delete from estate_map where RegionID = @RegionID";
 | 
			
		||||
            string insertSQL = "insert into estate_map values (@RegionID, @EstateID)";
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_connectionString))
 | 
			
		||||
            {
 | 
			
		||||
                conn.Open();
 | 
			
		||||
                SqlTransaction transaction = conn.BeginTransaction();
 | 
			
		||||
 | 
			
		||||
                try
 | 
			
		||||
                {
 | 
			
		||||
                    using (SqlCommand cmd = new SqlCommand(deleteSQL, conn))
 | 
			
		||||
                    {
 | 
			
		||||
                        cmd.Transaction = transaction;
 | 
			
		||||
                        cmd.Parameters.AddWithValue("@RegionID", regionID.Guid);
 | 
			
		||||
 | 
			
		||||
                        cmd.ExecuteNonQuery();
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    using (SqlCommand cmd = new SqlCommand(insertSQL, conn))
 | 
			
		||||
                    {
 | 
			
		||||
                        cmd.Transaction = transaction;
 | 
			
		||||
                        cmd.Parameters.AddWithValue("@RegionID", regionID.Guid);
 | 
			
		||||
                        cmd.Parameters.AddWithValue("@EstateID", estateID);
 | 
			
		||||
 | 
			
		||||
                        int ret = cmd.ExecuteNonQuery();
 | 
			
		||||
 | 
			
		||||
                        if (ret != 0)
 | 
			
		||||
                            transaction.Commit();
 | 
			
		||||
                        else
 | 
			
		||||
                            transaction.Rollback();
 | 
			
		||||
 | 
			
		||||
                        return (ret != 0);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                catch (Exception ex)
 | 
			
		||||
                {
 | 
			
		||||
                    m_log.Error("[REGION DB]: LinkRegion failed: " + ex.Message);
 | 
			
		||||
                    transaction.Rollback();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public List<UUID> GetRegions(int estateID)
 | 
			
		||||
        {
 | 
			
		||||
            List<UUID> result = new List<UUID>();
 | 
			
		||||
            string sql = "select RegionID from estate_map where EstateID = @EstateID";
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_connectionString))
 | 
			
		||||
            {
 | 
			
		||||
                conn.Open();
 | 
			
		||||
                using (SqlCommand cmd = new SqlCommand(sql, conn))
 | 
			
		||||
                {
 | 
			
		||||
                    cmd.Parameters.AddWithValue("@EstateID", estateID);
 | 
			
		||||
 | 
			
		||||
                    using (IDataReader reader = cmd.ExecuteReader())
 | 
			
		||||
                    {
 | 
			
		||||
                        while (reader.Read())
 | 
			
		||||
                        {
 | 
			
		||||
                            result.Add(DBGuid.FromDB(reader["RegionID"]));
 | 
			
		||||
                        }
 | 
			
		||||
                        reader.Close();
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return result;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool DeleteEstate(int estateID)
 | 
			
		||||
        {
 | 
			
		||||
            // TODO: Implementation!            
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        #endregion
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,99 @@
 | 
			
		|||
/*
 | 
			
		||||
 * 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.Data;
 | 
			
		||||
using OpenMetaverse;
 | 
			
		||||
using OpenSim.Framework;
 | 
			
		||||
using System.Data.SqlClient;
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
using System.Text;
 | 
			
		||||
 | 
			
		||||
namespace OpenSim.Data.MSSQL
 | 
			
		||||
{
 | 
			
		||||
    public class MSSQLFriendsData : MSSQLGenericTableHandler<FriendsData>, IFriendsData
 | 
			
		||||
    {
 | 
			
		||||
        public MSSQLFriendsData(string connectionString, string realm)
 | 
			
		||||
            : base(connectionString, realm, "FriendsStore")
 | 
			
		||||
        {
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_ConnectionString))
 | 
			
		||||
            {
 | 
			
		||||
                conn.Open();
 | 
			
		||||
                Migration m = new Migration(conn, GetType().Assembly, "FriendsStore");
 | 
			
		||||
                m.Update();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool Delete(UUID principalID, string friend)
 | 
			
		||||
        {
 | 
			
		||||
            return Delete(principalID.ToString(), friend);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool Delete(string principalID, string friend)
 | 
			
		||||
        {
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_ConnectionString))
 | 
			
		||||
            using (SqlCommand cmd = new SqlCommand())
 | 
			
		||||
            {
 | 
			
		||||
                cmd.CommandText = String.Format("delete from {0} where PrincipalID = @PrincipalID and Friend = @Friend", m_Realm);
 | 
			
		||||
                cmd.Parameters.Add(m_database.CreateParameter("@PrincipalID", principalID.ToString()));
 | 
			
		||||
                cmd.Parameters.Add(m_database.CreateParameter("@Friend", friend));
 | 
			
		||||
                cmd.Connection = conn;
 | 
			
		||||
                conn.Open();
 | 
			
		||||
                cmd.ExecuteNonQuery();
 | 
			
		||||
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public FriendsData[] GetFriends(UUID principalID)
 | 
			
		||||
        {
 | 
			
		||||
            return GetFriends(principalID.ToString());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public FriendsData[] GetFriends(string principalID)
 | 
			
		||||
        {
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_ConnectionString))
 | 
			
		||||
            using (SqlCommand cmd = new SqlCommand())
 | 
			
		||||
            {
 | 
			
		||||
 | 
			
		||||
                cmd.CommandText = String.Format("select a.*,case when b.Flags is null then -1 else b.Flags end as TheirFlags from {0} as a left join {0} as b on a.PrincipalID = b.Friend and a.Friend = b.PrincipalID where a.PrincipalID = @PrincipalID", m_Realm);
 | 
			
		||||
                cmd.Parameters.Add(m_database.CreateParameter("@PrincipalID", principalID.ToString()));
 | 
			
		||||
                cmd.Connection = conn;
 | 
			
		||||
                conn.Open();
 | 
			
		||||
                return DoQuery(cmd);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public FriendsData[] GetFriends(Guid principalID)
 | 
			
		||||
        {
 | 
			
		||||
            return GetFriends(principalID.ToString());
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,384 @@
 | 
			
		|||
/*
 | 
			
		||||
 * 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.Data;
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
using log4net;
 | 
			
		||||
using System.Data.SqlClient;
 | 
			
		||||
using OpenMetaverse;
 | 
			
		||||
using OpenSim.Framework;
 | 
			
		||||
using OpenSim.Region.Framework.Interfaces;
 | 
			
		||||
using System.Text;
 | 
			
		||||
 | 
			
		||||
namespace OpenSim.Data.MSSQL
 | 
			
		||||
{
 | 
			
		||||
    public class MSSQLGenericTableHandler<T> where T : class, new()
 | 
			
		||||
    {
 | 
			
		||||
//        private static readonly ILog m_log =
 | 
			
		||||
//            LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 | 
			
		||||
 | 
			
		||||
        protected string m_ConnectionString;
 | 
			
		||||
        protected MSSQLManager m_database; //used for parameter type translation
 | 
			
		||||
        protected Dictionary<string, FieldInfo> m_Fields =
 | 
			
		||||
                new Dictionary<string, FieldInfo>();
 | 
			
		||||
 | 
			
		||||
        protected List<string> m_ColumnNames = null;
 | 
			
		||||
        protected string m_Realm;
 | 
			
		||||
        protected FieldInfo m_DataField = null;
 | 
			
		||||
 | 
			
		||||
        public MSSQLGenericTableHandler(string connectionString,
 | 
			
		||||
                string realm, string storeName)
 | 
			
		||||
        {
 | 
			
		||||
            m_Realm = realm;
 | 
			
		||||
            
 | 
			
		||||
            m_ConnectionString = connectionString;
 | 
			
		||||
 | 
			
		||||
            if (storeName != String.Empty)
 | 
			
		||||
            {
 | 
			
		||||
                using (SqlConnection conn = new SqlConnection(m_ConnectionString))
 | 
			
		||||
                {
 | 
			
		||||
                    conn.Open();
 | 
			
		||||
                    Migration m = new Migration(conn, GetType().Assembly, storeName);
 | 
			
		||||
                    m.Update();
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
            m_database = new MSSQLManager(m_ConnectionString);
 | 
			
		||||
 | 
			
		||||
            Type t = typeof(T);
 | 
			
		||||
            FieldInfo[] fields = t.GetFields(BindingFlags.Public |
 | 
			
		||||
                                             BindingFlags.Instance |
 | 
			
		||||
                                             BindingFlags.DeclaredOnly);
 | 
			
		||||
 | 
			
		||||
            if (fields.Length == 0)
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
            foreach (FieldInfo f in fields)
 | 
			
		||||
            {
 | 
			
		||||
                if (f.Name != "Data")
 | 
			
		||||
                    m_Fields[f.Name] = f;
 | 
			
		||||
                else
 | 
			
		||||
                    m_DataField = f;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void CheckColumnNames(SqlDataReader reader)
 | 
			
		||||
        {
 | 
			
		||||
            if (m_ColumnNames != null)
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
            m_ColumnNames = new List<string>();
 | 
			
		||||
 | 
			
		||||
            DataTable schemaTable = reader.GetSchemaTable();
 | 
			
		||||
            foreach (DataRow row in schemaTable.Rows)
 | 
			
		||||
            {
 | 
			
		||||
                if (row["ColumnName"] != null &&
 | 
			
		||||
                        (!m_Fields.ContainsKey(row["ColumnName"].ToString())))
 | 
			
		||||
                    m_ColumnNames.Add(row["ColumnName"].ToString());
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private List<string> GetConstraints()
 | 
			
		||||
        {
 | 
			
		||||
            List<string> constraints = new List<string>();
 | 
			
		||||
            string query = string.Format(@"SELECT 
 | 
			
		||||
                            COL_NAME(ic.object_id,ic.column_id) AS column_name
 | 
			
		||||
                            FROM sys.indexes AS i
 | 
			
		||||
                            INNER JOIN sys.index_columns AS ic 
 | 
			
		||||
                              ON i.object_id = ic.object_id AND i.index_id = ic.index_id
 | 
			
		||||
                            WHERE i.is_primary_key = 1 
 | 
			
		||||
                            AND i.object_id = OBJECT_ID('{0}');", m_Realm);
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_ConnectionString))
 | 
			
		||||
            using (SqlCommand cmd = new SqlCommand(query, conn))
 | 
			
		||||
            {
 | 
			
		||||
                conn.Open();
 | 
			
		||||
                using (SqlDataReader rdr = cmd.ExecuteReader())
 | 
			
		||||
                {
 | 
			
		||||
                    while (rdr.Read())
 | 
			
		||||
                    {
 | 
			
		||||
                        // query produces 0 to many rows of single column, so always add the first item in each row
 | 
			
		||||
                        constraints.Add((string)rdr[0]);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                return constraints;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public virtual T[] Get(string field, string key)
 | 
			
		||||
        {
 | 
			
		||||
            return Get(new string[] { field }, new string[] { key });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public virtual T[] Get(string[] fields, string[] keys)
 | 
			
		||||
        {
 | 
			
		||||
            if (fields.Length != keys.Length)
 | 
			
		||||
                return new T[0];
 | 
			
		||||
 | 
			
		||||
            List<string> terms = new List<string>();
 | 
			
		||||
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_ConnectionString))
 | 
			
		||||
            using (SqlCommand cmd = new SqlCommand())
 | 
			
		||||
            {
 | 
			
		||||
 | 
			
		||||
                for (int i = 0; i < fields.Length; i++)
 | 
			
		||||
                {
 | 
			
		||||
                    cmd.Parameters.Add(m_database.CreateParameter(fields[i], keys[i]));
 | 
			
		||||
                    terms.Add("[" + fields[i] + "] = @" + fields[i]);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                string where = String.Join(" AND ", terms.ToArray());
 | 
			
		||||
 | 
			
		||||
                string query = String.Format("SELECT * FROM {0} WHERE {1}",
 | 
			
		||||
                        m_Realm, where);
 | 
			
		||||
 | 
			
		||||
                cmd.Connection = conn;
 | 
			
		||||
                cmd.CommandText = query;
 | 
			
		||||
                conn.Open();
 | 
			
		||||
                return DoQuery(cmd);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected T[] DoQuery(SqlCommand cmd)
 | 
			
		||||
        {
 | 
			
		||||
            List<T> result = new List<T>();
 | 
			
		||||
            using (SqlDataReader reader = cmd.ExecuteReader())
 | 
			
		||||
            {
 | 
			
		||||
                if (reader == null)
 | 
			
		||||
                    return new T[0];
 | 
			
		||||
 | 
			
		||||
                CheckColumnNames(reader);                
 | 
			
		||||
 | 
			
		||||
                while (reader.Read())
 | 
			
		||||
                {
 | 
			
		||||
                    T row = new T();
 | 
			
		||||
 | 
			
		||||
                    foreach (string name in m_Fields.Keys)
 | 
			
		||||
                    {
 | 
			
		||||
                        if (m_Fields[name].GetValue(row) is bool)
 | 
			
		||||
                        {
 | 
			
		||||
                            int v = Convert.ToInt32(reader[name]);
 | 
			
		||||
                            m_Fields[name].SetValue(row, v != 0 ? true : false);
 | 
			
		||||
                        }
 | 
			
		||||
                        else if (m_Fields[name].GetValue(row) is UUID)
 | 
			
		||||
                        {
 | 
			
		||||
                            UUID uuid = UUID.Zero;
 | 
			
		||||
 | 
			
		||||
                            UUID.TryParse(reader[name].ToString(), out uuid);
 | 
			
		||||
                            m_Fields[name].SetValue(row, uuid);
 | 
			
		||||
                        }
 | 
			
		||||
                        else if (m_Fields[name].GetValue(row) is int)
 | 
			
		||||
                        {
 | 
			
		||||
                            int v = Convert.ToInt32(reader[name]);
 | 
			
		||||
                            m_Fields[name].SetValue(row, v);
 | 
			
		||||
                        }
 | 
			
		||||
                        else
 | 
			
		||||
                        {
 | 
			
		||||
                            m_Fields[name].SetValue(row, reader[name]);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    if (m_DataField != null)
 | 
			
		||||
                    {
 | 
			
		||||
                        Dictionary<string, string> data =
 | 
			
		||||
                                new Dictionary<string, string>();
 | 
			
		||||
 | 
			
		||||
                        foreach (string col in m_ColumnNames)
 | 
			
		||||
                        {
 | 
			
		||||
                            data[col] = reader[col].ToString();
 | 
			
		||||
                            if (data[col] == null)
 | 
			
		||||
                                data[col] = String.Empty;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        m_DataField.SetValue(row, data);
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    result.Add(row);
 | 
			
		||||
                }
 | 
			
		||||
                return result.ToArray();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public virtual T[] Get(string where)
 | 
			
		||||
        {
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_ConnectionString))
 | 
			
		||||
            using (SqlCommand cmd = new SqlCommand())
 | 
			
		||||
            {
 | 
			
		||||
 | 
			
		||||
                string query = String.Format("SELECT * FROM {0} WHERE {1}",
 | 
			
		||||
                        m_Realm, where);
 | 
			
		||||
                cmd.Connection = conn;
 | 
			
		||||
                cmd.CommandText = query;
 | 
			
		||||
 | 
			
		||||
                //m_log.WarnFormat("[MSSQLGenericTable]: SELECT {0} WHERE {1}", m_Realm, where);
 | 
			
		||||
 | 
			
		||||
                conn.Open();
 | 
			
		||||
                return DoQuery(cmd);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public virtual bool Store(T row)
 | 
			
		||||
        {
 | 
			
		||||
            List<string> constraintFields = GetConstraints();
 | 
			
		||||
            List<KeyValuePair<string, string>> constraints = new List<KeyValuePair<string, string>>();
 | 
			
		||||
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_ConnectionString))
 | 
			
		||||
            using (SqlCommand cmd = new SqlCommand())
 | 
			
		||||
            {
 | 
			
		||||
 | 
			
		||||
                StringBuilder query = new StringBuilder();
 | 
			
		||||
                List<String> names = new List<String>();
 | 
			
		||||
                List<String> values = new List<String>();
 | 
			
		||||
 | 
			
		||||
                foreach (FieldInfo fi in m_Fields.Values)
 | 
			
		||||
                {
 | 
			
		||||
                    names.Add(fi.Name);
 | 
			
		||||
                    values.Add("@" + fi.Name);
 | 
			
		||||
                    // Temporarily return more information about what field is unexpectedly null for
 | 
			
		||||
                    // http://opensimulator.org/mantis/view.php?id=5403.  This might be due to a bug in the 
 | 
			
		||||
                    // InventoryTransferModule or we may be required to substitute a DBNull here.
 | 
			
		||||
                    if (fi.GetValue(row) == null)
 | 
			
		||||
                        throw new NullReferenceException(
 | 
			
		||||
                            string.Format(
 | 
			
		||||
                                "[MSSQL GENERIC TABLE HANDLER]: Trying to store field {0} for {1} which is unexpectedly null",
 | 
			
		||||
                                fi.Name, row));
 | 
			
		||||
 | 
			
		||||
                    if (constraintFields.Count > 0 && constraintFields.Contains(fi.Name))
 | 
			
		||||
                    {
 | 
			
		||||
                        constraints.Add(new KeyValuePair<string, string>(fi.Name, fi.GetValue(row).ToString()));
 | 
			
		||||
                    }
 | 
			
		||||
                    cmd.Parameters.Add(m_database.CreateParameter(fi.Name, fi.GetValue(row).ToString()));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (m_DataField != null)
 | 
			
		||||
                {
 | 
			
		||||
                    Dictionary<string, string> data =
 | 
			
		||||
                            (Dictionary<string, string>)m_DataField.GetValue(row);
 | 
			
		||||
 | 
			
		||||
                    foreach (KeyValuePair<string, string> kvp in data)
 | 
			
		||||
                    {
 | 
			
		||||
                        if (constraintFields.Count > 0 && constraintFields.Contains(kvp.Key))
 | 
			
		||||
                        {
 | 
			
		||||
                            constraints.Add(new KeyValuePair<string, string>(kvp.Key, kvp.Key));
 | 
			
		||||
                        }
 | 
			
		||||
                        names.Add(kvp.Key);
 | 
			
		||||
                        values.Add("@" + kvp.Key);
 | 
			
		||||
                        cmd.Parameters.Add(m_database.CreateParameter("@" + kvp.Key, kvp.Value));
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                query.AppendFormat("UPDATE {0} SET ", m_Realm);
 | 
			
		||||
                int i = 0;
 | 
			
		||||
                for (i = 0; i < names.Count - 1; i++)
 | 
			
		||||
                {
 | 
			
		||||
                    query.AppendFormat("[{0}] = {1}, ", names[i], values[i]);
 | 
			
		||||
                }
 | 
			
		||||
                query.AppendFormat("[{0}] = {1} ", names[i], values[i]);
 | 
			
		||||
                if (constraints.Count > 0)
 | 
			
		||||
                {
 | 
			
		||||
                    List<string> terms = new List<string>();
 | 
			
		||||
                    for (int j = 0; j < constraints.Count; j++)
 | 
			
		||||
                    {
 | 
			
		||||
                        terms.Add(" [" + constraints[j].Key + "] = @" + constraints[j].Key);
 | 
			
		||||
                    }
 | 
			
		||||
                    string where = String.Join(" AND ", terms.ToArray());
 | 
			
		||||
                    query.AppendFormat(" WHERE {0} ", where);
 | 
			
		||||
                    
 | 
			
		||||
                }
 | 
			
		||||
                cmd.Connection = conn;
 | 
			
		||||
                cmd.CommandText = query.ToString();
 | 
			
		||||
                
 | 
			
		||||
                conn.Open();
 | 
			
		||||
                if (cmd.ExecuteNonQuery() > 0)
 | 
			
		||||
                {
 | 
			
		||||
                    //m_log.WarnFormat("[MSSQLGenericTable]: Updating {0}", m_Realm);
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    // assume record has not yet been inserted
 | 
			
		||||
 | 
			
		||||
                    query = new StringBuilder();
 | 
			
		||||
                    query.AppendFormat("INSERT INTO {0} ([", m_Realm);
 | 
			
		||||
                    query.Append(String.Join("],[", names.ToArray()));
 | 
			
		||||
                    query.Append("]) values (" + String.Join(",", values.ToArray()) + ")");
 | 
			
		||||
                    cmd.Connection = conn;
 | 
			
		||||
                    cmd.CommandText = query.ToString();
 | 
			
		||||
                    //m_log.WarnFormat("[MSSQLGenericTable]: Inserting into {0}", m_Realm);
 | 
			
		||||
                    if (conn.State != ConnectionState.Open)
 | 
			
		||||
                        conn.Open();
 | 
			
		||||
                    if (cmd.ExecuteNonQuery() > 0)
 | 
			
		||||
                        return true;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public virtual bool Delete(string field, string key)
 | 
			
		||||
        {
 | 
			
		||||
            return Delete(new string[] { field }, new string[] { key });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public virtual bool Delete(string[] fields, string[] keys)
 | 
			
		||||
        {
 | 
			
		||||
            if (fields.Length != keys.Length)
 | 
			
		||||
                return false;
 | 
			
		||||
 | 
			
		||||
            List<string> terms = new List<string>();
 | 
			
		||||
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_ConnectionString))
 | 
			
		||||
            using (SqlCommand cmd = new SqlCommand())
 | 
			
		||||
            {
 | 
			
		||||
                for (int i = 0; i < fields.Length; i++)
 | 
			
		||||
                {
 | 
			
		||||
                    cmd.Parameters.Add(m_database.CreateParameter(fields[i], keys[i]));
 | 
			
		||||
                    terms.Add("[" + fields[i] + "] = @" + fields[i]);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                string where = String.Join(" AND ", terms.ToArray());
 | 
			
		||||
 | 
			
		||||
                string query = String.Format("DELETE FROM {0} WHERE {1}", m_Realm, where);
 | 
			
		||||
 | 
			
		||||
                cmd.Connection = conn;
 | 
			
		||||
                cmd.CommandText = query;
 | 
			
		||||
                conn.Open();
 | 
			
		||||
 | 
			
		||||
                if (cmd.ExecuteNonQuery() > 0)
 | 
			
		||||
                {
 | 
			
		||||
                    //m_log.Warn("[MSSQLGenericTable]: " + deleteCommand);
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,4 +1,4 @@
 | 
			
		|||
/*
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) Contributors, http://opensimulator.org/
 | 
			
		||||
 * See CONTRIBUTORS.TXT for a full list of copyright holders.
 | 
			
		||||
 *
 | 
			
		||||
| 
						 | 
				
			
			@ -26,29 +26,33 @@
 | 
			
		|||
 */
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Data;
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
using System.Threading;
 | 
			
		||||
using log4net;
 | 
			
		||||
using OpenMetaverse;
 | 
			
		||||
using OpenSim.Framework;
 | 
			
		||||
#if CSharpSqlite
 | 
			
		||||
  using Community.CsharpSqlite.Sqlite;
 | 
			
		||||
#else
 | 
			
		||||
  using Mono.Data.Sqlite;
 | 
			
		||||
#endif
 | 
			
		||||
using System.Data.SqlClient;
 | 
			
		||||
 | 
			
		||||
namespace OpenSim.Data.SQLite
 | 
			
		||||
namespace OpenSim.Data.MSSQL
 | 
			
		||||
{
 | 
			
		||||
    public class SQLiteAgentPreferencesData : SQLiteGenericTableHandler<AgentPreferencesData>, IAgentPreferencesData
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// A MSSQL Interface for Avatar Storage
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class MSSQLGridUserData : MSSQLGenericTableHandler<GridUserData>,
 | 
			
		||||
            IGridUserData
 | 
			
		||||
    {
 | 
			
		||||
        public SQLiteAgentPreferencesData(string connectionString, string realm)
 | 
			
		||||
            : base(connectionString, realm, "AgentPrefs")
 | 
			
		||||
//        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 | 
			
		||||
 | 
			
		||||
        public MSSQLGridUserData(string connectionString, string realm) :
 | 
			
		||||
            base(connectionString, realm, "GridUserStore")
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public AgentPreferencesData GetPrefs(UUID agentID)
 | 
			
		||||
        public new GridUserData Get(string userID)
 | 
			
		||||
        {
 | 
			
		||||
            AgentPreferencesData[] ret = Get("PrincipalID", agentID.ToString());
 | 
			
		||||
            GridUserData[] ret = Get("UserID", userID);
 | 
			
		||||
 | 
			
		||||
            if (ret.Length == 0)
 | 
			
		||||
                return null;
 | 
			
		||||
| 
						 | 
				
			
			@ -56,5 +60,10 @@ namespace OpenSim.Data.SQLite
 | 
			
		|||
            return ret[0];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public GridUserData[] GetAll(string userID)
 | 
			
		||||
        {
 | 
			
		||||
            return base.Get(String.Format("UserID LIKE '{0}%'", userID));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,831 @@
 | 
			
		|||
/*
 | 
			
		||||
 * 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.Data;
 | 
			
		||||
using System.Data.SqlClient;
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
using log4net;
 | 
			
		||||
using OpenMetaverse;
 | 
			
		||||
using OpenSim.Framework;
 | 
			
		||||
 | 
			
		||||
namespace OpenSim.Data.MSSQL
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// A MSSQL interface for the inventory server
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class MSSQLInventoryData : IInventoryDataPlugin
 | 
			
		||||
    {
 | 
			
		||||
        private const string _migrationStore = "InventoryStore";
 | 
			
		||||
 | 
			
		||||
        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// The database manager
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        private MSSQLManager database;
 | 
			
		||||
        private string m_connectionString;
 | 
			
		||||
 | 
			
		||||
        #region IPlugin members
 | 
			
		||||
 | 
			
		||||
        [Obsolete("Cannot be default-initialized!")]
 | 
			
		||||
        public void Initialise()
 | 
			
		||||
        {
 | 
			
		||||
            m_log.Info("[MSSQLInventoryData]: " + Name + " cannot be default-initialized!");
 | 
			
		||||
            throw new PluginNotInitialisedException(Name);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Loads and initialises the MSSQL inventory storage interface
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="connectionString">connect string</param>
 | 
			
		||||
        /// <remarks>use mssql_connection.ini</remarks>
 | 
			
		||||
        public void Initialise(string connectionString)
 | 
			
		||||
        {
 | 
			
		||||
            m_connectionString = connectionString;
 | 
			
		||||
            database = new MSSQLManager(connectionString);
 | 
			
		||||
          
 | 
			
		||||
            //New migrations check of store
 | 
			
		||||
            database.CheckMigration(_migrationStore);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// The name of this DB provider
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <returns>A string containing the name of the DB provider</returns>
 | 
			
		||||
        public string Name
 | 
			
		||||
        {
 | 
			
		||||
            get { return "MSSQL Inventory Data Interface"; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Closes this DB provider
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public void Dispose()
 | 
			
		||||
        {
 | 
			
		||||
            database = null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Returns the version of this DB provider
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <returns>A string containing the DB provider</returns>
 | 
			
		||||
        public string Version
 | 
			
		||||
        {
 | 
			
		||||
            get { return database.getVersion(); }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        #endregion
 | 
			
		||||
 | 
			
		||||
        #region Folder methods
 | 
			
		||||
 | 
			
		||||
        /// <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>
 | 
			
		||||
        public List<InventoryFolderBase> getUserRootFolders(UUID user)
 | 
			
		||||
        {
 | 
			
		||||
            if (user == UUID.Zero)
 | 
			
		||||
                return new List<InventoryFolderBase>();
 | 
			
		||||
 | 
			
		||||
            return getInventoryFolders(UUID.Zero, user);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// see InventoryItemBase.getUserRootFolder
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="user">the User UUID</param>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        public InventoryFolderBase getUserRootFolder(UUID user)
 | 
			
		||||
        {
 | 
			
		||||
            List<InventoryFolderBase> items = getUserRootFolders(user);
 | 
			
		||||
 | 
			
		||||
            InventoryFolderBase rootFolder = null;
 | 
			
		||||
 | 
			
		||||
            // There should only ever be one root folder for a user.  However, if there's more
 | 
			
		||||
            // than one we'll simply use the first one rather than failing.  It would be even
 | 
			
		||||
            // nicer to print some message to this effect, but this feels like it's too low a
 | 
			
		||||
            // to put such a message out, and it's too minor right now to spare the time to
 | 
			
		||||
            // suitably refactor.
 | 
			
		||||
            if (items.Count > 0)
 | 
			
		||||
            {
 | 
			
		||||
                rootFolder = items[0];
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return rootFolder;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Returns a list of folders in a users inventory contained within the specified folder
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="parentID">The folder to search</param>
 | 
			
		||||
        /// <returns>A list of inventory folders</returns>
 | 
			
		||||
        public List<InventoryFolderBase> getInventoryFolders(UUID parentID)
 | 
			
		||||
        {
 | 
			
		||||
            return getInventoryFolders(parentID, UUID.Zero);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Returns a specified inventory folder
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="folderID">The folder to return</param>
 | 
			
		||||
        /// <returns>A folder class</returns>
 | 
			
		||||
        public InventoryFolderBase getInventoryFolder(UUID folderID)
 | 
			
		||||
        {
 | 
			
		||||
            string sql = "SELECT * FROM inventoryfolders WHERE folderID = @folderID";
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_connectionString))
 | 
			
		||||
            using (SqlCommand cmd = new SqlCommand(sql, conn))
 | 
			
		||||
            {
 | 
			
		||||
                cmd.Parameters.Add(database.CreateParameter("folderID", folderID));
 | 
			
		||||
                conn.Open();
 | 
			
		||||
                using (SqlDataReader reader = cmd.ExecuteReader())
 | 
			
		||||
                {
 | 
			
		||||
                    if (reader.Read())
 | 
			
		||||
                    {
 | 
			
		||||
                        return readInventoryFolder(reader);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            m_log.InfoFormat("[INVENTORY DB] : Found no inventory folder with ID : {0}", folderID);
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Returns all child folders in the hierarchy from the parent folder and down.
 | 
			
		||||
        /// 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>
 | 
			
		||||
        public List<InventoryFolderBase> getFolderHierarchy(UUID parentID)
 | 
			
		||||
        {
 | 
			
		||||
            //Note maybe change this to use a Dataset that loading in all folders of a user and then go throw it that way.
 | 
			
		||||
            //Note this is changed so it opens only one connection to the database and not everytime it wants to get data.
 | 
			
		||||
 | 
			
		||||
            /*  NOTE: the implementation below is very inefficient (makes a separate request to get subfolders for
 | 
			
		||||
             * every found folder, recursively).  Inventory code for other DBs has been already rewritten to get ALL
 | 
			
		||||
             * inventory for a specific user at once.
 | 
			
		||||
             * 
 | 
			
		||||
             * Meanwhile, one little thing is corrected:  getFolderHierarchy(UUID.Zero) doesn't make sense and should never 
 | 
			
		||||
             * be used, so check for that and return an empty list.
 | 
			
		||||
             */
 | 
			
		||||
 | 
			
		||||
            List<InventoryFolderBase> folders = new List<InventoryFolderBase>();
 | 
			
		||||
 | 
			
		||||
            if (parentID == UUID.Zero)
 | 
			
		||||
                return folders;
 | 
			
		||||
 | 
			
		||||
            string sql = "SELECT * FROM inventoryfolders WHERE parentFolderID = @parentID";
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_connectionString))
 | 
			
		||||
            using (SqlCommand cmd = new SqlCommand(sql, conn))
 | 
			
		||||
            {
 | 
			
		||||
                cmd.Parameters.Add(database.CreateParameter("@parentID", parentID));
 | 
			
		||||
                conn.Open();
 | 
			
		||||
                folders.AddRange(getInventoryFolders(cmd));
 | 
			
		||||
 | 
			
		||||
                List<InventoryFolderBase> tempFolders = new List<InventoryFolderBase>();
 | 
			
		||||
 | 
			
		||||
                foreach (InventoryFolderBase folderBase in folders)
 | 
			
		||||
                {
 | 
			
		||||
                    tempFolders.AddRange(getFolderHierarchy(folderBase.ID, cmd));
 | 
			
		||||
                }
 | 
			
		||||
                if (tempFolders.Count > 0)
 | 
			
		||||
                {
 | 
			
		||||
                    folders.AddRange(tempFolders);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            return folders;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Creates a new inventory folder
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="folder">Folder to create</param>
 | 
			
		||||
        public void addInventoryFolder(InventoryFolderBase folder)
 | 
			
		||||
        {
 | 
			
		||||
            string sql = @"INSERT INTO inventoryfolders ([folderID], [agentID], [parentFolderID], [folderName], [type], [version]) 
 | 
			
		||||
                            VALUES (@folderID, @agentID, @parentFolderID, @folderName, @type, @version);";
 | 
			
		||||
 | 
			
		||||
            string folderName = folder.Name;
 | 
			
		||||
            if (folderName.Length > 64)
 | 
			
		||||
            {
 | 
			
		||||
                folderName = folderName.Substring(0, 64);
 | 
			
		||||
                m_log.Warn("[INVENTORY DB]: Name field truncated from " + folder.Name.Length.ToString() + " to " + folderName.Length + " characters on add");
 | 
			
		||||
            }
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_connectionString))
 | 
			
		||||
            using (SqlCommand cmd = new SqlCommand(sql, conn))
 | 
			
		||||
            {
 | 
			
		||||
                cmd.Parameters.Add(database.CreateParameter("folderID", folder.ID));
 | 
			
		||||
                cmd.Parameters.Add(database.CreateParameter("agentID", folder.Owner));
 | 
			
		||||
                cmd.Parameters.Add(database.CreateParameter("parentFolderID", folder.ParentID));
 | 
			
		||||
                cmd.Parameters.Add(database.CreateParameter("folderName", folderName));
 | 
			
		||||
                cmd.Parameters.Add(database.CreateParameter("type", folder.Type));
 | 
			
		||||
                cmd.Parameters.Add(database.CreateParameter("version", folder.Version));
 | 
			
		||||
                conn.Open();
 | 
			
		||||
                try
 | 
			
		||||
                {
 | 
			
		||||
                    cmd.ExecuteNonQuery();
 | 
			
		||||
                }
 | 
			
		||||
                catch (Exception e)
 | 
			
		||||
                {
 | 
			
		||||
                    m_log.ErrorFormat("[INVENTORY DB]: Error : {0}", e.Message);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Updates an inventory folder
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="folder">Folder to update</param>
 | 
			
		||||
        public void updateInventoryFolder(InventoryFolderBase folder)
 | 
			
		||||
        {
 | 
			
		||||
            string sql = @"UPDATE inventoryfolders SET agentID = @agentID, 
 | 
			
		||||
                                                       parentFolderID = @parentFolderID,
 | 
			
		||||
                                                       folderName = @folderName,
 | 
			
		||||
                                                       type = @type,
 | 
			
		||||
                                                       version = @version 
 | 
			
		||||
                           WHERE folderID = @folderID";
 | 
			
		||||
 | 
			
		||||
            string folderName = folder.Name;
 | 
			
		||||
            if (folderName.Length > 64)
 | 
			
		||||
            {
 | 
			
		||||
                folderName = folderName.Substring(0, 64);
 | 
			
		||||
                m_log.Warn("[INVENTORY DB]: Name field truncated from " + folder.Name.Length.ToString() + " to " + folderName.Length + " characters on update");
 | 
			
		||||
            }
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_connectionString))
 | 
			
		||||
            using (SqlCommand cmd = new SqlCommand(sql, conn))
 | 
			
		||||
            {
 | 
			
		||||
                cmd.Parameters.Add(database.CreateParameter("folderID", folder.ID));
 | 
			
		||||
                cmd.Parameters.Add(database.CreateParameter("agentID", folder.Owner));
 | 
			
		||||
                cmd.Parameters.Add(database.CreateParameter("parentFolderID", folder.ParentID));
 | 
			
		||||
                cmd.Parameters.Add(database.CreateParameter("folderName", folderName));
 | 
			
		||||
                cmd.Parameters.Add(database.CreateParameter("type", folder.Type));
 | 
			
		||||
                cmd.Parameters.Add(database.CreateParameter("version", folder.Version));
 | 
			
		||||
                conn.Open();
 | 
			
		||||
                try
 | 
			
		||||
                {
 | 
			
		||||
                    cmd.ExecuteNonQuery();
 | 
			
		||||
                }
 | 
			
		||||
                catch (Exception e)
 | 
			
		||||
                {
 | 
			
		||||
                    m_log.ErrorFormat("[INVENTORY DB]: Error : {0}", e.Message);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Updates an inventory folder
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="folder">Folder to update</param>
 | 
			
		||||
        public void moveInventoryFolder(InventoryFolderBase folder)
 | 
			
		||||
        {
 | 
			
		||||
            string sql = @"UPDATE inventoryfolders SET parentFolderID = @parentFolderID WHERE folderID = @folderID";
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_connectionString))
 | 
			
		||||
            using (SqlCommand cmd = new SqlCommand(sql, conn))
 | 
			
		||||
            {
 | 
			
		||||
                cmd.Parameters.Add(database.CreateParameter("parentFolderID", folder.ParentID));
 | 
			
		||||
                cmd.Parameters.Add(database.CreateParameter("folderID", folder.ID));
 | 
			
		||||
                conn.Open();
 | 
			
		||||
                try
 | 
			
		||||
                {
 | 
			
		||||
                    cmd.ExecuteNonQuery();
 | 
			
		||||
                }
 | 
			
		||||
                catch (Exception e)
 | 
			
		||||
                {
 | 
			
		||||
                    m_log.ErrorFormat("[INVENTORY DB]: Error : {0}", e.Message);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Delete an inventory folder
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="folderID">Id of folder to delete</param>
 | 
			
		||||
        public void deleteInventoryFolder(UUID folderID)
 | 
			
		||||
        {
 | 
			
		||||
            string sql = "SELECT * FROM inventoryfolders WHERE parentFolderID = @parentID";
 | 
			
		||||
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_connectionString))
 | 
			
		||||
            using (SqlCommand cmd = new SqlCommand(sql, conn))
 | 
			
		||||
            {
 | 
			
		||||
                List<InventoryFolderBase> subFolders;
 | 
			
		||||
                cmd.Parameters.Add(database.CreateParameter("@parentID", UUID.Zero));
 | 
			
		||||
                conn.Open();
 | 
			
		||||
                subFolders = getFolderHierarchy(folderID, cmd);
 | 
			
		||||
                
 | 
			
		||||
 | 
			
		||||
                //Delete all sub-folders
 | 
			
		||||
                foreach (InventoryFolderBase f in subFolders)
 | 
			
		||||
                {
 | 
			
		||||
                    DeleteOneFolder(f.ID, conn);
 | 
			
		||||
                    DeleteItemsInFolder(f.ID, conn);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                //Delete the actual row
 | 
			
		||||
                DeleteOneFolder(folderID, conn);
 | 
			
		||||
                DeleteItemsInFolder(folderID, conn);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        #endregion
 | 
			
		||||
 | 
			
		||||
        #region Item Methods
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Returns a list of items in a specified folder
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="folderID">The folder to search</param>
 | 
			
		||||
        /// <returns>A list containing inventory items</returns>
 | 
			
		||||
        public List<InventoryItemBase> getInventoryInFolder(UUID folderID)
 | 
			
		||||
        {
 | 
			
		||||
            string sql = "SELECT * FROM inventoryitems WHERE parentFolderID = @parentFolderID";
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_connectionString))
 | 
			
		||||
            using (SqlCommand cmd = new SqlCommand(sql, conn))
 | 
			
		||||
            {
 | 
			
		||||
                cmd.Parameters.Add(database.CreateParameter("parentFolderID", folderID));
 | 
			
		||||
                conn.Open();
 | 
			
		||||
                List<InventoryItemBase> items = new List<InventoryItemBase>();
 | 
			
		||||
 | 
			
		||||
                using (SqlDataReader reader = cmd.ExecuteReader())
 | 
			
		||||
                {
 | 
			
		||||
                    while (reader.Read())
 | 
			
		||||
                    {
 | 
			
		||||
                        items.Add(readInventoryItem(reader));
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                return items;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Returns a specified inventory item
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="itemID">The item ID</param>
 | 
			
		||||
        /// <returns>An inventory item</returns>
 | 
			
		||||
        public InventoryItemBase getInventoryItem(UUID itemID)
 | 
			
		||||
        {
 | 
			
		||||
            string sql = "SELECT * FROM inventoryitems WHERE inventoryID = @inventoryID";
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_connectionString))
 | 
			
		||||
            using (SqlCommand cmd = new SqlCommand(sql, conn))
 | 
			
		||||
            {
 | 
			
		||||
                cmd.Parameters.Add(database.CreateParameter("inventoryID", itemID));
 | 
			
		||||
                conn.Open();
 | 
			
		||||
                using (SqlDataReader reader = cmd.ExecuteReader())
 | 
			
		||||
                {
 | 
			
		||||
                    if (reader.Read())
 | 
			
		||||
                    {
 | 
			
		||||
                        return readInventoryItem(reader);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            m_log.InfoFormat("[INVENTORY DB]: Found no inventory item with ID : {0}", itemID);
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Adds a specified item to the database
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="item">The inventory item</param>
 | 
			
		||||
        public void addInventoryItem(InventoryItemBase item)
 | 
			
		||||
        {
 | 
			
		||||
            if (getInventoryItem(item.ID) != null)
 | 
			
		||||
            {
 | 
			
		||||
                updateInventoryItem(item);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            string sql = @"INSERT INTO inventoryitems 
 | 
			
		||||
                            ([inventoryID], [assetID], [assetType], [parentFolderID], [avatarID], [inventoryName], 
 | 
			
		||||
                             [inventoryDescription], [inventoryNextPermissions], [inventoryCurrentPermissions],
 | 
			
		||||
                             [invType], [creatorID], [inventoryBasePermissions], [inventoryEveryOnePermissions], [inventoryGroupPermissions],
 | 
			
		||||
                             [salePrice], [saleType], [creationDate], [groupID], [groupOwned], [flags]) 
 | 
			
		||||
                        VALUES
 | 
			
		||||
                            (@inventoryID, @assetID, @assetType, @parentFolderID, @avatarID, @inventoryName, @inventoryDescription,
 | 
			
		||||
                             @inventoryNextPermissions, @inventoryCurrentPermissions, @invType, @creatorID,
 | 
			
		||||
                             @inventoryBasePermissions, @inventoryEveryOnePermissions, @inventoryGroupPermissions, @salePrice, @saleType,
 | 
			
		||||
                             @creationDate, @groupID, @groupOwned, @flags)";
 | 
			
		||||
            
 | 
			
		||||
            string itemName = item.Name;
 | 
			
		||||
            if (item.Name.Length > 64)
 | 
			
		||||
            {
 | 
			
		||||
                itemName = item.Name.Substring(0, 64);
 | 
			
		||||
                m_log.Warn("[INVENTORY DB]: Name field truncated from " + item.Name.Length.ToString() + " to " + itemName.Length.ToString() + " characters");
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            string itemDesc = item.Description;
 | 
			
		||||
            if (item.Description.Length > 128)
 | 
			
		||||
            {
 | 
			
		||||
                itemDesc = item.Description.Substring(0, 128);
 | 
			
		||||
                m_log.Warn("[INVENTORY DB]: Description field truncated from " + item.Description.Length.ToString() + " to " + itemDesc.Length.ToString() + " characters");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_connectionString))
 | 
			
		||||
            using (SqlCommand command = new SqlCommand(sql, conn))
 | 
			
		||||
            {
 | 
			
		||||
                command.Parameters.Add(database.CreateParameter("inventoryID", item.ID));
 | 
			
		||||
                command.Parameters.Add(database.CreateParameter("assetID", item.AssetID));
 | 
			
		||||
                command.Parameters.Add(database.CreateParameter("assetType", item.AssetType));
 | 
			
		||||
                command.Parameters.Add(database.CreateParameter("parentFolderID", item.Folder));
 | 
			
		||||
                command.Parameters.Add(database.CreateParameter("avatarID", item.Owner));
 | 
			
		||||
                command.Parameters.Add(database.CreateParameter("inventoryName", itemName));
 | 
			
		||||
                command.Parameters.Add(database.CreateParameter("inventoryDescription", itemDesc));
 | 
			
		||||
                command.Parameters.Add(database.CreateParameter("inventoryNextPermissions", item.NextPermissions));
 | 
			
		||||
                command.Parameters.Add(database.CreateParameter("inventoryCurrentPermissions", item.CurrentPermissions));
 | 
			
		||||
                command.Parameters.Add(database.CreateParameter("invType", item.InvType));
 | 
			
		||||
                command.Parameters.Add(database.CreateParameter("creatorID", item.CreatorId));
 | 
			
		||||
                command.Parameters.Add(database.CreateParameter("inventoryBasePermissions", item.BasePermissions));
 | 
			
		||||
                command.Parameters.Add(database.CreateParameter("inventoryEveryOnePermissions", item.EveryOnePermissions));
 | 
			
		||||
                command.Parameters.Add(database.CreateParameter("inventoryGroupPermissions", item.GroupPermissions));
 | 
			
		||||
                command.Parameters.Add(database.CreateParameter("salePrice", item.SalePrice));
 | 
			
		||||
                command.Parameters.Add(database.CreateParameter("saleType", item.SaleType));
 | 
			
		||||
                command.Parameters.Add(database.CreateParameter("creationDate", item.CreationDate));
 | 
			
		||||
                command.Parameters.Add(database.CreateParameter("groupID", item.GroupID));
 | 
			
		||||
                command.Parameters.Add(database.CreateParameter("groupOwned", item.GroupOwned));
 | 
			
		||||
                command.Parameters.Add(database.CreateParameter("flags", item.Flags));
 | 
			
		||||
                conn.Open();
 | 
			
		||||
                try
 | 
			
		||||
                {
 | 
			
		||||
                    command.ExecuteNonQuery();
 | 
			
		||||
                }
 | 
			
		||||
                catch (Exception e)
 | 
			
		||||
                {
 | 
			
		||||
                    m_log.Error("[INVENTORY DB]: Error inserting item :" + e.Message);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            sql = "UPDATE inventoryfolders SET version = version + 1 WHERE folderID = @folderID";
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_connectionString))
 | 
			
		||||
            using (SqlCommand command = new SqlCommand(sql, conn))
 | 
			
		||||
            {
 | 
			
		||||
                command.Parameters.Add(database.CreateParameter("folderID", item.Folder.ToString()));
 | 
			
		||||
                conn.Open();
 | 
			
		||||
                try
 | 
			
		||||
                {
 | 
			
		||||
                    command.ExecuteNonQuery();
 | 
			
		||||
                }
 | 
			
		||||
                catch (Exception e)
 | 
			
		||||
                {
 | 
			
		||||
                    m_log.Error("[INVENTORY DB] Error updating inventory folder for new item :" + e.Message);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Updates the specified inventory item
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="item">Inventory item to update</param>
 | 
			
		||||
        public void updateInventoryItem(InventoryItemBase item)
 | 
			
		||||
        {
 | 
			
		||||
            string sql = @"UPDATE inventoryitems SET assetID = @assetID, 
 | 
			
		||||
                                                assetType = @assetType,
 | 
			
		||||
                                                parentFolderID = @parentFolderID,
 | 
			
		||||
                                                avatarID = @avatarID,
 | 
			
		||||
                                                inventoryName = @inventoryName, 
 | 
			
		||||
                                                inventoryDescription = @inventoryDescription, 
 | 
			
		||||
                                                inventoryNextPermissions = @inventoryNextPermissions, 
 | 
			
		||||
                                                inventoryCurrentPermissions = @inventoryCurrentPermissions, 
 | 
			
		||||
                                                invType = @invType, 
 | 
			
		||||
                                                creatorID = @creatorID, 
 | 
			
		||||
                                                inventoryBasePermissions = @inventoryBasePermissions, 
 | 
			
		||||
                                                inventoryEveryOnePermissions = @inventoryEveryOnePermissions, 
 | 
			
		||||
                                                inventoryGroupPermissions = @inventoryGroupPermissions, 
 | 
			
		||||
                                                salePrice = @salePrice, 
 | 
			
		||||
                                                saleType = @saleType, 
 | 
			
		||||
                                                creationDate = @creationDate, 
 | 
			
		||||
                                                groupID = @groupID, 
 | 
			
		||||
                                                groupOwned = @groupOwned, 
 | 
			
		||||
                                                flags = @flags 
 | 
			
		||||
                                        WHERE inventoryID = @inventoryID";
 | 
			
		||||
 | 
			
		||||
            string itemName = item.Name;
 | 
			
		||||
            if (item.Name.Length > 64)
 | 
			
		||||
            {
 | 
			
		||||
                itemName = item.Name.Substring(0, 64);
 | 
			
		||||
                m_log.Warn("[INVENTORY DB]: Name field truncated from " + item.Name.Length.ToString() + " to " + itemName.Length.ToString() + " characters on update");
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            string itemDesc = item.Description;
 | 
			
		||||
            if (item.Description.Length > 128)
 | 
			
		||||
            {
 | 
			
		||||
                itemDesc = item.Description.Substring(0, 128);
 | 
			
		||||
                m_log.Warn("[INVENTORY DB]: Description field truncated from " + item.Description.Length.ToString() + " to " + itemDesc.Length.ToString() + " characters on update");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_connectionString))
 | 
			
		||||
            using (SqlCommand command = new SqlCommand(sql, conn))
 | 
			
		||||
            {
 | 
			
		||||
                command.Parameters.Add(database.CreateParameter("inventoryID", item.ID));
 | 
			
		||||
                command.Parameters.Add(database.CreateParameter("assetID", item.AssetID));
 | 
			
		||||
                command.Parameters.Add(database.CreateParameter("assetType", item.AssetType));
 | 
			
		||||
                command.Parameters.Add(database.CreateParameter("parentFolderID", item.Folder));
 | 
			
		||||
                command.Parameters.Add(database.CreateParameter("avatarID", item.Owner));
 | 
			
		||||
                command.Parameters.Add(database.CreateParameter("inventoryName", itemName));
 | 
			
		||||
                command.Parameters.Add(database.CreateParameter("inventoryDescription", itemDesc));
 | 
			
		||||
                command.Parameters.Add(database.CreateParameter("inventoryNextPermissions", item.NextPermissions));
 | 
			
		||||
                command.Parameters.Add(database.CreateParameter("inventoryCurrentPermissions", item.CurrentPermissions));
 | 
			
		||||
                command.Parameters.Add(database.CreateParameter("invType", item.InvType));
 | 
			
		||||
                command.Parameters.Add(database.CreateParameter("creatorID", item.CreatorId));
 | 
			
		||||
                command.Parameters.Add(database.CreateParameter("inventoryBasePermissions", item.BasePermissions));
 | 
			
		||||
                command.Parameters.Add(database.CreateParameter("inventoryEveryOnePermissions", item.EveryOnePermissions));
 | 
			
		||||
                command.Parameters.Add(database.CreateParameter("inventoryGroupPermissions", item.GroupPermissions));
 | 
			
		||||
                command.Parameters.Add(database.CreateParameter("salePrice", item.SalePrice));
 | 
			
		||||
                command.Parameters.Add(database.CreateParameter("saleType", item.SaleType));
 | 
			
		||||
                command.Parameters.Add(database.CreateParameter("creationDate", item.CreationDate));
 | 
			
		||||
                command.Parameters.Add(database.CreateParameter("groupID", item.GroupID));
 | 
			
		||||
                command.Parameters.Add(database.CreateParameter("groupOwned", item.GroupOwned));
 | 
			
		||||
                command.Parameters.Add(database.CreateParameter("flags", item.Flags));
 | 
			
		||||
                conn.Open();
 | 
			
		||||
                try
 | 
			
		||||
                {
 | 
			
		||||
                    command.ExecuteNonQuery();
 | 
			
		||||
                }
 | 
			
		||||
                catch (Exception e)
 | 
			
		||||
                {
 | 
			
		||||
                    m_log.Error("[INVENTORY DB]: Error updating item :" + e.Message);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // See IInventoryDataPlugin
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Delete an item in inventory database
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="itemID">the item UUID</param>
 | 
			
		||||
        public void deleteInventoryItem(UUID itemID)
 | 
			
		||||
        {
 | 
			
		||||
            string sql = "DELETE FROM inventoryitems WHERE inventoryID=@inventoryID";
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_connectionString))
 | 
			
		||||
            using (SqlCommand cmd = new SqlCommand(sql, conn))
 | 
			
		||||
            {
 | 
			
		||||
                cmd.Parameters.Add(database.CreateParameter("inventoryID", itemID));
 | 
			
		||||
                try
 | 
			
		||||
                {
 | 
			
		||||
                    conn.Open();
 | 
			
		||||
                    cmd.ExecuteNonQuery();
 | 
			
		||||
                }
 | 
			
		||||
                catch (Exception e)
 | 
			
		||||
                {
 | 
			
		||||
                    m_log.Error("[INVENTORY DB]: Error deleting item :" + e.Message);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public InventoryItemBase queryInventoryItem(UUID itemID)
 | 
			
		||||
        {
 | 
			
		||||
            return getInventoryItem(itemID);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public InventoryFolderBase queryInventoryFolder(UUID folderID)
 | 
			
		||||
        {
 | 
			
		||||
            return getInventoryFolder(folderID);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <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>
 | 
			
		||||
        public List<InventoryItemBase> fetchActiveGestures(UUID avatarID)
 | 
			
		||||
        {
 | 
			
		||||
            string sql = "SELECT * FROM inventoryitems WHERE avatarId = @uuid AND assetType = @assetType and flags = 1";
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_connectionString))
 | 
			
		||||
            using (SqlCommand cmd = new SqlCommand(sql, conn))
 | 
			
		||||
            {
 | 
			
		||||
                cmd.Parameters.Add(database.CreateParameter("uuid", avatarID));
 | 
			
		||||
                cmd.Parameters.Add(database.CreateParameter("assetType", (int)AssetType.Gesture));
 | 
			
		||||
                conn.Open();
 | 
			
		||||
                using (SqlDataReader reader = cmd.ExecuteReader())
 | 
			
		||||
                {
 | 
			
		||||
                    List<InventoryItemBase> gestureList = new List<InventoryItemBase>();
 | 
			
		||||
                    while (reader.Read())
 | 
			
		||||
                    {
 | 
			
		||||
                        gestureList.Add(readInventoryItem(reader));
 | 
			
		||||
                    }
 | 
			
		||||
                    return gestureList;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        #endregion
 | 
			
		||||
 | 
			
		||||
        #region Private methods
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Delete an item in inventory database
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="folderID">the item ID</param>
 | 
			
		||||
        /// <param name="connection">connection to the database</param>
 | 
			
		||||
        private void DeleteItemsInFolder(UUID folderID, SqlConnection connection)
 | 
			
		||||
        {
 | 
			
		||||
            using (SqlCommand command = new SqlCommand("DELETE FROM inventoryitems WHERE folderID=@folderID", connection))
 | 
			
		||||
            {
 | 
			
		||||
                command.Parameters.Add(database.CreateParameter("folderID", folderID));
 | 
			
		||||
 | 
			
		||||
                try
 | 
			
		||||
                {
 | 
			
		||||
                    command.ExecuteNonQuery();
 | 
			
		||||
                }
 | 
			
		||||
                catch (Exception e)
 | 
			
		||||
                {
 | 
			
		||||
                    m_log.Error("[INVENTORY DB] Error deleting item :" + e.Message);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the folder hierarchy in a loop.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="parentID">parent ID.</param>
 | 
			
		||||
        /// <param name="command">SQL command/connection to database</param>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        private static List<InventoryFolderBase> getFolderHierarchy(UUID parentID, SqlCommand command)
 | 
			
		||||
        {
 | 
			
		||||
            command.Parameters["@parentID"].Value = parentID.Guid; //.ToString();
 | 
			
		||||
 | 
			
		||||
            List<InventoryFolderBase> folders = getInventoryFolders(command);
 | 
			
		||||
 | 
			
		||||
            if (folders.Count > 0)
 | 
			
		||||
            {
 | 
			
		||||
                List<InventoryFolderBase> tempFolders = new List<InventoryFolderBase>();
 | 
			
		||||
 | 
			
		||||
                foreach (InventoryFolderBase folderBase in folders)
 | 
			
		||||
                {
 | 
			
		||||
                    tempFolders.AddRange(getFolderHierarchy(folderBase.ID, command));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (tempFolders.Count > 0)
 | 
			
		||||
                {
 | 
			
		||||
                    folders.AddRange(tempFolders);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            return folders;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the inventory folders.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="parentID">parentID, use UUID.Zero to get root</param>
 | 
			
		||||
        /// <param name="user">user id, use UUID.Zero, if you want all folders from a parentID.</param>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        private List<InventoryFolderBase> getInventoryFolders(UUID parentID, UUID user)
 | 
			
		||||
        {
 | 
			
		||||
            string sql = "SELECT * FROM inventoryfolders WHERE parentFolderID = @parentID AND agentID LIKE @uuid";
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_connectionString))
 | 
			
		||||
            using (SqlCommand command = new SqlCommand(sql, conn))
 | 
			
		||||
            {
 | 
			
		||||
                if (user == UUID.Zero)
 | 
			
		||||
                {
 | 
			
		||||
                    command.Parameters.Add(database.CreateParameter("uuid", "%"));
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    command.Parameters.Add(database.CreateParameter("uuid", user));
 | 
			
		||||
                }
 | 
			
		||||
                command.Parameters.Add(database.CreateParameter("parentID", parentID));
 | 
			
		||||
                conn.Open();
 | 
			
		||||
                return getInventoryFolders(command);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the inventory folders.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="command">SQLcommand.</param>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        private static List<InventoryFolderBase> getInventoryFolders(SqlCommand command)
 | 
			
		||||
        {
 | 
			
		||||
            using (SqlDataReader reader = command.ExecuteReader())
 | 
			
		||||
            {
 | 
			
		||||
 | 
			
		||||
                List<InventoryFolderBase> items = new List<InventoryFolderBase>();
 | 
			
		||||
                while (reader.Read())
 | 
			
		||||
                {
 | 
			
		||||
                    items.Add(readInventoryFolder(reader));
 | 
			
		||||
                }
 | 
			
		||||
                return items;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Reads a list of inventory folders returned by a query.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="reader">A MSSQL Data Reader</param>
 | 
			
		||||
        /// <returns>A List containing inventory folders</returns>
 | 
			
		||||
        protected static InventoryFolderBase readInventoryFolder(SqlDataReader reader)
 | 
			
		||||
        {
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                InventoryFolderBase folder = new InventoryFolderBase();
 | 
			
		||||
                folder.Owner = DBGuid.FromDB(reader["agentID"]);
 | 
			
		||||
                folder.ParentID = DBGuid.FromDB(reader["parentFolderID"]);
 | 
			
		||||
                folder.ID = DBGuid.FromDB(reader["folderID"]);
 | 
			
		||||
                folder.Name = (string)reader["folderName"];
 | 
			
		||||
                folder.Type = (short)reader["type"];
 | 
			
		||||
                folder.Version = Convert.ToUInt16(reader["version"]);
 | 
			
		||||
 | 
			
		||||
                return folder;
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception e)
 | 
			
		||||
            {
 | 
			
		||||
                m_log.Error("[INVENTORY DB] Error reading inventory folder :" + e.Message);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Reads a one item from an SQL result
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="reader">The SQL Result</param>
 | 
			
		||||
        /// <returns>the item read</returns>
 | 
			
		||||
        private static InventoryItemBase readInventoryItem(IDataRecord reader)
 | 
			
		||||
        {
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                InventoryItemBase item = new InventoryItemBase();
 | 
			
		||||
 | 
			
		||||
                item.ID = DBGuid.FromDB(reader["inventoryID"]);
 | 
			
		||||
                item.AssetID = DBGuid.FromDB(reader["assetID"]);
 | 
			
		||||
                item.AssetType = Convert.ToInt32(reader["assetType"].ToString());
 | 
			
		||||
                item.Folder = DBGuid.FromDB(reader["parentFolderID"]);
 | 
			
		||||
                item.Owner = DBGuid.FromDB(reader["avatarID"]);
 | 
			
		||||
                item.Name = reader["inventoryName"].ToString();
 | 
			
		||||
                item.Description = reader["inventoryDescription"].ToString();
 | 
			
		||||
                item.NextPermissions = Convert.ToUInt32(reader["inventoryNextPermissions"]);
 | 
			
		||||
                item.CurrentPermissions = Convert.ToUInt32(reader["inventoryCurrentPermissions"]);
 | 
			
		||||
                item.InvType = Convert.ToInt32(reader["invType"].ToString());
 | 
			
		||||
                item.CreatorId = reader["creatorID"].ToString();
 | 
			
		||||
                item.BasePermissions = Convert.ToUInt32(reader["inventoryBasePermissions"]);
 | 
			
		||||
                item.EveryOnePermissions = Convert.ToUInt32(reader["inventoryEveryOnePermissions"]);
 | 
			
		||||
                item.GroupPermissions = Convert.ToUInt32(reader["inventoryGroupPermissions"]);
 | 
			
		||||
                item.SalePrice = Convert.ToInt32(reader["salePrice"]);
 | 
			
		||||
                item.SaleType = Convert.ToByte(reader["saleType"]);
 | 
			
		||||
                item.CreationDate = Convert.ToInt32(reader["creationDate"]);
 | 
			
		||||
                item.GroupID = DBGuid.FromDB(reader["groupID"]);
 | 
			
		||||
                item.GroupOwned = Convert.ToBoolean(reader["groupOwned"]);
 | 
			
		||||
                item.Flags = Convert.ToUInt32(reader["flags"]);
 | 
			
		||||
 | 
			
		||||
                return item;
 | 
			
		||||
            }
 | 
			
		||||
            catch (SqlException e)
 | 
			
		||||
            {
 | 
			
		||||
                m_log.Error("[INVENTORY DB]: Error reading inventory item :" + e.Message);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Delete a folder in inventory databasae
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="folderID">the folder UUID</param>
 | 
			
		||||
        /// <param name="connection">connection to database</param>
 | 
			
		||||
        private void DeleteOneFolder(UUID folderID, SqlConnection connection)
 | 
			
		||||
        {
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                using (SqlCommand command = new SqlCommand("DELETE FROM inventoryfolders WHERE folderID=@folderID and type=-1", connection))
 | 
			
		||||
                {
 | 
			
		||||
                    command.Parameters.Add(database.CreateParameter("folderID", folderID));
 | 
			
		||||
 | 
			
		||||
                    command.ExecuteNonQuery();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            catch (SqlException e)
 | 
			
		||||
            {
 | 
			
		||||
                m_log.Error("[INVENTORY DB]: Error deleting folder :" + e.Message);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        #endregion
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,219 @@
 | 
			
		|||
/*
 | 
			
		||||
 * 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.Data;
 | 
			
		||||
using System.Data.SqlClient;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
using log4net;
 | 
			
		||||
using OpenMetaverse;
 | 
			
		||||
 | 
			
		||||
namespace OpenSim.Data.MSSQL
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// A management class for the MS SQL Storage Engine
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class MSSQLManager
 | 
			
		||||
    {
 | 
			
		||||
//        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Connection string for ADO.net
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        private readonly string connectionString;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Initialize the manager and set the connectionstring
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="connection"></param>
 | 
			
		||||
        public MSSQLManager(string connection)
 | 
			
		||||
        {
 | 
			
		||||
            connectionString = connection;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Type conversion to a SQLDbType functions
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="type"></param>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        internal SqlDbType DbtypeFromType(Type type)
 | 
			
		||||
        {
 | 
			
		||||
            if (type == typeof(string))
 | 
			
		||||
            {
 | 
			
		||||
                return SqlDbType.VarChar;
 | 
			
		||||
            }
 | 
			
		||||
            if (type == typeof(double))
 | 
			
		||||
            {
 | 
			
		||||
                return SqlDbType.Float;
 | 
			
		||||
            }
 | 
			
		||||
            if (type == typeof(Single))
 | 
			
		||||
            {
 | 
			
		||||
                return SqlDbType.Float;
 | 
			
		||||
            }
 | 
			
		||||
            if (type == typeof(int))
 | 
			
		||||
            {
 | 
			
		||||
                return SqlDbType.Int;
 | 
			
		||||
            }
 | 
			
		||||
            if (type == typeof(bool))
 | 
			
		||||
            {
 | 
			
		||||
                return SqlDbType.Bit;
 | 
			
		||||
            }
 | 
			
		||||
            if (type == typeof(UUID))
 | 
			
		||||
            {
 | 
			
		||||
                return SqlDbType.UniqueIdentifier;
 | 
			
		||||
            }
 | 
			
		||||
            if (type == typeof(sbyte))
 | 
			
		||||
            {
 | 
			
		||||
                return SqlDbType.Int;
 | 
			
		||||
            }
 | 
			
		||||
            if (type == typeof(Byte[]))
 | 
			
		||||
            {
 | 
			
		||||
                return SqlDbType.Image;
 | 
			
		||||
            }
 | 
			
		||||
            if (type == typeof(uint) || type == typeof(ushort))
 | 
			
		||||
            {
 | 
			
		||||
                return SqlDbType.Int;
 | 
			
		||||
            }
 | 
			
		||||
            if (type == typeof(ulong))
 | 
			
		||||
            {
 | 
			
		||||
                return SqlDbType.BigInt;
 | 
			
		||||
            }
 | 
			
		||||
            if (type == typeof(DateTime))
 | 
			
		||||
            {
 | 
			
		||||
                return SqlDbType.DateTime;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return SqlDbType.VarChar;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Creates value for parameter.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="value">The value.</param>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        private static object CreateParameterValue(object value)
 | 
			
		||||
        {
 | 
			
		||||
            Type valueType = value.GetType();
 | 
			
		||||
 | 
			
		||||
            if (valueType == typeof(UUID)) //TODO check if this works
 | 
			
		||||
            {
 | 
			
		||||
                return ((UUID) value).Guid;
 | 
			
		||||
            }
 | 
			
		||||
            if (valueType == typeof(UUID))
 | 
			
		||||
            {
 | 
			
		||||
                return ((UUID)value).Guid;
 | 
			
		||||
            }
 | 
			
		||||
            if (valueType == typeof(bool))
 | 
			
		||||
            {
 | 
			
		||||
                return (bool)value ? 1 : 0;
 | 
			
		||||
            }
 | 
			
		||||
            if (valueType == typeof(Byte[]))
 | 
			
		||||
            {
 | 
			
		||||
                return value;
 | 
			
		||||
            }
 | 
			
		||||
            if (valueType == typeof(int))
 | 
			
		||||
            {
 | 
			
		||||
                return value;
 | 
			
		||||
            }
 | 
			
		||||
            return value;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Create a parameter for a command
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="parameterName">Name of the parameter.</param>
 | 
			
		||||
        /// <param name="parameterObject">parameter object.</param>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        internal SqlParameter CreateParameter(string parameterName, object parameterObject)
 | 
			
		||||
        {
 | 
			
		||||
            return CreateParameter(parameterName, parameterObject, false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Creates the parameter for a command.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="parameterName">Name of the parameter.</param>
 | 
			
		||||
        /// <param name="parameterObject">parameter object.</param>
 | 
			
		||||
        /// <param name="parameterOut">if set to <c>true</c> parameter is a output parameter</param>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        internal SqlParameter CreateParameter(string parameterName, object parameterObject, bool parameterOut)
 | 
			
		||||
        {
 | 
			
		||||
            //Tweak so we dont always have to add @ sign
 | 
			
		||||
            if (!parameterName.StartsWith("@")) parameterName = "@" + parameterName;
 | 
			
		||||
 | 
			
		||||
            //HACK if object is null, it is turned into a string, there are no nullable type till now
 | 
			
		||||
            if (parameterObject == null) parameterObject = "";
 | 
			
		||||
 | 
			
		||||
            SqlParameter parameter = new SqlParameter(parameterName, DbtypeFromType(parameterObject.GetType()));
 | 
			
		||||
 | 
			
		||||
            if (parameterOut)
 | 
			
		||||
            {
 | 
			
		||||
                parameter.Direction = ParameterDirection.Output;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                parameter.Direction = ParameterDirection.Input;
 | 
			
		||||
                parameter.Value = CreateParameterValue(parameterObject);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return parameter;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Checks if we need to do some migrations to the database
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="migrationStore">migrationStore.</param>
 | 
			
		||||
        public void CheckMigration(string migrationStore)
 | 
			
		||||
        {
 | 
			
		||||
            using (SqlConnection connection = new SqlConnection(connectionString)) 
 | 
			
		||||
            {
 | 
			
		||||
                connection.Open();
 | 
			
		||||
                Assembly assem = GetType().Assembly;
 | 
			
		||||
                MSSQLMigration migration = new MSSQLMigration(connection, assem, migrationStore);
 | 
			
		||||
 | 
			
		||||
                migration.Update();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Returns the version of this DB provider
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <returns>A string containing the DB provider</returns>
 | 
			
		||||
        public string getVersion()
 | 
			
		||||
        {
 | 
			
		||||
            Module module = GetType().Module;
 | 
			
		||||
            // string dllName = module.Assembly.ManifestModule.Name;
 | 
			
		||||
            Version dllVersion = module.Assembly.GetName().Version;
 | 
			
		||||
 | 
			
		||||
            return
 | 
			
		||||
                string.Format("{0}.{1}.{2}.{3}", dllVersion.Major, dllVersion.Minor, dllVersion.Build,
 | 
			
		||||
                              dllVersion.Revision);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -24,70 +24,76 @@
 | 
			
		|||
 * (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.Data;
 | 
			
		||||
using System.Data.Common;
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
using System.Data.SqlClient;
 | 
			
		||||
 | 
			
		||||
using OpenSim.Region.CoreModules.World.Terrain;
 | 
			
		||||
using OpenSim.Region.Framework.Interfaces;
 | 
			
		||||
 | 
			
		||||
namespace OpenSim.Region.CoreModules.World.Terrain.Modifiers
 | 
			
		||||
namespace OpenSim.Data.MSSQL
 | 
			
		||||
{
 | 
			
		||||
    public class FillModifier : TerrainModifier
 | 
			
		||||
    public class MSSQLMigration : Migration
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
        public FillModifier(ITerrainModule module) : base(module)
 | 
			
		||||
        public MSSQLMigration(DbConnection conn, Assembly assem, string type)
 | 
			
		||||
            : base(conn, assem, type)
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override string ModifyTerrain(ITerrainChannel map, string[] args)
 | 
			
		||||
        public MSSQLMigration(DbConnection conn, Assembly assem, string subtype, string type)
 | 
			
		||||
            : base(conn, assem, subtype, type)
 | 
			
		||||
        {
 | 
			
		||||
            string result;
 | 
			
		||||
            if (args.Length < 3)
 | 
			
		||||
            {
 | 
			
		||||
                result = "Usage: " + GetUsage();
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                TerrainModifierData data;
 | 
			
		||||
                result = this.parseParameters(args, out data);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
                // Context-specific validation
 | 
			
		||||
                if (result == String.Empty)
 | 
			
		||||
        protected override int FindVersion(DbConnection conn, string type)
 | 
			
		||||
        {
 | 
			
		||||
            int version = 0;
 | 
			
		||||
            using (DbCommand cmd = conn.CreateCommand())
 | 
			
		||||
            {
 | 
			
		||||
                try
 | 
			
		||||
                {
 | 
			
		||||
                    if (data.shape == String.Empty)
 | 
			
		||||
                    cmd.CommandText = "select top 1 version from migrations where name = '" + type + "' order by version desc"; //Must be 
 | 
			
		||||
                    using (IDataReader reader = cmd.ExecuteReader())
 | 
			
		||||
                    {
 | 
			
		||||
                        data.shape = "rectangle";
 | 
			
		||||
                        data.x0 = 0;
 | 
			
		||||
                        data.y0 = 0;
 | 
			
		||||
                        data.dx = map.Width;
 | 
			
		||||
                        data.dy = map.Height;
 | 
			
		||||
                        if (reader.Read())
 | 
			
		||||
                        {
 | 
			
		||||
                            version = Convert.ToInt32(reader["version"]);
 | 
			
		||||
                        }
 | 
			
		||||
                        reader.Close();
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // if it's all good, then do the work
 | 
			
		||||
                if (result == String.Empty)
 | 
			
		||||
                catch
 | 
			
		||||
                {
 | 
			
		||||
                    this.applyModification(map, data);
 | 
			
		||||
                    // Return -1 to indicate table does not exist
 | 
			
		||||
                    return -1;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return result;
 | 
			
		||||
            return version;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override string GetUsage()
 | 
			
		||||
        protected override void ExecuteScript(DbConnection conn, string[] script)
 | 
			
		||||
        {
 | 
			
		||||
            string val = "fill <height> [ -rec=x1,y1,dx[,dy] | -ell=x0,y0,rx[,ry] ] [-taper=<height2>]"
 | 
			
		||||
                                + "\nSets all points within the specified range to the specified value.";
 | 
			
		||||
            return val;
 | 
			
		||||
        }
 | 
			
		||||
            if (!(conn is SqlConnection))
 | 
			
		||||
            {
 | 
			
		||||
                base.ExecuteScript(conn, script);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        public override float operate(float[,] map, TerrainModifierData data, int x, int y)
 | 
			
		||||
        {
 | 
			
		||||
            float factor = this.computeBevel(data, x, y);
 | 
			
		||||
            float result = data.elevation - (data.elevation - data.bevelevation) * factor;
 | 
			
		||||
            return result;
 | 
			
		||||
        }
 | 
			
		||||
            foreach (string sql in script)
 | 
			
		||||
            {
 | 
			
		||||
                try
 | 
			
		||||
                {
 | 
			
		||||
                    using (SqlCommand cmd = new SqlCommand(sql, (SqlConnection)conn))
 | 
			
		||||
                    {
 | 
			
		||||
                        cmd.ExecuteNonQuery();
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                catch (Exception)
 | 
			
		||||
                {
 | 
			
		||||
                    throw new Exception(sql);
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,117 @@
 | 
			
		|||
/*
 | 
			
		||||
 * 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.Data;
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
using System.Threading;
 | 
			
		||||
using log4net;
 | 
			
		||||
using OpenMetaverse;
 | 
			
		||||
using OpenSim.Framework;
 | 
			
		||||
using System.Data.SqlClient;
 | 
			
		||||
 | 
			
		||||
namespace OpenSim.Data.MSSQL
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// A MySQL Interface for the Presence Server
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class MSSQLPresenceData : MSSQLGenericTableHandler<PresenceData>,
 | 
			
		||||
            IPresenceData
 | 
			
		||||
    {
 | 
			
		||||
//        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 | 
			
		||||
 | 
			
		||||
        public MSSQLPresenceData(string connectionString, string realm) :
 | 
			
		||||
                base(connectionString, realm, "Presence")
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public PresenceData Get(UUID sessionID)
 | 
			
		||||
        {
 | 
			
		||||
            PresenceData[] ret = Get("SessionID",
 | 
			
		||||
                    sessionID.ToString());
 | 
			
		||||
 | 
			
		||||
            if (ret.Length == 0)
 | 
			
		||||
                return null;
 | 
			
		||||
 | 
			
		||||
            return ret[0];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void LogoutRegionAgents(UUID regionID)
 | 
			
		||||
        {
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_ConnectionString))
 | 
			
		||||
            using (SqlCommand cmd = new SqlCommand())
 | 
			
		||||
            {
 | 
			
		||||
 | 
			
		||||
                cmd.CommandText = String.Format("DELETE FROM {0} WHERE [RegionID]=@RegionID", m_Realm);
 | 
			
		||||
 | 
			
		||||
                cmd.Parameters.Add(m_database.CreateParameter("@RegionID", regionID.ToString()));
 | 
			
		||||
                cmd.Connection = conn;
 | 
			
		||||
                conn.Open();
 | 
			
		||||
                cmd.ExecuteNonQuery();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool ReportAgent(UUID sessionID, UUID regionID)
 | 
			
		||||
        {
 | 
			
		||||
            PresenceData[] pd = Get("SessionID", sessionID.ToString());
 | 
			
		||||
            if (pd.Length == 0)
 | 
			
		||||
                return false;
 | 
			
		||||
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_ConnectionString))
 | 
			
		||||
            using (SqlCommand cmd = new SqlCommand())
 | 
			
		||||
            {
 | 
			
		||||
 | 
			
		||||
                cmd.CommandText = String.Format(@"UPDATE {0} SET 
 | 
			
		||||
                                                [RegionID] = @RegionID
 | 
			
		||||
                                        WHERE [SessionID] = @SessionID", m_Realm);
 | 
			
		||||
 | 
			
		||||
                cmd.Parameters.Add(m_database.CreateParameter("@SessionID", sessionID.ToString()));
 | 
			
		||||
                cmd.Parameters.Add(m_database.CreateParameter("@RegionID", regionID.ToString()));
 | 
			
		||||
                cmd.Connection = conn;
 | 
			
		||||
                conn.Open();
 | 
			
		||||
                if (cmd.ExecuteNonQuery() == 0)
 | 
			
		||||
                    return false;
 | 
			
		||||
            }
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool VerifyAgent(UUID agentId, UUID secureSessionID)
 | 
			
		||||
        {
 | 
			
		||||
            PresenceData[] ret = Get("SecureSessionID",
 | 
			
		||||
                    secureSessionID.ToString());
 | 
			
		||||
            
 | 
			
		||||
            if (ret.Length == 0)
 | 
			
		||||
                return false;
 | 
			
		||||
 | 
			
		||||
            if(ret[0].UserID != agentId.ToString())
 | 
			
		||||
                return false;
 | 
			
		||||
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,352 @@
 | 
			
		|||
/*
 | 
			
		||||
 * 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.Data;
 | 
			
		||||
using System.Data.SqlClient;
 | 
			
		||||
using System.Drawing;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
using log4net;
 | 
			
		||||
using OpenMetaverse;
 | 
			
		||||
using OpenSim.Framework;
 | 
			
		||||
using OpenSim.Region.Framework.Interfaces;
 | 
			
		||||
using OpenSim.Region.Framework.Scenes;
 | 
			
		||||
using RegionFlags = OpenSim.Framework.RegionFlags;
 | 
			
		||||
 | 
			
		||||
namespace OpenSim.Data.MSSQL
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// A MSSQL Interface for the Region Server.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class MSSQLRegionData : IRegionData
 | 
			
		||||
    {
 | 
			
		||||
        private string m_Realm;
 | 
			
		||||
        private List<string> m_ColumnNames = null;
 | 
			
		||||
        private string m_ConnectionString;
 | 
			
		||||
        private MSSQLManager m_database;
 | 
			
		||||
        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 | 
			
		||||
 | 
			
		||||
        public MSSQLRegionData(string connectionString, string realm) 
 | 
			
		||||
        {
 | 
			
		||||
            m_Realm = realm;
 | 
			
		||||
            m_ConnectionString = connectionString;
 | 
			
		||||
            m_database = new MSSQLManager(connectionString);
 | 
			
		||||
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_ConnectionString))
 | 
			
		||||
            {
 | 
			
		||||
                conn.Open();
 | 
			
		||||
                Migration m = new Migration(conn, GetType().Assembly, "GridStore");
 | 
			
		||||
                m.Update();
 | 
			
		||||
            }
 | 
			
		||||
         }
 | 
			
		||||
 | 
			
		||||
        public List<RegionData> Get(string regionName, UUID scopeID)
 | 
			
		||||
        {
 | 
			
		||||
            string sql = "select * from ["+m_Realm+"] where regionName like @regionName";
 | 
			
		||||
            if (scopeID != UUID.Zero)
 | 
			
		||||
                sql += " and ScopeID = @scopeID";
 | 
			
		||||
            sql += " order by regionName";
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_ConnectionString))
 | 
			
		||||
            using (SqlCommand cmd = new SqlCommand(sql, conn))
 | 
			
		||||
            {
 | 
			
		||||
                cmd.Parameters.Add(m_database.CreateParameter("@regionName", regionName));
 | 
			
		||||
                cmd.Parameters.Add(m_database.CreateParameter("@scopeID", scopeID));
 | 
			
		||||
                conn.Open();
 | 
			
		||||
                return RunCommand(cmd);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public RegionData Get(int posX, int posY, UUID scopeID)
 | 
			
		||||
        {
 | 
			
		||||
            string sql = "select * from ["+m_Realm+"] where locX = @posX and locY = @posY";
 | 
			
		||||
            if (scopeID != UUID.Zero)
 | 
			
		||||
                sql += " and ScopeID = @scopeID";
 | 
			
		||||
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_ConnectionString))
 | 
			
		||||
            using (SqlCommand cmd = new SqlCommand(sql, conn))
 | 
			
		||||
            {
 | 
			
		||||
                cmd.Parameters.Add(m_database.CreateParameter("@posX", posX.ToString()));
 | 
			
		||||
                cmd.Parameters.Add(m_database.CreateParameter("@posY", posY.ToString()));
 | 
			
		||||
                cmd.Parameters.Add(m_database.CreateParameter("@scopeID", scopeID));
 | 
			
		||||
                conn.Open();
 | 
			
		||||
                List<RegionData> ret = RunCommand(cmd);
 | 
			
		||||
                if (ret.Count == 0)
 | 
			
		||||
                    return null;
 | 
			
		||||
 | 
			
		||||
                return ret[0];
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public RegionData Get(UUID regionID, UUID scopeID)
 | 
			
		||||
        {
 | 
			
		||||
            string sql = "select * from ["+m_Realm+"] where uuid = @regionID";
 | 
			
		||||
            if (scopeID != UUID.Zero)
 | 
			
		||||
                sql += " and ScopeID = @scopeID";
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_ConnectionString))
 | 
			
		||||
            using (SqlCommand cmd = new SqlCommand(sql, conn))
 | 
			
		||||
            {
 | 
			
		||||
                cmd.Parameters.Add(m_database.CreateParameter("@regionID", regionID));
 | 
			
		||||
                cmd.Parameters.Add(m_database.CreateParameter("@scopeID", scopeID));
 | 
			
		||||
                conn.Open();
 | 
			
		||||
                List<RegionData> ret = RunCommand(cmd);
 | 
			
		||||
                if (ret.Count == 0)
 | 
			
		||||
                    return null;
 | 
			
		||||
 | 
			
		||||
                return ret[0];
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public List<RegionData> Get(int startX, int startY, int endX, int endY, UUID scopeID)
 | 
			
		||||
        {
 | 
			
		||||
            string sql = "select * from ["+m_Realm+"] where locX between @startX and @endX and locY between @startY and @endY";
 | 
			
		||||
            if (scopeID != UUID.Zero)
 | 
			
		||||
                sql += " and ScopeID = @scopeID";
 | 
			
		||||
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_ConnectionString))
 | 
			
		||||
            using (SqlCommand cmd = new SqlCommand(sql, conn))
 | 
			
		||||
            {
 | 
			
		||||
                cmd.Parameters.Add(m_database.CreateParameter("@startX", startX));
 | 
			
		||||
                cmd.Parameters.Add(m_database.CreateParameter("@startY", startY));
 | 
			
		||||
                cmd.Parameters.Add(m_database.CreateParameter("@endX", endX));
 | 
			
		||||
                cmd.Parameters.Add(m_database.CreateParameter("@endY", endY));
 | 
			
		||||
                cmd.Parameters.Add(m_database.CreateParameter("@scopeID", scopeID));
 | 
			
		||||
                conn.Open();
 | 
			
		||||
                return RunCommand(cmd);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public List<RegionData> RunCommand(SqlCommand cmd)
 | 
			
		||||
        {
 | 
			
		||||
            List<RegionData> retList = new List<RegionData>();
 | 
			
		||||
 | 
			
		||||
            SqlDataReader result = cmd.ExecuteReader();
 | 
			
		||||
 | 
			
		||||
            while (result.Read())
 | 
			
		||||
            {
 | 
			
		||||
                RegionData ret = new RegionData();
 | 
			
		||||
                ret.Data = new Dictionary<string, object>();
 | 
			
		||||
 | 
			
		||||
                UUID regionID;
 | 
			
		||||
                UUID.TryParse(result["uuid"].ToString(), out regionID);
 | 
			
		||||
                ret.RegionID = regionID;
 | 
			
		||||
                UUID scope;
 | 
			
		||||
                UUID.TryParse(result["ScopeID"].ToString(), out scope);
 | 
			
		||||
                ret.ScopeID = scope;
 | 
			
		||||
                ret.RegionName = result["regionName"].ToString();
 | 
			
		||||
                ret.posX = Convert.ToInt32(result["locX"]);
 | 
			
		||||
                ret.posY = Convert.ToInt32(result["locY"]);
 | 
			
		||||
                ret.sizeX = Convert.ToInt32(result["sizeX"]);
 | 
			
		||||
                ret.sizeY = Convert.ToInt32(result["sizeY"]);
 | 
			
		||||
 | 
			
		||||
                if (m_ColumnNames == null)
 | 
			
		||||
                {
 | 
			
		||||
                    m_ColumnNames = new List<string>();
 | 
			
		||||
 | 
			
		||||
                    DataTable schemaTable = result.GetSchemaTable();
 | 
			
		||||
                    foreach (DataRow row in schemaTable.Rows)
 | 
			
		||||
                        m_ColumnNames.Add(row["ColumnName"].ToString());
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                foreach (string s in m_ColumnNames)
 | 
			
		||||
                {
 | 
			
		||||
                    if (s == "uuid")
 | 
			
		||||
                        continue;
 | 
			
		||||
                    if (s == "ScopeID")
 | 
			
		||||
                        continue;
 | 
			
		||||
                    if (s == "regionName")
 | 
			
		||||
                        continue;
 | 
			
		||||
                    if (s == "locX")
 | 
			
		||||
                        continue;
 | 
			
		||||
                    if (s == "locY")
 | 
			
		||||
                        continue;
 | 
			
		||||
 | 
			
		||||
                    ret.Data[s] = result[s].ToString();
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                retList.Add(ret);
 | 
			
		||||
            }
 | 
			
		||||
            return retList;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool Store(RegionData data)
 | 
			
		||||
        {
 | 
			
		||||
            if (data.Data.ContainsKey("uuid"))
 | 
			
		||||
                data.Data.Remove("uuid");
 | 
			
		||||
            if (data.Data.ContainsKey("ScopeID"))
 | 
			
		||||
                data.Data.Remove("ScopeID");
 | 
			
		||||
            if (data.Data.ContainsKey("regionName"))
 | 
			
		||||
                data.Data.Remove("regionName");
 | 
			
		||||
            if (data.Data.ContainsKey("posX"))
 | 
			
		||||
                data.Data.Remove("posX");
 | 
			
		||||
            if (data.Data.ContainsKey("posY"))
 | 
			
		||||
                data.Data.Remove("posY");
 | 
			
		||||
            if (data.Data.ContainsKey("sizeX"))
 | 
			
		||||
                data.Data.Remove("sizeX");
 | 
			
		||||
            if (data.Data.ContainsKey("sizeY"))
 | 
			
		||||
                data.Data.Remove("sizeY");
 | 
			
		||||
            if (data.Data.ContainsKey("locX"))
 | 
			
		||||
                data.Data.Remove("locX");
 | 
			
		||||
            if (data.Data.ContainsKey("locY"))
 | 
			
		||||
                data.Data.Remove("locY");
 | 
			
		||||
 | 
			
		||||
            string[] fields = new List<string>(data.Data.Keys).ToArray();
 | 
			
		||||
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_ConnectionString))
 | 
			
		||||
            using (SqlCommand cmd = new SqlCommand())
 | 
			
		||||
            {
 | 
			
		||||
 | 
			
		||||
                string update = "update [" + m_Realm + "] set locX=@posX, locY=@posY, sizeX=@sizeX, sizeY=@sizeY ";
 | 
			
		||||
                
 | 
			
		||||
                foreach (string field in fields)
 | 
			
		||||
                {
 | 
			
		||||
 | 
			
		||||
                    update += ", ";
 | 
			
		||||
                    update += "[" + field + "] = @" + field;
 | 
			
		||||
 | 
			
		||||
                    cmd.Parameters.Add(m_database.CreateParameter("@" + field, data.Data[field]));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                update += " where uuid = @regionID";
 | 
			
		||||
 | 
			
		||||
                if (data.ScopeID != UUID.Zero)
 | 
			
		||||
                    update += " and ScopeID = @scopeID";
 | 
			
		||||
 | 
			
		||||
                cmd.CommandText = update;
 | 
			
		||||
                cmd.Connection = conn;
 | 
			
		||||
                cmd.Parameters.Add(m_database.CreateParameter("@regionID", data.RegionID));
 | 
			
		||||
                cmd.Parameters.Add(m_database.CreateParameter("@regionName", data.RegionName));
 | 
			
		||||
                cmd.Parameters.Add(m_database.CreateParameter("@scopeID", data.ScopeID));
 | 
			
		||||
                cmd.Parameters.Add(m_database.CreateParameter("@posX", data.posX));
 | 
			
		||||
                cmd.Parameters.Add(m_database.CreateParameter("@posY", data.posY));
 | 
			
		||||
                cmd.Parameters.Add(m_database.CreateParameter("@sizeX", data.sizeX));
 | 
			
		||||
                cmd.Parameters.Add(m_database.CreateParameter("@sizeY", data.sizeY));
 | 
			
		||||
                conn.Open();
 | 
			
		||||
                try
 | 
			
		||||
                {
 | 
			
		||||
                    if (cmd.ExecuteNonQuery() < 1)
 | 
			
		||||
                    {
 | 
			
		||||
                        string insert = "insert into [" + m_Realm + "] ([uuid], [ScopeID], [locX], [locY], [sizeX], [sizeY], [regionName], [" +
 | 
			
		||||
                                String.Join("], [", fields) +
 | 
			
		||||
                                "]) values (@regionID, @scopeID, @posX, @posY, @sizeX, @sizeY, @regionName, @" + String.Join(", @", fields) + ")";
 | 
			
		||||
 | 
			
		||||
                        cmd.CommandText = insert;
 | 
			
		||||
 | 
			
		||||
                        try
 | 
			
		||||
                        {
 | 
			
		||||
                            if (cmd.ExecuteNonQuery() < 1)
 | 
			
		||||
                            {
 | 
			
		||||
                                return false;
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                        catch (Exception ex)
 | 
			
		||||
                        {
 | 
			
		||||
                            m_log.Warn("[MSSQL Grid]: Error inserting into Regions table: " + ex.Message + ", INSERT sql: " + insert);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                catch (Exception ex)
 | 
			
		||||
                {
 | 
			
		||||
                    m_log.Warn("[MSSQL Grid]: Error updating Regions table: " + ex.Message + ", UPDATE sql: " + update);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool SetDataItem(UUID regionID, string item, string value)
 | 
			
		||||
        {
 | 
			
		||||
            string sql = "update [" + m_Realm +
 | 
			
		||||
                    "] set [" + item + "] = @" + item + " where uuid = @UUID";
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_ConnectionString))
 | 
			
		||||
            using (SqlCommand cmd = new SqlCommand(sql, conn))
 | 
			
		||||
            {
 | 
			
		||||
                cmd.Parameters.Add(m_database.CreateParameter("@" + item, value));
 | 
			
		||||
                cmd.Parameters.Add(m_database.CreateParameter("@UUID", regionID));
 | 
			
		||||
                conn.Open();
 | 
			
		||||
                if (cmd.ExecuteNonQuery() > 0)
 | 
			
		||||
                    return true;
 | 
			
		||||
            }
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool Delete(UUID regionID)
 | 
			
		||||
        {
 | 
			
		||||
            string sql = "delete from [" + m_Realm +
 | 
			
		||||
                    "] where uuid = @UUID";
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_ConnectionString))
 | 
			
		||||
            using (SqlCommand cmd = new SqlCommand(sql, conn))
 | 
			
		||||
            {
 | 
			
		||||
                cmd.Parameters.Add(m_database.CreateParameter("@UUID", regionID));
 | 
			
		||||
                conn.Open();
 | 
			
		||||
                if (cmd.ExecuteNonQuery() > 0)
 | 
			
		||||
                    return true;
 | 
			
		||||
            }
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public List<RegionData> GetDefaultRegions(UUID scopeID)
 | 
			
		||||
        {
 | 
			
		||||
            return Get((int)RegionFlags.DefaultRegion, scopeID);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public List<RegionData> GetDefaultHypergridRegions(UUID scopeID)
 | 
			
		||||
        {
 | 
			
		||||
            return Get((int)RegionFlags.DefaultHGRegion, scopeID);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public List<RegionData> GetFallbackRegions(UUID scopeID, int x, int y)
 | 
			
		||||
        {
 | 
			
		||||
            List<RegionData> regions = Get((int)RegionFlags.FallbackRegion, scopeID);
 | 
			
		||||
            RegionDataDistanceCompare distanceComparer = new RegionDataDistanceCompare(x, y);
 | 
			
		||||
            regions.Sort(distanceComparer);
 | 
			
		||||
 | 
			
		||||
            return regions;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public List<RegionData> GetHyperlinks(UUID scopeID)
 | 
			
		||||
        {
 | 
			
		||||
            return Get((int)RegionFlags.Hyperlink, scopeID);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private List<RegionData> Get(int regionFlags, UUID scopeID)
 | 
			
		||||
        {
 | 
			
		||||
            string sql = "SELECT * FROM [" + m_Realm + "] WHERE (flags & " + regionFlags.ToString() + ") <> 0";
 | 
			
		||||
            if (scopeID != UUID.Zero)
 | 
			
		||||
                sql += " AND ScopeID = @scopeID";
 | 
			
		||||
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_ConnectionString))
 | 
			
		||||
            using (SqlCommand cmd = new SqlCommand(sql, conn))
 | 
			
		||||
            {
 | 
			
		||||
                cmd.Parameters.Add(m_database.CreateParameter("@scopeID", scopeID));
 | 
			
		||||
                conn.Open();
 | 
			
		||||
                return RunCommand(cmd);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| 
						 | 
				
			
			@ -0,0 +1,246 @@
 | 
			
		|||
/*
 | 
			
		||||
 * 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.Data;
 | 
			
		||||
using OpenMetaverse;
 | 
			
		||||
using OpenSim.Framework;
 | 
			
		||||
using System.Data.SqlClient;
 | 
			
		||||
using System.Text;
 | 
			
		||||
 | 
			
		||||
namespace OpenSim.Data.MSSQL
 | 
			
		||||
{
 | 
			
		||||
    public class MSSQLUserAccountData : MSSQLGenericTableHandler<UserAccountData>,IUserAccountData
 | 
			
		||||
    {
 | 
			
		||||
        public MSSQLUserAccountData(string connectionString, string realm) :
 | 
			
		||||
            base(connectionString, realm, "UserAccount")
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
        //private string m_Realm;
 | 
			
		||||
        //private List<string> m_ColumnNames = null;
 | 
			
		||||
        //private MSSQLManager m_database;
 | 
			
		||||
 | 
			
		||||
        //public MSSQLUserAccountData(string connectionString, string realm)
 | 
			
		||||
        //{
 | 
			
		||||
        //    m_Realm = realm;
 | 
			
		||||
        //    m_ConnectionString = connectionString;
 | 
			
		||||
        //    m_database = new MSSQLManager(connectionString);
 | 
			
		||||
 | 
			
		||||
        //    using (SqlConnection conn = new SqlConnection(m_ConnectionString))
 | 
			
		||||
        //    {
 | 
			
		||||
        //        conn.Open();
 | 
			
		||||
        //        Migration m = new Migration(conn, GetType().Assembly, "UserStore");
 | 
			
		||||
        //        m.Update();
 | 
			
		||||
        //    }
 | 
			
		||||
        //}
 | 
			
		||||
 | 
			
		||||
        //public List<UserAccountData> Query(UUID principalID, UUID scopeID, string query)
 | 
			
		||||
        //{
 | 
			
		||||
        //    return null;
 | 
			
		||||
        //}
 | 
			
		||||
 | 
			
		||||
        //public UserAccountData Get(UUID principalID, UUID scopeID)
 | 
			
		||||
        //{
 | 
			
		||||
        //    UserAccountData ret = new UserAccountData();
 | 
			
		||||
        //    ret.Data = new Dictionary<string, string>();
 | 
			
		||||
 | 
			
		||||
        //    string sql = string.Format("select * from {0} where UUID = @principalID", m_Realm);
 | 
			
		||||
        //    if (scopeID != UUID.Zero)
 | 
			
		||||
        //        sql += " and ScopeID = @scopeID";
 | 
			
		||||
 | 
			
		||||
        //    using (SqlConnection conn = new SqlConnection(m_ConnectionString))
 | 
			
		||||
        //    using (SqlCommand cmd = new SqlCommand(sql, conn))
 | 
			
		||||
        //    {
 | 
			
		||||
        //        cmd.Parameters.Add(m_database.CreateParameter("@principalID", principalID));
 | 
			
		||||
        //        cmd.Parameters.Add(m_database.CreateParameter("@scopeID", scopeID));
 | 
			
		||||
                
 | 
			
		||||
        //        conn.Open();
 | 
			
		||||
        //        using (SqlDataReader result = cmd.ExecuteReader())
 | 
			
		||||
        //        {
 | 
			
		||||
        //            if (result.Read())
 | 
			
		||||
        //            {
 | 
			
		||||
        //                ret.PrincipalID = principalID;
 | 
			
		||||
        //                UUID scope;
 | 
			
		||||
        //                UUID.TryParse(result["ScopeID"].ToString(), out scope);
 | 
			
		||||
        //                ret.ScopeID = scope;
 | 
			
		||||
 | 
			
		||||
        //                if (m_ColumnNames == null)
 | 
			
		||||
        //                {
 | 
			
		||||
        //                    m_ColumnNames = new List<string>();
 | 
			
		||||
 | 
			
		||||
        //                    DataTable schemaTable = result.GetSchemaTable();
 | 
			
		||||
        //                    foreach (DataRow row in schemaTable.Rows)
 | 
			
		||||
        //                        m_ColumnNames.Add(row["ColumnName"].ToString());
 | 
			
		||||
        //                }
 | 
			
		||||
 | 
			
		||||
        //                foreach (string s in m_ColumnNames)
 | 
			
		||||
        //                {
 | 
			
		||||
        //                    if (s == "UUID")
 | 
			
		||||
        //                        continue;
 | 
			
		||||
        //                    if (s == "ScopeID")
 | 
			
		||||
        //                        continue;
 | 
			
		||||
 | 
			
		||||
        //                    ret.Data[s] = result[s].ToString();
 | 
			
		||||
        //                }
 | 
			
		||||
        //                return ret;
 | 
			
		||||
        //            }
 | 
			
		||||
        //        }
 | 
			
		||||
        //    }
 | 
			
		||||
        //    return null;
 | 
			
		||||
        //}
 | 
			
		||||
 | 
			
		||||
        //public bool Store(UserAccountData data)
 | 
			
		||||
        //{
 | 
			
		||||
        //    if (data.Data.ContainsKey("UUID"))
 | 
			
		||||
        //        data.Data.Remove("UUID");
 | 
			
		||||
        //    if (data.Data.ContainsKey("ScopeID"))
 | 
			
		||||
        //        data.Data.Remove("ScopeID");
 | 
			
		||||
 | 
			
		||||
        //    string[] fields = new List<string>(data.Data.Keys).ToArray();
 | 
			
		||||
 | 
			
		||||
        //    using (SqlConnection conn = new SqlConnection(m_ConnectionString))
 | 
			
		||||
        //    using (SqlCommand cmd = new SqlCommand())
 | 
			
		||||
        //    {
 | 
			
		||||
        //        StringBuilder updateBuilder = new StringBuilder();
 | 
			
		||||
        //        updateBuilder.AppendFormat("update {0} set ", m_Realm);
 | 
			
		||||
        //        bool first = true;
 | 
			
		||||
        //        foreach (string field in fields)
 | 
			
		||||
        //        {
 | 
			
		||||
        //            if (!first)
 | 
			
		||||
        //                updateBuilder.Append(", ");
 | 
			
		||||
        //            updateBuilder.AppendFormat("{0} = @{0}", field);
 | 
			
		||||
 | 
			
		||||
        //            first = false;
 | 
			
		||||
        //            cmd.Parameters.Add(m_database.CreateParameter("@" + field, data.Data[field]));
 | 
			
		||||
        //        }
 | 
			
		||||
 | 
			
		||||
        //        updateBuilder.Append(" where UUID = @principalID");
 | 
			
		||||
 | 
			
		||||
        //        if (data.ScopeID != UUID.Zero)
 | 
			
		||||
        //            updateBuilder.Append(" and ScopeID = @scopeID");
 | 
			
		||||
 | 
			
		||||
        //        cmd.CommandText = updateBuilder.ToString();
 | 
			
		||||
        //        cmd.Connection = conn;
 | 
			
		||||
        //        cmd.Parameters.Add(m_database.CreateParameter("@principalID", data.PrincipalID));
 | 
			
		||||
        //        cmd.Parameters.Add(m_database.CreateParameter("@scopeID", data.ScopeID));
 | 
			
		||||
        //        conn.Open();
 | 
			
		||||
 | 
			
		||||
        //        if (cmd.ExecuteNonQuery() < 1)
 | 
			
		||||
        //        {
 | 
			
		||||
        //            StringBuilder insertBuilder = new StringBuilder();
 | 
			
		||||
        //            insertBuilder.AppendFormat("insert into {0} (UUID, ScopeID, ", m_Realm);
 | 
			
		||||
        //            insertBuilder.Append(String.Join(", ", fields));
 | 
			
		||||
        //            insertBuilder.Append(") values (@principalID, @scopeID, @");
 | 
			
		||||
        //            insertBuilder.Append(String.Join(", @", fields));
 | 
			
		||||
        //            insertBuilder.Append(")");
 | 
			
		||||
 | 
			
		||||
        //            cmd.CommandText = insertBuilder.ToString();
 | 
			
		||||
 | 
			
		||||
        //            if (cmd.ExecuteNonQuery() < 1)
 | 
			
		||||
        //            {
 | 
			
		||||
        //                return false;
 | 
			
		||||
        //            }
 | 
			
		||||
        //        }
 | 
			
		||||
        //    }
 | 
			
		||||
        //    return true;
 | 
			
		||||
        //}
 | 
			
		||||
 | 
			
		||||
        //public bool Store(UserAccountData data, UUID principalID, string token)
 | 
			
		||||
        //{
 | 
			
		||||
        //    return false;
 | 
			
		||||
        //}
 | 
			
		||||
 | 
			
		||||
        //public bool SetDataItem(UUID principalID, string item, string value)
 | 
			
		||||
        //{
 | 
			
		||||
        //    string sql = string.Format("update {0} set {1} = @{1} where UUID = @UUID", m_Realm, item);
 | 
			
		||||
        //    using (SqlConnection conn = new SqlConnection(m_ConnectionString))
 | 
			
		||||
        //    using (SqlCommand cmd = new SqlCommand(sql, conn))
 | 
			
		||||
        //    {
 | 
			
		||||
        //        cmd.Parameters.Add(m_database.CreateParameter("@" + item, value));
 | 
			
		||||
        //        cmd.Parameters.Add(m_database.CreateParameter("@UUID", principalID));
 | 
			
		||||
 | 
			
		||||
        //        conn.Open();
 | 
			
		||||
 | 
			
		||||
        //        if (cmd.ExecuteNonQuery() > 0)
 | 
			
		||||
        //            return true;
 | 
			
		||||
        //    }
 | 
			
		||||
        //    return false;
 | 
			
		||||
        //}
 | 
			
		||||
 | 
			
		||||
        //public UserAccountData[] Get(string[] keys, string[] vals)
 | 
			
		||||
        //{
 | 
			
		||||
        //    return null;
 | 
			
		||||
        //}
 | 
			
		||||
 | 
			
		||||
        public UserAccountData[] GetUsers(UUID scopeID, string query)
 | 
			
		||||
        {
 | 
			
		||||
            string[] words = query.Split(new char[] { ' ' });
 | 
			
		||||
 | 
			
		||||
            for (int i = 0; i < words.Length; i++)
 | 
			
		||||
            {
 | 
			
		||||
                if (words[i].Length < 3)
 | 
			
		||||
                {
 | 
			
		||||
                    if (i != words.Length - 1)
 | 
			
		||||
                        Array.Copy(words, i + 1, words, i, words.Length - i - 1);
 | 
			
		||||
                    Array.Resize(ref words, words.Length - 1);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (words.Length == 0)
 | 
			
		||||
                return new UserAccountData[0];
 | 
			
		||||
 | 
			
		||||
            if (words.Length > 2)
 | 
			
		||||
                return new UserAccountData[0];
 | 
			
		||||
 | 
			
		||||
            string sql = "";
 | 
			
		||||
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_ConnectionString))
 | 
			
		||||
            using (SqlCommand cmd = new SqlCommand())
 | 
			
		||||
            {
 | 
			
		||||
                if (words.Length == 1)
 | 
			
		||||
                {
 | 
			
		||||
                    sql = String.Format("select * from {0} where ([ScopeID]=@ScopeID or [ScopeID]='00000000-0000-0000-0000-000000000000') and ([FirstName] like @search or [LastName] like @search)", m_Realm);
 | 
			
		||||
                    cmd.Parameters.Add(m_database.CreateParameter("@scopeID", scopeID));
 | 
			
		||||
                    cmd.Parameters.Add(m_database.CreateParameter("@search", "%" + words[0] + "%"));
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    sql = String.Format("select * from {0} where ([ScopeID]=@ScopeID or [ScopeID]='00000000-0000-0000-0000-000000000000') and ([FirstName] like @searchFirst or [LastName] like @searchLast)", m_Realm);
 | 
			
		||||
                    cmd.Parameters.Add(m_database.CreateParameter("@searchFirst", "%" + words[0] + "%"));
 | 
			
		||||
                    cmd.Parameters.Add(m_database.CreateParameter("@searchLast", "%" + words[1] + "%"));
 | 
			
		||||
                    cmd.Parameters.Add(m_database.CreateParameter("@ScopeID", scopeID.ToString()));
 | 
			
		||||
                }
 | 
			
		||||
                cmd.Connection = conn;
 | 
			
		||||
                cmd.CommandText = sql;
 | 
			
		||||
                conn.Open();
 | 
			
		||||
                return DoQuery(cmd);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,305 @@
 | 
			
		|||
/*
 | 
			
		||||
 * 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.Data;
 | 
			
		||||
using OpenMetaverse;
 | 
			
		||||
using OpenSim.Framework;
 | 
			
		||||
using System.Data.SqlClient;
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using log4net;
 | 
			
		||||
 | 
			
		||||
namespace OpenSim.Data.MSSQL
 | 
			
		||||
{
 | 
			
		||||
    public class MSSQLXInventoryData : IXInventoryData
 | 
			
		||||
    {
 | 
			
		||||
//        private static readonly ILog m_log = LogManager.GetLogger(
 | 
			
		||||
//                MethodBase.GetCurrentMethod().DeclaringType);
 | 
			
		||||
 | 
			
		||||
        private MSSQLFolderHandler m_Folders;
 | 
			
		||||
        private MSSQLItemHandler m_Items;
 | 
			
		||||
 | 
			
		||||
        public MSSQLXInventoryData(string conn, string realm)
 | 
			
		||||
        {
 | 
			
		||||
            m_Folders = new MSSQLFolderHandler(
 | 
			
		||||
                    conn, "inventoryfolders", "InventoryStore");
 | 
			
		||||
            m_Items = new MSSQLItemHandler(
 | 
			
		||||
                    conn, "inventoryitems", String.Empty);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public XInventoryFolder[] GetFolders(string[] fields, string[] vals)
 | 
			
		||||
        {
 | 
			
		||||
            return m_Folders.Get(fields, vals);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public XInventoryItem[] GetItems(string[] fields, string[] vals)
 | 
			
		||||
        {
 | 
			
		||||
            return m_Items.Get(fields, vals);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool StoreFolder(XInventoryFolder folder)
 | 
			
		||||
        {
 | 
			
		||||
            if (folder.folderName.Length > 64)
 | 
			
		||||
                folder.folderName = folder.folderName.Substring(0, 64);
 | 
			
		||||
            return m_Folders.Store(folder);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool StoreItem(XInventoryItem item)
 | 
			
		||||
        {
 | 
			
		||||
            if (item.inventoryName.Length > 64)
 | 
			
		||||
                item.inventoryName = item.inventoryName.Substring(0, 64);
 | 
			
		||||
            if (item.inventoryDescription.Length > 128)
 | 
			
		||||
                item.inventoryDescription = item.inventoryDescription.Substring(0, 128);
 | 
			
		||||
 | 
			
		||||
            return m_Items.Store(item);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool DeleteFolders(string field, string val)
 | 
			
		||||
        {
 | 
			
		||||
            return m_Folders.Delete(field, val);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool DeleteFolders(string[] fields, string[] vals)
 | 
			
		||||
        {
 | 
			
		||||
            return m_Folders.Delete(fields, vals);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool DeleteItems(string field, string val)
 | 
			
		||||
        {
 | 
			
		||||
            return m_Items.Delete(field, val);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool DeleteItems(string[] fields, string[] vals)
 | 
			
		||||
        {
 | 
			
		||||
            return m_Items.Delete(fields, vals);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool MoveItem(string id, string newParent)
 | 
			
		||||
        {
 | 
			
		||||
            return m_Items.MoveItem(id, newParent);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool MoveFolder(string id, string newParent)
 | 
			
		||||
        {
 | 
			
		||||
            return m_Folders.MoveFolder(id, newParent);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public XInventoryItem[] GetActiveGestures(UUID principalID)
 | 
			
		||||
        {
 | 
			
		||||
            return m_Items.GetActiveGestures(principalID);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public int GetAssetPermissions(UUID principalID, UUID assetID)
 | 
			
		||||
        {
 | 
			
		||||
            return m_Items.GetAssetPermissions(principalID, assetID);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class MSSQLItemHandler : MSSQLInventoryHandler<XInventoryItem>
 | 
			
		||||
    {
 | 
			
		||||
        public MSSQLItemHandler(string c, string t, string m) :
 | 
			
		||||
            base(c, t, m)
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool MoveItem(string id, string newParent)
 | 
			
		||||
        {
 | 
			
		||||
            XInventoryItem[] retrievedItems = Get(new string[] { "inventoryID" }, new string[] { id });
 | 
			
		||||
            if (retrievedItems.Length == 0)
 | 
			
		||||
                return false;
 | 
			
		||||
 | 
			
		||||
            UUID oldParent = retrievedItems[0].parentFolderID;
 | 
			
		||||
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_ConnectionString))
 | 
			
		||||
            {
 | 
			
		||||
                using (SqlCommand cmd = new SqlCommand())
 | 
			
		||||
                {
 | 
			
		||||
 | 
			
		||||
                    cmd.CommandText = String.Format("update {0} set parentFolderID = @ParentFolderID where inventoryID = @InventoryID", m_Realm);
 | 
			
		||||
                    cmd.Parameters.Add(m_database.CreateParameter("@ParentFolderID", newParent));
 | 
			
		||||
                    cmd.Parameters.Add(m_database.CreateParameter("@InventoryID", id));
 | 
			
		||||
                    cmd.Connection = conn;
 | 
			
		||||
                    conn.Open();
 | 
			
		||||
 | 
			
		||||
                    if (cmd.ExecuteNonQuery() == 0)
 | 
			
		||||
                        return false;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            IncrementFolderVersion(oldParent);
 | 
			
		||||
            IncrementFolderVersion(newParent);
 | 
			
		||||
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public XInventoryItem[] GetActiveGestures(UUID principalID)
 | 
			
		||||
        {
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_ConnectionString))
 | 
			
		||||
            {
 | 
			
		||||
                using (SqlCommand cmd = new SqlCommand())
 | 
			
		||||
                {
 | 
			
		||||
                    cmd.CommandText = String.Format("select * from inventoryitems where avatarId = @uuid and assetType = @type and flags = 1", m_Realm);
 | 
			
		||||
 | 
			
		||||
                    cmd.Parameters.Add(m_database.CreateParameter("@uuid", principalID.ToString()));
 | 
			
		||||
                    cmd.Parameters.Add(m_database.CreateParameter("@type", (int)AssetType.Gesture));
 | 
			
		||||
                    cmd.Connection = conn;
 | 
			
		||||
                    conn.Open();
 | 
			
		||||
                    return DoQuery(cmd);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public int GetAssetPermissions(UUID principalID, UUID assetID)
 | 
			
		||||
        {
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_ConnectionString))
 | 
			
		||||
            {
 | 
			
		||||
                using (SqlCommand cmd = new SqlCommand())
 | 
			
		||||
                {
 | 
			
		||||
                    cmd.CommandText = String.Format("select bit_or(inventoryCurrentPermissions) as inventoryCurrentPermissions from inventoryitems where avatarID = @PrincipalID and assetID = @AssetID group by assetID", m_Realm);
 | 
			
		||||
                    cmd.Parameters.Add(m_database.CreateParameter("@PrincipalID", principalID.ToString()));
 | 
			
		||||
                    cmd.Parameters.Add(m_database.CreateParameter("@AssetID", assetID.ToString()));
 | 
			
		||||
                    cmd.Connection = conn;
 | 
			
		||||
                    conn.Open();
 | 
			
		||||
                    using (SqlDataReader reader = cmd.ExecuteReader())
 | 
			
		||||
                    {
 | 
			
		||||
 | 
			
		||||
                        int perms = 0;
 | 
			
		||||
 | 
			
		||||
                        if (reader.Read())
 | 
			
		||||
                        {
 | 
			
		||||
                            perms = Convert.ToInt32(reader["inventoryCurrentPermissions"]);
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        return perms;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override bool Store(XInventoryItem item)
 | 
			
		||||
        {
 | 
			
		||||
            if (!base.Store(item))
 | 
			
		||||
                return false;
 | 
			
		||||
 | 
			
		||||
            IncrementFolderVersion(item.parentFolderID);
 | 
			
		||||
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class MSSQLFolderHandler : MSSQLInventoryHandler<XInventoryFolder>
 | 
			
		||||
    {
 | 
			
		||||
        public MSSQLFolderHandler(string c, string t, string m) :
 | 
			
		||||
            base(c, t, m)
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool MoveFolder(string id, string newParentFolderID)
 | 
			
		||||
        {
 | 
			
		||||
            XInventoryFolder[] folders = Get(new string[] { "folderID" }, new string[] { id });
 | 
			
		||||
 | 
			
		||||
            if (folders.Length == 0)
 | 
			
		||||
                return false;
 | 
			
		||||
 | 
			
		||||
            UUID oldParentFolderUUID = folders[0].parentFolderID;
 | 
			
		||||
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_ConnectionString))
 | 
			
		||||
            {
 | 
			
		||||
                using (SqlCommand cmd = new SqlCommand())
 | 
			
		||||
                {
 | 
			
		||||
 | 
			
		||||
                    cmd.CommandText = String.Format("update {0} set parentFolderID = @ParentFolderID where folderID = @folderID", m_Realm);
 | 
			
		||||
                    cmd.Parameters.Add(m_database.CreateParameter("@ParentFolderID", newParentFolderID));
 | 
			
		||||
                    cmd.Parameters.Add(m_database.CreateParameter("@folderID", id));
 | 
			
		||||
                    cmd.Connection = conn;
 | 
			
		||||
                    conn.Open();
 | 
			
		||||
 | 
			
		||||
                    if (cmd.ExecuteNonQuery() == 0)
 | 
			
		||||
                        return false;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            IncrementFolderVersion(oldParentFolderUUID);
 | 
			
		||||
            IncrementFolderVersion(newParentFolderID);
 | 
			
		||||
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override bool Store(XInventoryFolder folder)
 | 
			
		||||
        {
 | 
			
		||||
            if (!base.Store(folder))
 | 
			
		||||
                return false;
 | 
			
		||||
 | 
			
		||||
            IncrementFolderVersion(folder.parentFolderID);
 | 
			
		||||
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class MSSQLInventoryHandler<T> : MSSQLGenericTableHandler<T> where T: class, new()
 | 
			
		||||
    {
 | 
			
		||||
        public MSSQLInventoryHandler(string c, string t, string m) : base(c, t, m) {}
 | 
			
		||||
 | 
			
		||||
        protected bool IncrementFolderVersion(UUID folderID)
 | 
			
		||||
        {
 | 
			
		||||
            return IncrementFolderVersion(folderID.ToString());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected bool IncrementFolderVersion(string folderID)
 | 
			
		||||
        {
 | 
			
		||||
//            m_log.DebugFormat("[MYSQL ITEM HANDLER]: Incrementing version on folder {0}", folderID);
 | 
			
		||||
//            Util.PrintCallStack();
 | 
			
		||||
 | 
			
		||||
            string sql = "update inventoryfolders set version=version+1 where folderID = ?folderID";
 | 
			
		||||
            
 | 
			
		||||
            using (SqlConnection conn = new SqlConnection(m_ConnectionString))
 | 
			
		||||
            {
 | 
			
		||||
                using (SqlCommand cmd = new SqlCommand(sql, conn))
 | 
			
		||||
                {
 | 
			
		||||
                    conn.Open();
 | 
			
		||||
 | 
			
		||||
                    cmd.Parameters.AddWithValue("@folderID", folderID);
 | 
			
		||||
 | 
			
		||||
                    try
 | 
			
		||||
                    {
 | 
			
		||||
                        cmd.ExecuteNonQuery();
 | 
			
		||||
                    }
 | 
			
		||||
                    catch (Exception)
 | 
			
		||||
                    {
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,65 @@
 | 
			
		|||
/*
 | 
			
		||||
 * 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.Reflection;
 | 
			
		||||
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.Data.MSSQL")]
 | 
			
		||||
[assembly : AssemblyDescription("")]
 | 
			
		||||
[assembly : AssemblyConfiguration("")]
 | 
			
		||||
[assembly : AssemblyCompany("http://opensimulator.org")]
 | 
			
		||||
[assembly : AssemblyProduct("OpenSim.Data.MSSQL")]
 | 
			
		||||
[assembly : AssemblyCopyright("Copyright (c) OpenSimulator.org Developers 2007-2009")]
 | 
			
		||||
[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("0e1c1ca4-2cf2-4315-b0e7-432c02feea8a")]
 | 
			
		||||
 | 
			
		||||
// Version information for an assembly consists of the following four values:
 | 
			
		||||
//
 | 
			
		||||
//      Major Version
 | 
			
		||||
//      Minor Version
 | 
			
		||||
//      Build Number
 | 
			
		||||
//      Revision
 | 
			
		||||
//
 | 
			
		||||
// You can specify all the values or you can default the Revision and Build Numbers
 | 
			
		||||
// by using the '*' as shown below:
 | 
			
		||||
 | 
			
		||||
[assembly : AssemblyVersion("0.8.0.*")]
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,106 @@
 | 
			
		|||
:VERSION 1
 | 
			
		||||
 | 
			
		||||
CREATE TABLE [assets] (
 | 
			
		||||
  [id] [varchar](36) NOT NULL,
 | 
			
		||||
  [name] [varchar](64) NOT NULL,
 | 
			
		||||
  [description] [varchar](64) NOT NULL,
 | 
			
		||||
  [assetType] [tinyint] NOT NULL,
 | 
			
		||||
  [local] [tinyint] NOT NULL,
 | 
			
		||||
  [temporary] [tinyint] NOT NULL,
 | 
			
		||||
  [data] [image] NOT NULL,
 | 
			
		||||
PRIMARY KEY CLUSTERED 
 | 
			
		||||
(
 | 
			
		||||
	[id] ASC
 | 
			
		||||
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
 | 
			
		||||
) ON [PRIMARY]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
:VERSION 2
 | 
			
		||||
 | 
			
		||||
BEGIN TRANSACTION
 | 
			
		||||
 | 
			
		||||
CREATE TABLE Tmp_assets
 | 
			
		||||
	(
 | 
			
		||||
	id varchar(36) NOT NULL,
 | 
			
		||||
	name varchar(64) NOT NULL,
 | 
			
		||||
	description varchar(64) NOT NULL,
 | 
			
		||||
	assetType tinyint NOT NULL,
 | 
			
		||||
	local bit NOT NULL,
 | 
			
		||||
	temporary bit NOT NULL,
 | 
			
		||||
	data image NOT NULL
 | 
			
		||||
	)  ON [PRIMARY]
 | 
			
		||||
	 TEXTIMAGE_ON [PRIMARY]
 | 
			
		||||
 | 
			
		||||
IF EXISTS(SELECT * FROM assets)
 | 
			
		||||
	 EXEC('INSERT INTO Tmp_assets (id, name, description, assetType, local, temporary, data)
 | 
			
		||||
		SELECT id, name, description, assetType, CONVERT(bit, local), CONVERT(bit, temporary), data FROM assets WITH (HOLDLOCK TABLOCKX)')
 | 
			
		||||
 | 
			
		||||
DROP TABLE assets
 | 
			
		||||
 | 
			
		||||
EXECUTE sp_rename N'Tmp_assets', N'assets', 'OBJECT' 
 | 
			
		||||
 | 
			
		||||
ALTER TABLE dbo.assets ADD CONSTRAINT
 | 
			
		||||
	PK__assets__id PRIMARY KEY CLUSTERED 
 | 
			
		||||
	(
 | 
			
		||||
	id
 | 
			
		||||
	) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
 | 
			
		||||
 | 
			
		||||
COMMIT
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
:VERSION 3
 | 
			
		||||
 | 
			
		||||
BEGIN TRANSACTION
 | 
			
		||||
 | 
			
		||||
ALTER TABLE assets add create_time integer default 0
 | 
			
		||||
ALTER TABLE assets add access_time integer default 0
 | 
			
		||||
 | 
			
		||||
COMMIT
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
:VERSION 4
 | 
			
		||||
 | 
			
		||||
BEGIN TRANSACTION
 | 
			
		||||
 | 
			
		||||
CREATE TABLE dbo.Tmp_assets
 | 
			
		||||
	(
 | 
			
		||||
	id uniqueidentifier NOT NULL,
 | 
			
		||||
	name varchar(64) NOT NULL,
 | 
			
		||||
	description varchar(64) NOT NULL,
 | 
			
		||||
	assetType tinyint NOT NULL,
 | 
			
		||||
	local bit NOT NULL,
 | 
			
		||||
	temporary bit NOT NULL,
 | 
			
		||||
	data image NOT NULL,
 | 
			
		||||
	create_time int NULL,
 | 
			
		||||
	access_time int NULL
 | 
			
		||||
	)  ON [PRIMARY]
 | 
			
		||||
	 TEXTIMAGE_ON [PRIMARY]
 | 
			
		||||
 | 
			
		||||
IF EXISTS(SELECT * FROM dbo.assets)
 | 
			
		||||
	 EXEC('INSERT INTO dbo.Tmp_assets (id, name, description, assetType, local, temporary, data, create_time, access_time)
 | 
			
		||||
		SELECT CONVERT(uniqueidentifier, id), name, description, assetType, local, temporary, data, create_time, access_time FROM dbo.assets WITH (HOLDLOCK TABLOCKX)')
 | 
			
		||||
 | 
			
		||||
DROP TABLE assets
 | 
			
		||||
 | 
			
		||||
EXECUTE sp_rename N'Tmp_assets', N'assets', 'OBJECT' 
 | 
			
		||||
 | 
			
		||||
ALTER TABLE dbo.assets ADD CONSTRAINT
 | 
			
		||||
	PK__assets__id PRIMARY KEY CLUSTERED 
 | 
			
		||||
	(
 | 
			
		||||
	id
 | 
			
		||||
	) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
 | 
			
		||||
 | 
			
		||||
COMMIT
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
:VERSION 5
 | 
			
		||||
 | 
			
		||||
DELETE FROM assets WHERE id = 'dc4b9f0b-d008-45c6-96a4-01dd947ac621';
 | 
			
		||||
 | 
			
		||||
:VERSION 6
 | 
			
		||||
 | 
			
		||||
ALTER TABLE assets ADD asset_flags INTEGER NOT NULL DEFAULT 0;
 | 
			
		||||
 | 
			
		||||
:VERSION 7
 | 
			
		||||
 | 
			
		||||
alter table assets add creatorid varchar(36) not null default '';
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,32 @@
 | 
			
		|||
:VERSION 1
 | 
			
		||||
 | 
			
		||||
BEGIN TRANSACTION
 | 
			
		||||
 | 
			
		||||
CREATE TABLE [auth] (
 | 
			
		||||
  [uuid] [uniqueidentifier] NOT NULL default '00000000-0000-0000-0000-000000000000',
 | 
			
		||||
  [passwordHash] [varchar](32) NOT NULL,
 | 
			
		||||
  [passwordSalt] [varchar](32) NOT NULL,
 | 
			
		||||
  [webLoginKey] [varchar](255) NOT NULL,
 | 
			
		||||
  [accountType] VARCHAR(32) NOT NULL DEFAULT 'UserAccount',
 | 
			
		||||
) ON [PRIMARY]
 | 
			
		||||
 | 
			
		||||
CREATE TABLE [tokens] (
 | 
			
		||||
  [uuid] [uniqueidentifier] NOT NULL default '00000000-0000-0000-0000-000000000000',
 | 
			
		||||
  [token] [varchar](255) NOT NULL,
 | 
			
		||||
  [validity] [datetime] NOT NULL )
 | 
			
		||||
  ON [PRIMARY]
 | 
			
		||||
 | 
			
		||||
COMMIT
 | 
			
		||||
 | 
			
		||||
:VERSION 2
 | 
			
		||||
 | 
			
		||||
BEGIN TRANSACTION
 | 
			
		||||
 | 
			
		||||
IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[users]') AND type in (N'U'))
 | 
			
		||||
	INSERT INTO auth (UUID, passwordHash, passwordSalt, webLoginKey, accountType) SELECT [UUID] AS UUID, [passwordHash] AS passwordHash, [passwordSalt] AS passwordSalt, [webLoginKey] AS webLoginKey, 'UserAccount' as [accountType] FROM users;
 | 
			
		||||
 | 
			
		||||
COMMIT
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,64 @@
 | 
			
		|||
:VERSION 1
 | 
			
		||||
 | 
			
		||||
BEGIN TRANSACTION
 | 
			
		||||
 | 
			
		||||
CREATE TABLE [Avatars] (
 | 
			
		||||
[PrincipalID] uniqueidentifier NOT NULL, 
 | 
			
		||||
[Name] varchar(32) NOT NULL, 
 | 
			
		||||
[Value] varchar(255) NOT NULL DEFAULT '',
 | 
			
		||||
PRIMARY KEY CLUSTERED 
 | 
			
		||||
(
 | 
			
		||||
	[PrincipalID] ASC, [Name] ASC
 | 
			
		||||
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
 | 
			
		||||
) ON [PRIMARY]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
COMMIT
 | 
			
		||||
 | 
			
		||||
:VERSION 2
 | 
			
		||||
 | 
			
		||||
BEGIN TRANSACTION
 | 
			
		||||
 | 
			
		||||
CREATE TABLE dbo.Tmp_Avatars
 | 
			
		||||
	(
 | 
			
		||||
	PrincipalID uniqueidentifier NOT NULL,
 | 
			
		||||
	[Name] varchar(32) NOT NULL, 
 | 
			
		||||
	Value text NOT NULL DEFAULT '',
 | 
			
		||||
	)  ON [PRIMARY]
 | 
			
		||||
	 TEXTIMAGE_ON [PRIMARY]
 | 
			
		||||
 | 
			
		||||
IF EXISTS(SELECT * FROM dbo.Avatars)
 | 
			
		||||
	 EXEC('INSERT INTO dbo.Tmp_Avatars (PrincipalID, Name, Value)
 | 
			
		||||
		SELECT PrincipalID, CONVERT(text, Name), Value FROM dbo.Avatars WITH (HOLDLOCK TABLOCKX)')
 | 
			
		||||
 | 
			
		||||
DROP TABLE dbo.Avatars
 | 
			
		||||
 | 
			
		||||
EXECUTE sp_rename N'dbo.Tmp_Avatars', N'Avatars', 'OBJECT' 
 | 
			
		||||
 | 
			
		||||
COMMIT
 | 
			
		||||
 | 
			
		||||
:VERSION 3
 | 
			
		||||
 | 
			
		||||
BEGIN TRANSACTION
 | 
			
		||||
 | 
			
		||||
CREATE TABLE dbo.Tmp_Avatars
 | 
			
		||||
	(
 | 
			
		||||
	PrincipalID uniqueidentifier NOT NULL,
 | 
			
		||||
	[Name] varchar(32) NOT NULL, 
 | 
			
		||||
	Value text NOT NULL DEFAULT '',
 | 
			
		||||
	PRIMARY KEY CLUSTERED 
 | 
			
		||||
(
 | 
			
		||||
	[PrincipalID] ASC, [Name] ASC
 | 
			
		||||
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
 | 
			
		||||
)  ON [PRIMARY]
 | 
			
		||||
	 TEXTIMAGE_ON [PRIMARY]
 | 
			
		||||
 | 
			
		||||
IF EXISTS(SELECT * FROM dbo.Avatars)
 | 
			
		||||
	 EXEC('INSERT INTO dbo.Tmp_Avatars (PrincipalID, Name, Value)
 | 
			
		||||
		SELECT PrincipalID, CONVERT(text, Name), Value FROM dbo.Avatars WITH (HOLDLOCK TABLOCKX)')
 | 
			
		||||
 | 
			
		||||
DROP TABLE dbo.Avatars
 | 
			
		||||
 | 
			
		||||
EXECUTE sp_rename N'dbo.Tmp_Avatars', N'Avatars', 'OBJECT' 
 | 
			
		||||
COMMIT
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,334 @@
 | 
			
		|||
:VERSION 1
 | 
			
		||||
 | 
			
		||||
BEGIN TRANSACTION
 | 
			
		||||
 | 
			
		||||
CREATE TABLE [dbo].[estate_managers](
 | 
			
		||||
	[EstateID] [int] NOT NULL,
 | 
			
		||||
	[uuid] [varchar](36) NOT NULL,
 | 
			
		||||
 CONSTRAINT [PK_estate_managers] PRIMARY KEY CLUSTERED 
 | 
			
		||||
(
 | 
			
		||||
	[EstateID] ASC
 | 
			
		||||
)WITH (PAD_INDEX  = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
 | 
			
		||||
) ON [PRIMARY];
 | 
			
		||||
 | 
			
		||||
CREATE TABLE [dbo].[estate_groups](
 | 
			
		||||
	[EstateID] [int] NOT NULL,
 | 
			
		||||
	[uuid] [varchar](36) NOT NULL,
 | 
			
		||||
 CONSTRAINT [PK_estate_groups] PRIMARY KEY CLUSTERED 
 | 
			
		||||
(
 | 
			
		||||
	[EstateID] ASC
 | 
			
		||||
)WITH (PAD_INDEX  = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
 | 
			
		||||
) ON [PRIMARY];
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
CREATE TABLE [dbo].[estate_users](
 | 
			
		||||
	[EstateID] [int] NOT NULL,
 | 
			
		||||
	[uuid] [varchar](36) NOT NULL,
 | 
			
		||||
 CONSTRAINT [PK_estate_users] PRIMARY KEY CLUSTERED 
 | 
			
		||||
(
 | 
			
		||||
	[EstateID] ASC
 | 
			
		||||
)WITH (PAD_INDEX  = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
 | 
			
		||||
) ON [PRIMARY];
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
CREATE TABLE [dbo].[estateban](
 | 
			
		||||
	[EstateID] [int] NOT NULL,
 | 
			
		||||
	[bannedUUID] [varchar](36) NOT NULL,
 | 
			
		||||
	[bannedIp] [varchar](16) NOT NULL,
 | 
			
		||||
	[bannedIpHostMask] [varchar](16) NOT NULL,
 | 
			
		||||
	[bannedNameMask] [varchar](64) NULL DEFAULT (NULL),
 | 
			
		||||
 CONSTRAINT [PK_estateban] PRIMARY KEY CLUSTERED 
 | 
			
		||||
(
 | 
			
		||||
	[EstateID] ASC
 | 
			
		||||
)WITH (PAD_INDEX  = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
 | 
			
		||||
) ON [PRIMARY];
 | 
			
		||||
 | 
			
		||||
CREATE TABLE [dbo].[estate_settings](
 | 
			
		||||
	[EstateID] [int] IDENTITY(1,100) NOT NULL,
 | 
			
		||||
	[EstateName] [varchar](64) NULL DEFAULT (NULL),
 | 
			
		||||
	[AbuseEmailToEstateOwner] [bit] NOT NULL,
 | 
			
		||||
	[DenyAnonymous] [bit] NOT NULL,
 | 
			
		||||
	[ResetHomeOnTeleport] [bit] NOT NULL,
 | 
			
		||||
	[FixedSun] [bit] NOT NULL,
 | 
			
		||||
	[DenyTransacted] [bit] NOT NULL,
 | 
			
		||||
	[BlockDwell] [bit] NOT NULL,
 | 
			
		||||
	[DenyIdentified] [bit] NOT NULL,
 | 
			
		||||
	[AllowVoice] [bit] NOT NULL,
 | 
			
		||||
	[UseGlobalTime] [bit] NOT NULL,
 | 
			
		||||
	[PricePerMeter] [int] NOT NULL,
 | 
			
		||||
	[TaxFree] [bit] NOT NULL,
 | 
			
		||||
	[AllowDirectTeleport] [bit] NOT NULL,
 | 
			
		||||
	[RedirectGridX] [int] NOT NULL,
 | 
			
		||||
	[RedirectGridY] [int] NOT NULL,
 | 
			
		||||
	[ParentEstateID] [int] NOT NULL,
 | 
			
		||||
	[SunPosition] [float] NOT NULL,
 | 
			
		||||
	[EstateSkipScripts] [bit] NOT NULL,
 | 
			
		||||
	[BillableFactor] [float] NOT NULL,
 | 
			
		||||
	[PublicAccess] [bit] NOT NULL,
 | 
			
		||||
	[AbuseEmail] [varchar](255) NOT NULL,
 | 
			
		||||
	[EstateOwner] [varchar](36) NOT NULL,
 | 
			
		||||
	[DenyMinors] [bit] NOT NULL,
 | 
			
		||||
 CONSTRAINT [PK_estate_settings] PRIMARY KEY CLUSTERED 
 | 
			
		||||
(
 | 
			
		||||
	[EstateID] ASC
 | 
			
		||||
)WITH (PAD_INDEX  = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
 | 
			
		||||
) ON [PRIMARY];
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
CREATE TABLE [dbo].[estate_map](
 | 
			
		||||
	[RegionID] [varchar](36) NOT NULL DEFAULT ('00000000-0000-0000-0000-000000000000'),
 | 
			
		||||
	[EstateID] [int] NOT NULL,
 | 
			
		||||
 CONSTRAINT [PK_estate_map] PRIMARY KEY CLUSTERED 
 | 
			
		||||
(
 | 
			
		||||
	[RegionID] ASC
 | 
			
		||||
)WITH (PAD_INDEX  = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
 | 
			
		||||
) ON [PRIMARY];
 | 
			
		||||
 | 
			
		||||
COMMIT
 | 
			
		||||
 | 
			
		||||
:VERSION 2
 | 
			
		||||
 | 
			
		||||
BEGIN TRANSACTION
 | 
			
		||||
 | 
			
		||||
ALTER TABLE dbo.estate_managers DROP CONSTRAINT PK_estate_managers
 | 
			
		||||
 | 
			
		||||
CREATE NONCLUSTERED INDEX IX_estate_managers ON dbo.estate_managers
 | 
			
		||||
	(
 | 
			
		||||
	EstateID
 | 
			
		||||
	) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
 | 
			
		||||
 | 
			
		||||
ALTER TABLE dbo.estate_groups DROP CONSTRAINT PK_estate_groups
 | 
			
		||||
 | 
			
		||||
CREATE NONCLUSTERED INDEX IX_estate_groups ON dbo.estate_groups
 | 
			
		||||
	(
 | 
			
		||||
	EstateID
 | 
			
		||||
	) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
ALTER TABLE dbo.estate_users DROP CONSTRAINT PK_estate_users
 | 
			
		||||
 | 
			
		||||
CREATE NONCLUSTERED INDEX IX_estate_users ON dbo.estate_users
 | 
			
		||||
	(
 | 
			
		||||
	EstateID
 | 
			
		||||
	) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
 | 
			
		||||
 | 
			
		||||
COMMIT
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
:VERSION 3
 | 
			
		||||
 | 
			
		||||
BEGIN TRANSACTION
 | 
			
		||||
 | 
			
		||||
CREATE TABLE dbo.Tmp_estateban
 | 
			
		||||
	(
 | 
			
		||||
	EstateID int NOT NULL,
 | 
			
		||||
	bannedUUID varchar(36) NOT NULL,
 | 
			
		||||
	bannedIp varchar(16) NULL,
 | 
			
		||||
	bannedIpHostMask varchar(16) NULL,
 | 
			
		||||
	bannedNameMask varchar(64) NULL
 | 
			
		||||
	)  ON [PRIMARY]
 | 
			
		||||
 | 
			
		||||
IF EXISTS(SELECT * FROM dbo.estateban)
 | 
			
		||||
	 EXEC('INSERT INTO dbo.Tmp_estateban (EstateID, bannedUUID, bannedIp, bannedIpHostMask, bannedNameMask)
 | 
			
		||||
		SELECT EstateID, bannedUUID, bannedIp, bannedIpHostMask, bannedNameMask FROM dbo.estateban')
 | 
			
		||||
 | 
			
		||||
DROP TABLE dbo.estateban
 | 
			
		||||
 | 
			
		||||
EXECUTE sp_rename N'dbo.Tmp_estateban', N'estateban', 'OBJECT' 
 | 
			
		||||
 | 
			
		||||
CREATE NONCLUSTERED INDEX IX_estateban ON dbo.estateban
 | 
			
		||||
	(
 | 
			
		||||
	EstateID
 | 
			
		||||
	) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
 | 
			
		||||
 | 
			
		||||
COMMIT
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
:VERSION 4
 | 
			
		||||
 | 
			
		||||
BEGIN TRANSACTION
 | 
			
		||||
 | 
			
		||||
CREATE TABLE dbo.Tmp_estate_managers
 | 
			
		||||
	(
 | 
			
		||||
	EstateID int NOT NULL,
 | 
			
		||||
	uuid uniqueidentifier NOT NULL
 | 
			
		||||
	)  ON [PRIMARY]
 | 
			
		||||
 | 
			
		||||
IF EXISTS(SELECT * FROM dbo.estate_managers)
 | 
			
		||||
	 EXEC('INSERT INTO dbo.Tmp_estate_managers (EstateID, uuid)
 | 
			
		||||
		SELECT EstateID, CONVERT(uniqueidentifier, uuid) FROM dbo.estate_managers WITH (HOLDLOCK TABLOCKX)')
 | 
			
		||||
 | 
			
		||||
DROP TABLE dbo.estate_managers
 | 
			
		||||
 | 
			
		||||
EXECUTE sp_rename N'dbo.Tmp_estate_managers', N'estate_managers', 'OBJECT' 
 | 
			
		||||
 | 
			
		||||
CREATE NONCLUSTERED INDEX IX_estate_managers ON dbo.estate_managers
 | 
			
		||||
	(
 | 
			
		||||
	EstateID
 | 
			
		||||
	) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
 | 
			
		||||
 | 
			
		||||
COMMIT
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
:VERSION 5
 | 
			
		||||
 | 
			
		||||
BEGIN TRANSACTION
 | 
			
		||||
 | 
			
		||||
CREATE TABLE dbo.Tmp_estate_groups
 | 
			
		||||
	(
 | 
			
		||||
	EstateID int NOT NULL,
 | 
			
		||||
	uuid uniqueidentifier NOT NULL
 | 
			
		||||
	)  ON [PRIMARY]
 | 
			
		||||
 | 
			
		||||
IF EXISTS(SELECT * FROM dbo.estate_groups)
 | 
			
		||||
	 EXEC('INSERT INTO dbo.Tmp_estate_groups (EstateID, uuid)
 | 
			
		||||
		SELECT EstateID, CONVERT(uniqueidentifier, uuid) FROM dbo.estate_groups WITH (HOLDLOCK TABLOCKX)')
 | 
			
		||||
 | 
			
		||||
DROP TABLE dbo.estate_groups
 | 
			
		||||
 | 
			
		||||
EXECUTE sp_rename N'dbo.Tmp_estate_groups', N'estate_groups', 'OBJECT' 
 | 
			
		||||
 | 
			
		||||
CREATE NONCLUSTERED INDEX IX_estate_groups ON dbo.estate_groups
 | 
			
		||||
	(
 | 
			
		||||
	EstateID
 | 
			
		||||
	) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
 | 
			
		||||
 | 
			
		||||
COMMIT
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
:VERSION 6
 | 
			
		||||
 | 
			
		||||
BEGIN TRANSACTION
 | 
			
		||||
 | 
			
		||||
CREATE TABLE dbo.Tmp_estate_users
 | 
			
		||||
	(
 | 
			
		||||
	EstateID int NOT NULL,
 | 
			
		||||
	uuid uniqueidentifier NOT NULL
 | 
			
		||||
	)  ON [PRIMARY]
 | 
			
		||||
 | 
			
		||||
IF EXISTS(SELECT * FROM dbo.estate_users)
 | 
			
		||||
	 EXEC('INSERT INTO dbo.Tmp_estate_users (EstateID, uuid)
 | 
			
		||||
		SELECT EstateID, CONVERT(uniqueidentifier, uuid) FROM dbo.estate_users WITH (HOLDLOCK TABLOCKX)')
 | 
			
		||||
 | 
			
		||||
DROP TABLE dbo.estate_users
 | 
			
		||||
 | 
			
		||||
EXECUTE sp_rename N'dbo.Tmp_estate_users', N'estate_users', 'OBJECT' 
 | 
			
		||||
 | 
			
		||||
CREATE NONCLUSTERED INDEX IX_estate_users ON dbo.estate_users
 | 
			
		||||
	(
 | 
			
		||||
	EstateID
 | 
			
		||||
	) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
 | 
			
		||||
 | 
			
		||||
COMMIT
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
:VERSION 7
 | 
			
		||||
 | 
			
		||||
BEGIN TRANSACTION
 | 
			
		||||
 | 
			
		||||
CREATE TABLE dbo.Tmp_estateban
 | 
			
		||||
	(
 | 
			
		||||
	EstateID int NOT NULL,
 | 
			
		||||
	bannedUUID uniqueidentifier NOT NULL,
 | 
			
		||||
	bannedIp varchar(16) NULL,
 | 
			
		||||
	bannedIpHostMask varchar(16) NULL,
 | 
			
		||||
	bannedNameMask varchar(64) NULL
 | 
			
		||||
	)  ON [PRIMARY]
 | 
			
		||||
 | 
			
		||||
IF EXISTS(SELECT * FROM dbo.estateban)
 | 
			
		||||
	 EXEC('INSERT INTO dbo.Tmp_estateban (EstateID, bannedUUID, bannedIp, bannedIpHostMask, bannedNameMask)
 | 
			
		||||
		SELECT EstateID, CONVERT(uniqueidentifier, bannedUUID), bannedIp, bannedIpHostMask, bannedNameMask FROM dbo.estateban WITH (HOLDLOCK TABLOCKX)')
 | 
			
		||||
 | 
			
		||||
DROP TABLE dbo.estateban
 | 
			
		||||
 | 
			
		||||
EXECUTE sp_rename N'dbo.Tmp_estateban', N'estateban', 'OBJECT' 
 | 
			
		||||
 | 
			
		||||
CREATE NONCLUSTERED INDEX IX_estateban ON dbo.estateban
 | 
			
		||||
	(
 | 
			
		||||
	EstateID
 | 
			
		||||
	) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
 | 
			
		||||
 | 
			
		||||
COMMIT
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
:VERSION 8
 | 
			
		||||
 | 
			
		||||
BEGIN TRANSACTION
 | 
			
		||||
 | 
			
		||||
CREATE TABLE dbo.Tmp_estate_settings
 | 
			
		||||
	(
 | 
			
		||||
	EstateID int NOT NULL IDENTITY (1, 100),
 | 
			
		||||
	EstateName varchar(64) NULL DEFAULT (NULL),
 | 
			
		||||
	AbuseEmailToEstateOwner bit NOT NULL,
 | 
			
		||||
	DenyAnonymous bit NOT NULL,
 | 
			
		||||
	ResetHomeOnTeleport bit NOT NULL,
 | 
			
		||||
	FixedSun bit NOT NULL,
 | 
			
		||||
	DenyTransacted bit NOT NULL,
 | 
			
		||||
	BlockDwell bit NOT NULL,
 | 
			
		||||
	DenyIdentified bit NOT NULL,
 | 
			
		||||
	AllowVoice bit NOT NULL,
 | 
			
		||||
	UseGlobalTime bit NOT NULL,
 | 
			
		||||
	PricePerMeter int NOT NULL,
 | 
			
		||||
	TaxFree bit NOT NULL,
 | 
			
		||||
	AllowDirectTeleport bit NOT NULL,
 | 
			
		||||
	RedirectGridX int NOT NULL,
 | 
			
		||||
	RedirectGridY int NOT NULL,
 | 
			
		||||
	ParentEstateID int NOT NULL,
 | 
			
		||||
	SunPosition float(53) NOT NULL,
 | 
			
		||||
	EstateSkipScripts bit NOT NULL,
 | 
			
		||||
	BillableFactor float(53) NOT NULL,
 | 
			
		||||
	PublicAccess bit NOT NULL,
 | 
			
		||||
	AbuseEmail varchar(255) NOT NULL,
 | 
			
		||||
	EstateOwner uniqueidentifier NOT NULL,
 | 
			
		||||
	DenyMinors bit NOT NULL
 | 
			
		||||
	)  ON [PRIMARY]
 | 
			
		||||
 | 
			
		||||
SET IDENTITY_INSERT dbo.Tmp_estate_settings ON
 | 
			
		||||
 | 
			
		||||
IF EXISTS(SELECT * FROM dbo.estate_settings)
 | 
			
		||||
	 EXEC('INSERT INTO dbo.Tmp_estate_settings (EstateID, EstateName, AbuseEmailToEstateOwner, DenyAnonymous, ResetHomeOnTeleport, FixedSun, DenyTransacted, BlockDwell, DenyIdentified, AllowVoice, UseGlobalTime, PricePerMeter, TaxFree, AllowDirectTeleport, RedirectGridX, RedirectGridY, ParentEstateID, SunPosition, EstateSkipScripts, BillableFactor, PublicAccess, AbuseEmail, EstateOwner, DenyMinors)
 | 
			
		||||
		SELECT EstateID, EstateName, AbuseEmailToEstateOwner, DenyAnonymous, ResetHomeOnTeleport, FixedSun, DenyTransacted, BlockDwell, DenyIdentified, AllowVoice, UseGlobalTime, PricePerMeter, TaxFree, AllowDirectTeleport, RedirectGridX, RedirectGridY, ParentEstateID, SunPosition, EstateSkipScripts, BillableFactor, PublicAccess, AbuseEmail, CONVERT(uniqueidentifier, EstateOwner), DenyMinors FROM dbo.estate_settings WITH (HOLDLOCK TABLOCKX)')
 | 
			
		||||
 | 
			
		||||
SET IDENTITY_INSERT dbo.Tmp_estate_settings OFF
 | 
			
		||||
 | 
			
		||||
DROP TABLE dbo.estate_settings
 | 
			
		||||
 | 
			
		||||
EXECUTE sp_rename N'dbo.Tmp_estate_settings', N'estate_settings', 'OBJECT' 
 | 
			
		||||
 | 
			
		||||
ALTER TABLE dbo.estate_settings ADD CONSTRAINT
 | 
			
		||||
	PK_estate_settings PRIMARY KEY CLUSTERED 
 | 
			
		||||
	(
 | 
			
		||||
	EstateID
 | 
			
		||||
	) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
 | 
			
		||||
 | 
			
		||||
COMMIT
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
:VERSION 9
 | 
			
		||||
 | 
			
		||||
BEGIN TRANSACTION
 | 
			
		||||
 | 
			
		||||
CREATE TABLE dbo.Tmp_estate_map
 | 
			
		||||
	(
 | 
			
		||||
	RegionID uniqueidentifier NOT NULL DEFAULT ('00000000-0000-0000-0000-000000000000'),
 | 
			
		||||
	EstateID int NOT NULL
 | 
			
		||||
	)  ON [PRIMARY]
 | 
			
		||||
 | 
			
		||||
IF EXISTS(SELECT * FROM dbo.estate_map)
 | 
			
		||||
	 EXEC('INSERT INTO dbo.Tmp_estate_map (RegionID, EstateID)
 | 
			
		||||
		SELECT CONVERT(uniqueidentifier, RegionID), EstateID FROM dbo.estate_map WITH (HOLDLOCK TABLOCKX)')
 | 
			
		||||
 | 
			
		||||
DROP TABLE dbo.estate_map
 | 
			
		||||
 | 
			
		||||
EXECUTE sp_rename N'dbo.Tmp_estate_map', N'estate_map', 'OBJECT' 
 | 
			
		||||
 | 
			
		||||
ALTER TABLE dbo.estate_map ADD CONSTRAINT
 | 
			
		||||
	PK_estate_map PRIMARY KEY CLUSTERED 
 | 
			
		||||
	(
 | 
			
		||||
	RegionID
 | 
			
		||||
	) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
COMMIT
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
		Reference in New Issue