diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000..94f896dbe4
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,113 @@
+.project
+.settings
+*.csproj
+*.csproj.user
+*.build
+*.mdb
+*.mdp
+*.mds
+*.pdb
+*.pidb
+*.dll.build
+*.dll
+
+# Ignore .user and .suo files as these are user preference specific
+# http://stackoverflow.com/questions/72298/should-i-add-the-visual-studio-suo-and-user-files-to-source-control
+*.suo
+*.user
+
+*.VisualState.xml
+*/*/obj
+*/*/*/obj
+*/*/*/*/obj
+*/*/*/*/*/obj
+*/*/*/*/*/*/obj
+*/*/*/*/*/*/*/obj
+*/*/bin
+*/*/*/bin
+*/*/*/*/bin
+*/*/*/*/*/bin
+*/*/*/*/*/*/bin
+*/*/*/*/*/*/*/bin
+bin/Debug/*.dll
+bin/*.dll.mdb
+bin/*.db
+bin/*.db-journal
+bin/addin-db-*
+bin/*.dll
+bin/OpenSim.vshost.exe.config
+bin/OpenSim.32BitLaunch.vshost.exe.config
+bin/OpenSim.32BitLaunch.log
+UpgradeLog.XML
+_UpgradeReport_Files/
+bin/ScriptEngines/*-*-*-*-*
+bin/ScriptEngines/*.dll
+bin/ScriptEngines/*/*.dll
+bin/ScriptEngines/*/*.state
+bin/*.maddin
+bin/*.exe
+bin/*.ini
+bin/j2kDecodeCache
+bin/Physics*
+bin/Terrain*
+bin/Regions/*
+bin/UserAssets
+bin/assetcache
+bin/maptiles
+bin/bakes
+bin/estate_settings.xml
+bin/config-include/CenomeCache.ini
+bin/config-include/FlotsamCache.ini
+bin/config-include/GridCommon.ini
+bin/config-include/StandaloneCommon.ini
+bin/OpenSim.Grid.AssetInventoryServer.log
+bin/OpenSim.Grid.AssetServer.log
+bin/OpenSim.Grid.GridServer.log
+bin/OpenSim.Grid.InventoryServer.log
+bin/OpenSim.Grid.MessagingServer.log
+bin/OpenSim.Grid.UserServer.log
+bin/OpenSim.log
+bin/OpenSimStats.log
+bin/Robust.log
+bin/RobustStats.log
+bin/OpenSimConsoleHistory.txt
+bin/RobustConsoleHistory.txt
+bin/*.Tests.log
+bin/*.manifest
+bin/crashes/
+Examples/*.dll
+OpenSim.build
+OpenSim.sln
+OpenSim.userprefs
+Prebuild/Prebuild.build
+Prebuild/Prebuild.sln
+TestResult.xml
+cov/*
+OpenSim/OpenSim.userprefs
+OpenSim/OpenSim.usertasks
+TAGS
+*~
+Makefile.local
+bin/.version
+compile.bat
+addon-modules
+OpenSim/Data/Tests/test-results/
+OpenSim/Framework/Serialization/Tests/test-results/
+OpenSim/Framework/Servers/Tests/test-results/
+OpenSim/Framework/Tests/test-results/
+OpenSim/Region/ClientStack/Linden/Caps/test-results/
+OpenSim/Region/ClientStack/Linden/UDP/Tests/test-results/
+OpenSim/Region/CoreModules/test-results/
+OpenSim/Region/Framework/test-results/
+OpenSim/Region/OptionalModules/test-results/
+OpenSim/Region/Physics/BulletDotNETPlugin/
+OpenSim/Region/Physics/Manager/test-results/
+OpenSim/Region/Physics/OdePlugin/Tests/test-results/
+OpenSim/Region/ScriptEngine/test-results/
+OpenSim/Tests/Common/test-results/
+OpenSim/Tests/test-results/
+test-results/
+doc/html
+doc/doxygen.error.log
+
+*.patch
diff --git a/.hgignore b/.hgignore
new file mode 100644
index 0000000000..29bba21730
--- /dev/null
+++ b/.hgignore
@@ -0,0 +1,23 @@
+^tailor.state.old$
+^tailor.state.journal$
+\.csproj$
+\.csproj\.user$
+\.mdp$
+\.mds$
+\.dll\.build$
+^bin/Debug/.+\.dll$
+^bin/.+\.db$
+^bin/OpenSim\.ini$
+^bin/OpenSim\.log$
+^bin/estate_settings\.xml$
+^bin/Regions
+bin/.+\.dll.mdb$
+bin/addin-db-
+bin/.+\.dll$
+bin/.+\.maddin$
+Examples/.+\.dll$
+^bin/.+\.exe
+^(OpenSim|Prebuild)/.+\.(exe|exe\.build|exe\.mdb)$
+^OpenSim\.(build|sln)$
+^Prebuild/Prebuild\.(build|sln)$
+.+~$
diff --git a/.nant/local.include b/.nant/local.include
new file mode 100644
index 0000000000..c20794499f
--- /dev/null
+++ b/.nant/local.include
@@ -0,0 +1,274 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/BUILDING.md b/BUILDING.md
new file mode 100644
index 0000000000..d8deeeb237
--- /dev/null
+++ b/BUILDING.md
@@ -0,0 +1,40 @@
+# 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
+
+Prereqs:
+* 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
+ * nant (or !* xbuild)
+ * cd bin
+ * copy OpenSim.ini.example to OpenSim.ini and other appropriate files in bin/config-include
+ * run mono OpenSim.exe
+ !* xbuild option switches
+ !* clean: xbuild /target:clean
+ !* debug: (default) xbuild /property:Configuration=Debug
+ !* release: xbuild /property:Configuration=Release
+
+# Using Monodevelop
+
+From the distribution type:
+ * ./runprebuild.sh
+ * type monodevelop OpenSim.sln
+
+# References
+
+Helpful resources:
+* http://opensimulator.org/wiki/Build_Instructions
diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt
new file mode 100644
index 0000000000..e14e5efcc1
--- /dev/null
+++ b/CONTRIBUTORS.txt
@@ -0,0 +1,239 @@
+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)
+* dahlia
+* Melanie Thielker
+* Diva (Crista Lopes, University of California, Irvine)
+* BlueWall (James Hughes)
+* Nebadon Izumi (Michael Cerquoni, OSgrid)
+* Snoopy Pfeffer
+* Robert Adams (MisterBlue)
+* Oren Hurvitz (Kitely)
+* Kevin Cozens
+
+= 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.
+
+* Teravus (w3z)
+* Arthur Rodrigo S Valadares (IBM)
+* Dan Lake
+* Marck
+* Mic Bowman
+
+= Past Open Sim Developers =
+These folks are alumns of the OpenSim core group, but are now
+currently not active. Their great contributions helped get us to
+where we are today.
+
+* Gareth
+* Andy-
+* MorphW
+* CW
+* Babblefrog
+* Danx0r
+* Dalien
+* Darok
+* Alondria
+* Sean Dague / sdague (IBM)
+* Tedd
+* MingChen (DeepThink Pty Ltd)
+* adjohn (Genkii)
+* idb (Ian Brown)
+* Johan Berntsson (3Di)
+* MW (Tribal Media AB)
+* Adam Frisby (DeepThink Pty Ltd)
+* lbsa71 (Tribal Media AB)
+* Ckrinke (Charles Krinke)
+* Dr Scofield aka Dirk Husemann (IBM Research - Zurich)
+* mikem (3Di)
+* Homer_Horwitz
+* nlin (3Di)
+* John Hurliman
+* chi11ken (Genkii)
+
+
+= 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
+* alex_carnell
+* Alan Webb (IBM)
+* Aleric
+* Alicia Raven
+* Allen Kerensky
+* BigFootAg
+* 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
+* dr0b3rts
+* dslake
+* eeyore
+* FredoChaplin
+* FreakyTech
+* Garmin Kawaguichi
+* Gavin Hird
+* Gerhard
+* Godfrey
+* Greg C.
+* Grumly57
+* GuduleLapointe
+* Ewe Loon
+* Fernando Oliveira
+* Fly-Man
+* Flyte Xevious
+* Freaky Tech
+* Garmin Kawaguichi
+* Glenn Martin (MOSES)
+* Gryc Ueusp
+* H-H-H (ginge264)
+* Hiro Lecker
+* Iain Oliver
+* Imaze Rhiano
+* Intimidated
+* Jak Daniels
+* Jeremy Bongio (IBM)
+* jhurliman
+* John R Sohn (XenReborn)
+* jonc
+* Jon Cundill
+* Junta Kohime
+* Kayne
+* kinoc (Daxtron Labs)
+* Kira
+* Kitto Flora
+* KittyLiu
+* Kurt Taylor (IBM)
+* Lani Global
+* lillith_xue
+* lkalif
+* LuciusSirnah
+* lulurun
+* M.Igarashi
+* Magnuz Binder
+* maimedleech
+* Mana Janus
+* MarcelEdward
+* Matt Lehmann
+* Mic Bowman
+* Michelle Argus
+* Michael Cortez (The Flotsam Project, http://osflotsam.org/)
+* Michael Heilmann (MOSES)
+* Micheil Merlin
+* Mike Osias (IBM)
+* Mike Pitman (IBM)
+* mikemig
+* mikkopa/_someone - RealXtend
+* Misterblue
+* Mircea Kitsune
+* mpallari
+* MrMonkE
+* Nebadon Izumi (Michael Cerquoni - http://OSgrid.org)
+* Neil Canham
+* nornalbion
+* Omar Vera Ustariz (IBM)
+* openlifegrid.com
+* otakup0pe
+* Pixel Tomsen
+* 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)
+* Strawberry Fride
+* Talun
+* TechplexEngineer (Blake Bourque)
+* TBG Renfold
+* tglion
+* tlaukkan/Tommil (Tommi S. E. Laukkanen, Bubble Cloud)
+* tyre
+* Vegaslon
+* VikingErik
+* Vytek
+* webmage (IBM)
+* Xantor
+* Y. Nitta
+* YoshikoFazuku
+* YZh
+* Zackary Geers aka Kunnis Basiat
+* 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)
+* SQLite (Public Domain)
+* XmlRpcCS (http://xmlrpccs.sf.net/)
+* MySQL, Inc. (MySQL Connector/NET)
+* NUnit (http://www.nunit.org)
+* AGEIA Inc. (PhysX)
+* Russel L. Smith (ODE)
+* Erwin Coumans (Bullet)
+* Prebuild (http://sourceforge.net/projects/dnpb/)
+* LibOpenMetaverse (http://lib.openmetaverse.org/)
+* DotNetOpenMail v0.5.8b (http://dotnetopenmail.sourceforge.net)
+* Prototype JavaScript Framework ajax (http://www.prototypejs.org/)
+* C5 GENERIC COLLECTION LIBRARY FOR C#/CLI
+* Nini (http://nini.sourceforge.net/)
+* log4net (http://logging.apache.org/log4net/)
+* GlynnTucker.Cache (http://gtcache.sourceforge.net/)
+* NDesk.Options 0.2.1 (http://www.ndesk.org/Options)
+* Json.NET 3.5 Release 6. The binary used is actually Newtonsoft.Json.Net20.dll for Mono 2.4 compatability (http://james.newtonking.com/projects/json-net.aspx)
+* zlib.net for C# 1.0.4 (http://www.componentace.com/zlib_.NET.htm)
+
+Some plugins are based on Cable Beach
+Cable Beach is Copyright (c) 2008 Intel Corporation
+see http://forge.opensimulator.org/gf/project/assetserver/
+
+In addition, we would like to thank:
+* The Mono Project
+* The NANT Developers
+* Microsoft (.NET, MSSQL-Adapters)
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 0000000000..570f7328af
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,25 @@
+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.
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000000..493cdca619
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,43 @@
+# hey, emacs! this is a -*- makefile -*-
+#
+# OpenSim makefile
+#
+
+RUBY = $(strip $(shell which ruby 2>/dev/null))
+ifeq ($(RUBY),)
+NANT = nant
+else
+NANT = $(shell if test "$$EMACS" = "t" ; then echo "nant"; else echo "./nant-color"; fi)
+endif
+
+all: prebuild
+ # @export PATH=/usr/local/bin:$(PATH)
+ ${NANT}
+ find OpenSim -name \*.mdb -exec cp {} bin \;
+
+release: prebuild
+ ${NANT} -D:project.config=Release
+ find OpenSim -name \*.mdb -exec cp {} bin \;
+
+prebuild:
+ ./runprebuild.sh
+
+clean:
+ # @export PATH=/usr/local/bin:$(PATH)
+ -${NANT} clean
+
+test: prebuild
+ ${NANT} test
+
+test-xml: prebuild
+ ${NANT} test-xml
+
+tags:
+ find OpenSim -name \*\.cs | xargs etags
+
+cscope-tags:
+ find OpenSim -name \*\.cs -fprint cscope.files
+ cscope -b
+
+include $(wildcard Makefile.local)
+
diff --git a/OpenSim.FxCop b/OpenSim.FxCop
new file mode 100644
index 0000000000..d07c26efbf
--- /dev/null
+++ b/OpenSim.FxCop
@@ -0,0 +1,7241 @@
+
+
+
+ True
+ http://www.gotdotnet.com/team/fxcop//xsl/1.35/FxCopReport.xsl
+
+
+
+
+
+ True
+ True
+ True
+ 10
+ 1
+
+ False
+ False
+
+ False
+ 120
+
+
+
+ $(ProjectDir)/lib/
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ - Sim
+ - OpenSim
+
+
+
+
+
+
+
+
+ - Sim
+ - OpenSim.Assets
+
+
+
+
+
+
+
+
+ - OpenSim.CAPS
+
+
+
+
+ - Sim
+ - OpenSim.CAPS
+
+
+
+
+ - OpenSim.CAPS
+
+
+
+
+
+
+
+
+ - Sim
+ - OpenSim.Config.SimConfigDb4o
+
+
+ - Sim
+ - OpenSim.Config.SimConfigDb4o
+
+
+
+
+
+
+
+
+ - OpenSim.Framework.Assets
+
+
+
+
+ - Sim
+ - OpenSim.Framework.Assets
+
+
+
+
+
+
+
+
+ - Sim
+ - OpenSim.Framework.Console
+
+
+
+
+
+
+
+
+ - OpenSim.Framework.Grid
+
+
+
+
+ - Sim
+ - OpenSim.Framework.Grid
+
+
+
+
+
+
+
+
+ - Sim
+ - OpenSim.Framework.Interfaces
+
+
+
+
+
+
+
+
+ - OpenSim.Framework.Inventory
+
+
+
+
+ - Sim
+ - OpenSim.Framework.Inventory
+
+
+
+
+
+
+
+
+ - OpenSim.Framework.Sims
+
+
+
+
+ - Sim
+ - OpenSim.Framework.Sims
+
+
+
+
+
+
+
+
+ - OpenSim.Framework.Terrain
+
+
+
+
+ - Sim
+ - OpenSim.Framework.Terrain
+
+
+
+
+
+
+
+
+ - OpenSim.Framework.User
+
+
+
+
+ - Sim
+ - OpenSim.Framework.User
+
+
+
+
+
+
+
+
+ - OpenSim.Framework.Utilities
+
+
+
+
+ - Sim
+ - OpenSim.Framework.Utilities
+
+
+
+
+
+
+
+
+ - Sim
+ - OpenSim.GridInterfaces.Local
+
+
+
+
+
+
+
+
+ - OpenSim.GridInterfaces.Remote
+
+
+
+
+ - Sim
+ - OpenSim.GridInterfaces.Remote
+
+
+
+
+
+
+
+
+ - Plugin
+ - OpenSim.Physics.BasicPhysicsPlugin
+
+
+
+
+ - Sim
+ - OpenSim.Physics.BasicPhysicsPlugin
+
+
+
+
+
+
+
+
+ - Sim
+ - OpenSim.Physics.Manager
+
+
+
+
+
+
+
+
+ - OpenSim.Physics.OdePlugin
+
+
+
+
+ - Plugin
+ - OpenSim.Physics.OdePlugin
+
+
+
+
+ - Sim
+ - OpenSim.Physics.OdePlugin
+
+
+
+
+
+
+
+
+ - OpenSim.Physics.PhysXPlugin
+
+
+
+
+ - Plugin
+ - OpenSim.Physics.PhysXPlugin
+
+
+
+
+ - Sim
+ - OpenSim.Physics.PhysXPlugin
+
+
+
+
+
+
+
+
+ - Sim
+ - OpenSim.Storage.LocalStorageDb4o
+
+
+
+
+
+
+
+
+ - OpenSim.types
+
+
+
+
+ - OpenSim.types
+
+
+
+
+ - Sim
+ - OpenSim.types
+
+
+
+
+
+
+
+
+ - OpenSim.UserServer
+
+
+
+
+ - Sim
+ - OpenSim.UserServer
+
+
+
+
+
+
+
+
+ - OpenSim.world
+
+
+
+
+ - Sim
+ - OpenSim.world
+
+
+
+
+
+
+
+
+ - OpenSim.world.scripting
+
+
+
+
+ - OpenSim.world.scripting
+
+
+ - OpenSim.world.scripting
+
+
+
+
+ - Sim
+ - OpenSim.world.scripting
+
+
+
+
+
+
+
+
+
+
+
+
+ - OpenGridServices.ServerConsole
+
+
+
+
+ - OpenGridServices.ServerConsole
+
+
+
+
+ - OpenGridServices.ServerConsole
+
+
+
+
+
+
+
+
+
+
+ - conscmd_callback
+
+
+
+
+ - conscmd
+ - ServerConsole.conscmd_callback
+
+
+
+
+ - conscmd_callback
+
+
+
+
+
+
+
+
+ - conscmd_callback.RunCmd(String, String[]):Void
+ - cmdparams
+ - cmdparams
+
+
+
+
+
+
+
+
+ - ShowWhat
+
+
+
+
+
+
+
+
+
+
+
+
+ - ConsoleBase.CmdPrompt(String, String):String
+ - defaultresponse
+ - defaultresponse
+
+
+
+
+
+
+
+
+ - OptionA
+
+
+
+
+ - OptionB
+
+
+
+
+ - ConsoleBase.CmdPrompt(String, String, String, String):String
+ - defaultresponse
+ - defaultresponse
+
+
+
+
+
+
+
+
+ - Passwd
+ - ConsoleBase.PasswdPrompt(String):String
+
+
+
+
+
+
+
+
+ - Cmd
+
+
+
+
+ - ConsoleBase.RunCmd(String, String[]):Object
+ - cmdparams
+ - cmdparams
+
+
+
+
+
+
+
+
+ - ShowWhat
+
+
+
+
+
+
+
+
+ - Line
+
+
+
+
+
+
+
+
+ - Line
+
+
+
+
+
+
+
+
+
+
+
+
+ - Sim
+ - ConsoleType.SimChat
+
+
+
+
+
+
+
+
+ - ConsoleType.TCP
+
+
+
+
+
+
+
+
+
+
+ - MainConsole
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ - OpenSim.Config.SimConfigDb4o
+
+
+
+
+ - OpenSim.Config.SimConfigDb4o
+
+
+
+
+ - OpenSim.Config.SimConfigDb4o
+
+
+
+
+
+
+
+
+
+
+ - Plugin
+ - OpenSim.Config.SimConfigDb4o.Db40ConfigPlugin
+
+
+
+
+
+
+
+
+ - Sim
+ - OpenSim.Config.SimConfigDb4o.DbSimConfig
+
+
+
+
+ - Db
+ - OpenSim.Config.SimConfigDb4o.DbSimConfig
+
+
+
+
+
+
+
+
+ - DbSimConfig.InitConfig(Boolean):Void
+ - System.Exception
+
+
+
+
+ - DbSimConfig.InitConfig(Boolean):Void
+ - System.UInt32.ToString
+ - System.UInt32.ToString(System.IFormatProvider)
+
+
+
+
+ - DbSimConfig.InitConfig(Boolean):Void
+ - System.UInt64.ToString
+ - System.UInt64.ToString(System.IFormatProvider)
+
+
+
+
+
+
+
+
+ - DbSimConfig.LoadDefaults():Void
+ - System.Convert.ToInt32(System.String)
+ - System.Convert.ToInt32(System.String,System.IFormatProvider)
+
+
+ - DbSimConfig.LoadDefaults():Void
+ - System.Convert.ToInt32(System.String)
+ - System.Convert.ToInt32(System.String,System.IFormatProvider)
+
+
+ - DbSimConfig.LoadDefaults():Void
+ - System.Convert.ToInt32(System.String)
+ - System.Convert.ToInt32(System.String,System.IFormatProvider)
+
+
+
+
+
+
+
+
+
+
+
+
+ - Map
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ - OpenSim
+
+
+
+
+ - OpenSim
+
+
+
+
+ - OpenSim
+
+
+
+
+ - OpenSim
+
+
+
+
+ - OpenSim
+
+
+
+
+
+
+
+
+
+
+
+
+ - 'args'
+ - RegionServer.Main(String[]):Void
+
+
+ - 'args'
+ - RegionServer.Main(String[]):Void
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ - OpenSim.Framework.Console
+
+
+
+
+ - OpenSim.Framework.Console
+
+
+
+
+ - OpenSim.Framework.Console
+
+
+
+
+
+
+
+
+
+
+
+
+ - ConsoleBase.CmdPrompt(String, String):String
+ - defaultresponse
+ - defaultresponse
+
+
+
+
+
+
+
+
+ - OptionA
+
+
+
+
+ - OptionB
+
+
+
+
+ - ConsoleBase.CmdPrompt(String, String, String, String):String
+ - defaultresponse
+ - defaultresponse
+
+
+
+
+
+
+
+
+ - Cmd
+
+
+
+
+ - ConsoleBase.RunCmd(String, String[]):Object
+ - cmdparams
+ - cmdparams
+
+
+
+
+
+
+
+
+ - ShowWhat
+
+
+
+
+
+
+
+
+
+
+
+
+ - Sim
+ - ConsoleType.SimChat
+
+
+
+
+
+
+
+
+ - ConsoleType.TCP
+
+
+
+
+
+
+
+
+
+
+ - MainConsole
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ - OpenSim.Framework
+
+
+
+
+ - OpenSim.Framework
+
+
+
+
+ - OpenSim.Framework
+
+
+
+
+
+
+
+
+
+
+
+
+ - Data
+
+
+
+
+
+
+
+
+ - Description
+
+
+
+
+
+
+
+
+ - FullID
+
+
+
+
+
+
+
+
+ - InvType
+
+
+
+
+
+
+
+
+ - Name
+
+
+
+
+
+
+
+
+ - Type
+
+
+
+
+
+
+
+
+
+
+
+
+ - PrimData.PrimData()
+ - ParentID
+ - System.UInt32
+ - 0
+
+
+
+
+
+
+
+
+ - FullID
+
+
+
+
+
+
+
+
+ - LocalID
+
+
+
+
+
+
+
+
+ - OwnerID
+
+
+
+
+
+
+
+
+ - ParentID
+
+
+
+
+
+
+
+
+ - PathBegin
+
+
+
+
+
+
+
+
+ - PathCurve
+
+
+
+
+
+
+
+
+ - PathEnd
+
+
+
+
+
+
+
+
+ - PathRadiusOffset
+
+
+
+
+
+
+
+
+ - PathRevolutions
+
+
+
+
+
+
+
+
+ - PathScaleX
+
+
+
+
+
+
+
+
+ - PathScaleY
+
+
+
+
+
+
+
+
+ - PathShearX
+
+
+
+
+
+
+
+
+ - PathShearY
+
+
+
+
+
+
+
+
+ - PathSkew
+
+
+
+
+
+
+
+
+ - PathTaperX
+
+
+
+
+
+
+
+
+ - PathTaperY
+
+
+
+
+
+
+
+
+ - PathTwist
+
+
+
+
+
+
+
+
+ - PathTwistBegin
+
+
+
+
+
+
+
+
+ - PCode
+
+
+
+
+
+
+
+
+ - Position
+
+
+
+
+
+
+
+
+ - ProfileBegin
+
+
+
+
+
+
+
+
+ - ProfileCurve
+
+
+
+
+
+
+
+
+ - ProfileEnd
+
+
+
+
+
+
+
+
+ - ProfileHollow
+
+
+
+
+
+
+
+
+ - Rotation
+
+
+
+
+
+
+
+
+ - Scale
+
+
+
+
+
+
+
+
+ - Texture
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ - Login
+ - LoginService
+ - LogOn
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ - AgentID
+
+
+
+
+
+
+
+
+ - circuitcode
+
+
+
+
+ - circuitcode
+ - AgentCircuitData.circuitcode
+
+
+
+
+
+
+
+
+ - firstname
+
+
+
+
+ - firstname
+ - AgentCircuitData.firstname
+
+
+
+
+
+
+
+
+ - lastname
+
+
+
+
+ - lastname
+ - AgentCircuitData.lastname
+
+
+
+
+
+
+
+
+ - SecureSessionID
+
+
+
+
+
+
+
+
+ - SessionID
+
+
+
+
+
+
+
+
+
+
+ - OpenSim.Framework.Interfaces.ARequest
+
+
+ - OpenSim.Framework.Interfaces.ARequest
+
+
+
+
+
+
+
+
+ - AssetID
+
+
+
+
+
+
+
+
+ - IsTexture
+
+
+
+
+
+
+
+
+
+
+
+
+ - Authorised
+
+
+
+
+ - Authorised
+ - AuthenticateResponse.Authorised
+
+
+
+
+
+
+
+
+ - LoginInfo
+
+
+
+
+ - Login
+ - LoginInfo
+ - LogOn
+
+
+
+
+
+
+
+
+
+
+ - Plugin
+ - OpenSim.Framework.Interfaces.IAssetPlugin
+
+
+
+
+
+
+
+
+ - GetAssetServer
+
+
+
+
+
+
+
+
+
+
+
+
+ - IsTexture
+
+
+
+
+
+
+
+
+
+
+
+
+ - ID
+ - assetID
+ - Id
+
+
+
+
+
+
+
+
+ - ServerUrl
+
+
+
+
+ - ServerKey
+
+
+
+
+ - ServerUrl
+ - IAssetServer.SetServerInfo(String, String):Void
+
+
+
+
+
+
+
+
+
+
+ - Plugin
+ - OpenSim.Framework.Interfaces.IGridPlugin
+
+
+
+
+
+
+
+
+ - GetGridServer
+
+
+
+
+
+
+
+
+
+
+
+
+ - ID
+ - sessionID
+ - Id
+
+
+
+
+ - ID
+ - agentID
+ - Id
+
+
+
+
+
+
+
+
+ - GetName
+
+
+
+
+
+
+
+
+ - ID
+ - sessionID
+ - Id
+
+
+
+
+ - ID
+ - agentID
+ - Id
+
+
+
+
+ - Logout
+ - LogoutSession
+ - LogOff
+
+
+
+
+
+
+
+
+ - Neighbours
+ - IGridServer.RequestNeighbours():NeighbourInfo[]
+
+
+
+
+
+
+
+
+ - IGridServer.RequestUUIDBlock():UUIDBlock
+
+
+
+
+
+
+
+
+ - ServerUrl
+
+
+
+
+ - SendKey
+
+
+
+
+ - RecvKey
+
+
+
+
+ - IGridServer.SetServerInfo(String, String, String):Void
+ - Recv
+ - RecvKey
+
+
+
+
+ - ServerUrl
+ - IGridServer.SetServerInfo(String, String, String):Void
+
+
+
+
+
+
+
+
+
+
+
+
+ - ID
+ - primID
+ - Id
+
+
+
+
+
+
+
+
+ - ShutDown
+ - method
+ - ShutDown
+ - Shutdown
+
+
+
+
+
+
+
+
+
+
+ - Sim
+ - OpenSim.Framework.Interfaces.ISimConfig
+
+
+
+
+
+
+
+
+ - GetConfigObject
+
+
+
+
+
+
+
+
+
+
+
+
+ - ID
+ - agentID
+ - Id
+
+
+
+
+
+
+
+
+ - ServerUrl
+
+
+
+
+ - SendKey
+
+
+
+
+ - RecvKey
+
+
+
+
+ - IUserServer.SetServerInfo(String, String, String):Void
+ - Recv
+ - RecvKey
+
+
+
+
+ - ServerUrl
+ - IUserServer.SetServerInfo(String, String, String):Void
+
+
+
+
+
+
+
+
+
+
+
+
+ - Logout
+ - LogoutSession
+ - LogOff
+
+
+
+
+
+
+
+
+
+
+ - Login
+ - Login
+ - LogOn
+
+
+
+
+
+
+
+
+ - Agent
+
+
+
+
+
+
+
+
+ - BaseFolder
+
+
+
+
+
+
+
+
+ - First
+
+
+
+
+
+
+
+
+ - InventoryFolder
+
+
+
+
+
+
+
+
+ - Last
+
+
+
+
+
+
+
+
+ - SecureSession
+
+
+
+
+
+
+
+
+ - Session
+
+
+
+
+
+
+
+
+
+
+ - Neighbour
+ - OpenSim.Framework.Interfaces.NeighbourInfo
+
+
+
+
+
+
+
+
+ - regionhandle
+
+
+
+
+ - regionhandle
+ - NeighbourInfo.regionhandle
+
+
+
+
+
+
+
+
+ - RegionLocX
+
+
+
+
+
+
+
+
+ - RegionLocY
+
+
+
+
+
+
+
+
+ - sim_ip
+
+
+
+
+ - sim
+ - NeighbourInfo.sim_ip
+
+
+
+
+ - sim_ip
+
+
+
+
+
+
+
+
+ - sim_port
+
+
+
+
+ - sim
+ - NeighbourInfo.sim_port
+
+
+
+
+ - sim_port
+
+
+
+
+
+
+
+
+
+
+
+
+ - agentcircuits
+
+
+
+
+ - agentcircuits
+
+
+
+
+ - agentcircuits
+ - RemoteGridBase.agentcircuits:Dictionary`2<System.UInt32,OpenSim.Framework.Interfaces.AgentCircuitData>
+
+
+
+
+
+
+
+
+ - Logout
+ - LogoutSession
+ - LogOff
+
+
+
+
+
+
+
+
+
+
+ - Sim
+ - OpenSim.Framework.Interfaces.SimConfig
+
+
+
+
+
+
+
+
+ - AssetSendKey
+
+
+
+
+
+
+
+
+ - AssetURL
+
+
+
+
+
+
+
+
+ - GridRecvKey
+
+
+
+
+ - Recv
+ - SimConfig.GridRecvKey
+
+
+
+
+
+
+
+
+ - GridSendKey
+
+
+
+
+
+
+
+
+ - GridURL
+
+
+
+
+
+
+
+
+ - IPListenAddr
+
+
+
+
+ - Addr
+ - SimConfig.IPListenAddr
+
+
+
+
+
+
+
+
+ - IPListenPort
+
+
+
+
+
+
+
+
+ - RegionHandle
+
+
+
+
+
+
+
+
+ - RegionLocX
+
+
+
+
+
+
+
+
+ - RegionLocY
+
+
+
+
+
+
+
+
+ - RegionName
+
+
+
+
+
+
+
+
+ - SimConfig.SaveMap(Single[]):Void
+ - heightmap
+ - heightmap
+
+
+
+
+
+
+
+
+ - UserRecvKey
+
+
+
+
+ - Recv
+ - SimConfig.UserRecvKey
+
+
+
+
+
+
+
+
+ - UserSendKey
+
+
+
+
+
+
+
+
+ - UserURL
+
+
+
+
+
+
+
+
+
+
+ - UUIDBlock
+
+
+
+
+ - OpenSim.Framework.Interfaces.UUIDBlock
+
+
+ - OpenSim.Framework.Interfaces.UUIDBlock
+
+
+
+
+
+
+
+
+ - BlockEnd
+
+
+
+
+
+
+
+
+ - BlockStart
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ - AgentInventory.AgentInventory()
+ -
AgentInventory.AgentInventory()
AgentInventory.Initialise():Void
+
+
+
+
+
+
+
+
+ - ID
+ - folderID
+ - Id
+
+
+
+
+
+
+
+
+ - AgentID
+
+
+
+
+
+
+
+
+ - ID
+ - folderID
+ - Id
+
+
+
+
+
+
+
+
+ - Initialise
+ - AgentInventory.Initialise():Void
+
+
+
+
+
+
+
+
+ - InventoryFolders
+
+
+
+
+
+
+
+
+ - InventoryItems
+
+
+
+
+
+
+
+
+ - InventoryRoot
+
+
+
+
+
+
+
+
+ - LastCached
+
+
+
+
+
+
+
+
+ - ID
+ - itemID
+ - Id
+
+
+
+
+
+
+
+
+ - Wearables
+
+
+
+
+ - Wearables
+ - AgentInventory.Wearables
+
+
+
+
+
+
+
+
+
+
+
+
+ - AssetID
+
+
+
+
+
+
+
+
+ - ItemID
+
+
+
+
+
+
+
+
+
+
+
+
+ - DefaultType
+
+
+
+
+
+
+
+
+ - FolderID
+
+
+
+
+
+
+
+
+ - FolderName
+
+
+
+
+
+
+
+
+ - Items
+
+
+
+
+ - System.Collections.Generic.List`1<OpenSim.Framework.Inventory.InventoryItem>
+ - InventoryFolder.Items
+
+
+
+
+
+
+
+
+ - OwnerID
+
+
+
+
+
+
+
+
+ - ParentID
+
+
+
+
+
+
+
+
+ - Version
+
+
+
+
+
+
+
+
+
+
+
+
+ - AssetID
+
+
+
+
+
+
+
+
+ - CreatorID
+
+
+
+
+
+
+
+
+ - Description
+
+
+
+
+
+
+
+
+ - FolderID
+
+
+
+
+
+
+
+
+ - InvType
+
+
+
+
+
+
+
+
+ - ItemID
+
+
+
+
+
+
+
+
+ - Name
+
+
+
+
+
+
+
+
+ - OwnerID
+
+
+
+
+
+
+
+
+ - Type
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ - Sim
+ - OpenSim.Framework.Sims.SimProfile
+
+
+
+
+
+
+
+
+ - SimProfile.LoadFromGrid(UInt64, String, String, String):SimProfile
+ - System.Exception
+
+
+
+
+ - GridURL
+
+
+
+
+ - SendKey
+
+
+
+
+ - RecvKey
+
+
+
+
+ - SimProfile.LoadFromGrid(UInt64, String, String, String):SimProfile
+ - Recv
+ - RecvKey
+
+
+
+
+ - region_handle
+
+
+
+
+ - GridURL
+
+
+
+
+ - RecvKey
+ - SimProfile.LoadFromGrid(UInt64, String, String, String):SimProfile
+
+
+
+
+ - SimProfile.LoadFromGrid(UInt64, String, String, String):SimProfile
+ - System.Convert.ToUInt16(System.Object)
+ - System.Convert.ToUInt16(System.Object,System.IFormatProvider)
+
+
+
+
+ - SimProfile.LoadFromGrid(UInt64, String, String, String):SimProfile
+ - System.Convert.ToUInt32(System.Object)
+ - System.Convert.ToUInt32(System.Object,System.IFormatProvider)
+
+
+ - SimProfile.LoadFromGrid(UInt64, String, String, String):SimProfile
+ - System.Convert.ToUInt32(System.Object)
+ - System.Convert.ToUInt32(System.Object,System.IFormatProvider)
+
+
+
+
+ - SimProfile.LoadFromGrid(UInt64, String, String, String):SimProfile
+ - System.Convert.ToUInt64(System.Object)
+ - System.Convert.ToUInt64(System.Object,System.IFormatProvider)
+
+
+
+
+ - SimProfile.LoadFromGrid(UInt64, String, String, String):SimProfile
+ - System.UInt64.ToString
+ - System.UInt64.ToString(System.IFormatProvider)
+
+
+
+
+
+
+
+
+
+
+ - Sim
+ - OpenSim.Framework.Sims.SimProfileBase
+
+
+
+
+
+
+
+
+ - caps_url
+
+
+
+
+ - caps_url
+
+
+
+
+
+
+
+
+ - recvkey
+
+
+
+
+ - recvkey
+ - SimProfileBase.recvkey
+
+
+
+
+
+
+
+
+ - regionhandle
+
+
+
+
+ - regionhandle
+ - SimProfileBase.regionhandle
+
+
+
+
+
+
+
+
+ - RegionLocX
+
+
+
+
+
+
+
+
+ - RegionLocY
+
+
+
+
+
+
+
+
+ - regionname
+
+
+
+
+ - regionname
+ - SimProfileBase.regionname
+
+
+
+
+
+
+
+
+ - sendkey
+
+
+
+
+ - sendkey
+ - SimProfileBase.sendkey
+
+
+
+
+
+
+
+
+ - sim_ip
+
+
+
+
+ - sim
+ - SimProfileBase.sim_ip
+
+
+
+
+ - sim_ip
+
+
+
+
+
+
+
+
+ - sim_port
+
+
+
+
+ - sim
+ - SimProfileBase.sim_port
+
+
+
+
+ - sim_port
+
+
+
+
+
+
+
+
+ - UUID
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ - Heightmap
+ - OpenSim.Framework.Terrain.HeightmapGenHills
+
+
+
+
+
+
+
+
+ - HeightmapGenHills.GenerateHeightmap(Int32, Single, Single, Boolean):Single[]
+ - num
+ - numHills
+
+
+
+
+ - Heightmap
+ - HeightmapGenHills.GenerateHeightmap(Int32, Single, Single, Boolean):Single[]
+
+
+
+
+
+
+
+
+ - HeightmapGenHills.NumHills
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ - UserProfile.UserProfile()
+ - IsGridGod
+ - System.Boolean
+ - false
+
+
+
+
+
+
+
+
+ - Sim
+ - UserProfile.AddSimCircuit(UInt32, LLUUID):Void
+
+
+
+
+ - regionUUID
+
+
+
+
+
+
+
+
+ - AssetURL
+
+
+
+
+
+
+
+
+ - Circuits
+
+
+
+
+
+
+
+
+ - CurrentSecureSessionID
+
+
+
+
+
+
+
+
+ - CurrentSessionID
+
+
+
+
+
+
+
+
+ - firstname
+
+
+
+
+ - firstname
+ - UserProfile.firstname
+
+
+
+
+
+
+
+
+ - homelookat
+
+
+
+
+ - homelookat
+ - UserProfile.homelookat
+
+
+
+
+
+
+
+
+ - homepos
+
+
+
+
+ - homepos
+ - UserProfile.homepos
+
+
+
+
+
+
+
+
+ - homeregionhandle
+
+
+
+
+ - homeregionhandle
+ - UserProfile.homeregionhandle
+
+
+
+
+
+
+
+
+ - Inventory
+
+
+
+
+
+
+
+
+ - IsGridGod
+
+
+
+
+
+
+
+
+ - IsLocal
+
+
+
+
+
+
+
+
+ - lastname
+
+
+
+
+ - lastname
+ - UserProfile.lastname
+
+
+
+
+
+
+
+
+ - MD5passwd
+
+
+
+
+
+
+
+
+ - UUID
+
+
+
+
+
+
+
+
+
+
+
+
+ - response
+
+
+
+
+ - Customise
+ - UserProfileManager.CustomiseResponse(Hashtable&, UserProfile):Void
+
+
+
+
+ - UserProfileManager.CustomiseResponse(Hashtable&, UserProfile):Void
+ - GridResp
+ - Nwc.XmlRpc.XmlRpcResponse
+
+
+
+
+ - UserProfileManager.CustomiseResponse(Hashtable&, UserProfile):Void
+ - System.Single.ToString
+ - System.Single.ToString(System.IFormatProvider)
+
+
+ - UserProfileManager.CustomiseResponse(Hashtable&, UserProfile):Void
+ - System.Single.ToString
+ - System.Single.ToString(System.IFormatProvider)
+
+
+ - UserProfileManager.CustomiseResponse(Hashtable&, UserProfile):Void
+ - System.Single.ToString
+ - System.Single.ToString(System.IFormatProvider)
+
+
+ - UserProfileManager.CustomiseResponse(Hashtable&, UserProfile):Void
+ - System.Single.ToString
+ - System.Single.ToString(System.IFormatProvider)
+
+
+ - UserProfileManager.CustomiseResponse(Hashtable&, UserProfile):Void
+ - System.Single.ToString
+ - System.Single.ToString(System.IFormatProvider)
+
+
+ - UserProfileManager.CustomiseResponse(Hashtable&, UserProfile):Void
+ - System.Single.ToString
+ - System.Single.ToString(System.IFormatProvider)
+
+
+
+
+ - UserProfileManager.CustomiseResponse(Hashtable&, UserProfile):Void
+ - System.UInt32.ToString
+ - System.UInt32.ToString(System.IFormatProvider)
+
+
+ - UserProfileManager.CustomiseResponse(Hashtable&, UserProfile):Void
+ - System.UInt32.ToString
+ - System.UInt32.ToString(System.IFormatProvider)
+
+
+
+
+
+
+
+
+ - DefaultStartupMsg
+
+
+
+
+
+
+
+
+ - GridRecvKey
+
+
+
+
+ - Recv
+ - UserProfileManager.GridRecvKey
+
+
+
+
+
+
+
+
+ - GridSendKey
+
+
+
+
+
+
+
+
+ - GridURL
+
+
+
+
+
+
+
+
+ - UserProfileManager.ParseXMLRPC(String):String
+ - System.Exception
+
+
+
+
+ - UserProfileManager.ParseXMLRPC(String):String
+
+
+
+
+ - UserProfileManager.ParseXMLRPC(String):String
+ - System.Int32.ToString
+ - System.Int32.ToString(System.IFormatProvider)
+
+
+ - UserProfileManager.ParseXMLRPC(String):String
+ - System.Int32.ToString
+ - System.Int32.ToString(System.IFormatProvider)
+
+
+
+
+ - UserProfileManager.ParseXMLRPC(String):String
+ - System.Single.ToString
+ - System.Single.ToString(System.IFormatProvider)
+
+
+ - UserProfileManager.ParseXMLRPC(String):String
+ - System.Single.ToString
+ - System.Single.ToString(System.IFormatProvider)
+
+
+ - UserProfileManager.ParseXMLRPC(String):String
+ - System.Single.ToString
+ - System.Single.ToString(System.IFormatProvider)
+
+
+ - UserProfileManager.ParseXMLRPC(String):String
+ - System.Single.ToString
+ - System.Single.ToString(System.IFormatProvider)
+
+
+ - UserProfileManager.ParseXMLRPC(String):String
+ - System.Single.ToString
+ - System.Single.ToString(System.IFormatProvider)
+
+
+ - UserProfileManager.ParseXMLRPC(String):String
+ - System.Single.ToString
+ - System.Single.ToString(System.IFormatProvider)
+
+
+ - UserProfileManager.ParseXMLRPC(String):String
+ - System.Single.ToString
+ - System.Single.ToString(System.IFormatProvider)
+
+
+ - UserProfileManager.ParseXMLRPC(String):String
+ - System.Single.ToString
+ - System.Single.ToString(System.IFormatProvider)
+
+
+ - UserProfileManager.ParseXMLRPC(String):String
+ - System.Single.ToString
+ - System.Single.ToString(System.IFormatProvider)
+
+
+
+
+
+
+
+
+ - UserProfileManager.SetKeys(String, String, String, String):Void
+ - recv
+ - recvKey
+
+
+
+
+ - url
+ - UserProfileManager.SetKeys(String, String, String, String):Void
+
+
+
+
+
+
+
+
+
+
+
+
+ - UserProfileManagerBase.AuthenticateUser(String, String, String):Boolean
+ - firstname
+ - firstname
+
+
+
+
+ - UserProfileManagerBase.AuthenticateUser(String, String, String):Boolean
+ - lastname
+ - lastname
+
+
+
+
+ - UserProfileManagerBase.AuthenticateUser(String, String, String):Boolean
+ - passwd
+ - passwd
+
+
+
+
+
+
+
+
+ - MD5passwd
+
+
+
+
+ - UserProfileManagerBase.CreateNewProfile(String, String, String):UserProfile
+ - firstname
+ - firstname
+
+
+
+
+ - UserProfileManagerBase.CreateNewProfile(String, String, String):UserProfile
+ - lastname
+ - lastname
+
+
+
+
+ - UserProfileManagerBase.CreateNewProfile(String, String, String):UserProfile
+ - M
+ - MD5passwd
+
+
+
+
+
+
+
+
+ - ProfileLLUUID
+
+
+
+
+ - ProfileLLUUID
+
+
+
+
+ - UserProfileManagerBase.GetProfileByLLUUID(LLUUID):UserProfile
+
+
+
+
+
+
+
+
+ - UserProfileManagerBase.GetProfileByName(String, String):UserProfile
+ - firstname
+ - firstname
+
+
+
+
+ - UserProfileManagerBase.GetProfileByName(String, String):UserProfile
+ - lastname
+ - lastname
+
+
+
+
+
+
+
+
+ - ID
+ - agentID
+ - Id
+
+
+
+
+
+
+
+
+ - GodID
+
+
+
+
+ - ID
+ - GodID
+ - Id
+
+
+
+
+
+
+
+
+ - UserProfiles
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ - OpenSim.Framework.Utilities.BlockingQueue`1
+ - Queue
+
+
+
+
+
+
+
+
+ - Util
+ - OpenSim.Framework.Utilities.Util
+
+
+
+
+ - Util
+
+
+
+
+ - Util
+ - System.Web.Util
+
+
+
+
+
+
+
+
+ - Xfer
+ - Util.GetNextXferID():UInt32
+
+
+
+
+ - Util.GetNextXferID():UInt32
+
+
+
+
+ - GetNextXferID
+
+
+
+
+
+
+
+
+ - X
+
+
+
+
+ - Y
+
+
+
+
+ - Util.UIntsToLong(UInt32, UInt32):UInt64
+ - X
+
+
+
+
+ - Util.UIntsToLong(UInt32, UInt32):UInt64
+ - Y
+
+
+
+
+ - Ints
+ - Util.UIntsToLong(UInt32, UInt32):UInt64
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ - OpenSim.GridInterfaces.Local
+
+
+
+
+ - OpenSim.GridInterfaces.Local
+
+
+
+
+ - OpenSim.GridInterfaces.Local
+
+
+
+
+
+
+
+
+
+
+
+
+ - Data
+
+
+
+
+
+
+
+
+ - Name
+
+
+
+
+
+
+
+
+ - Type
+
+
+
+
+
+
+
+
+ - UUID
+
+
+
+
+
+
+
+
+
+
+ - AssetUUIDQuery
+
+
+
+
+
+
+
+
+ - 'asset'
+ - AssetUUIDQuery.Match(AssetStorage):Boolean
+
+
+
+
+
+
+
+
+
+
+ - Plugin
+ - OpenSim.GridInterfaces.Local.LocalAssetPlugin
+
+
+
+
+
+
+
+
+
+
+ - LocalAssetServer.LocalAssetServer()
+ - System.Exception
+
+
+
+
+
+
+
+
+ - LocalAssetServer.LoadAsset(AssetBase, Boolean, String):Void
+
+
+
+
+ - image
+ - LocalAssetServer.LoadAsset(AssetBase, Boolean, String):Void
+
+
+
+
+
+
+
+
+ - 'asset'
+ - LocalAssetServer.UploadNewAsset(AssetBase):Void
+
+
+
+
+
+
+
+
+
+
+ - Plugin
+ - OpenSim.GridInterfaces.Local.LocalGridPlugin
+
+
+
+
+
+
+
+
+
+
+ - Logout
+ - LogoutSession
+ - LogOff
+
+
+
+
+
+
+
+
+ - Sessions
+
+
+
+
+ - System.Collections.Generic.List`1<OpenSim.Framework.Interfaces.Login>
+ - LocalGridServer.Sessions
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ - OpenSim.GridInterfaces.Remote
+
+
+
+
+ - OpenSim.GridInterfaces.Remote
+
+
+
+
+ - OpenSim.GridInterfaces.Remote
+
+
+
+
+
+
+
+
+
+
+ - Plugin
+ - OpenSim.GridInterfaces.Remote.RemoteAssetPlugin
+
+
+
+
+
+
+
+
+ - Plugin
+ - OpenSim.GridInterfaces.Remote.RemoteGridPlugin
+
+
+
+
+
+
+
+
+
+
+ - agentcircuits
+
+
+
+
+
+
+
+
+ - circuitcode
+ - RemoteGridServer.AuthenticateSession(LLUUID, LLUUID, UInt32):AuthenticateResponse
+ - circuitCode
+ - IGridServer.AuthenticateSession(LLUUID, LLUUID, UInt32):AuthenticateResponse
+
+
+
+
+
+
+
+
+ - RemoteGridServer.GridRecvKey
+
+
+
+
+
+
+
+
+ - RemoteGridServer.GridSendKey
+
+
+
+
+
+
+
+
+ - RemoteGridServer.LogoutSession(LLUUID, LLUUID, UInt32):Boolean
+ - WebRequest.Create(Uri):WebRequest
+ - WebRequest.Create(String):WebRequest
+
+
+
+
+ - RemoteGridServer.LogoutSession(LLUUID, LLUUID, UInt32):Boolean
+ - GridResponse
+ - System.String
+
+
+
+
+ - Logout
+ - LogoutSession
+ - LogOff
+
+
+
+
+ - 'sessionID'
+ - RemoteGridServer.LogoutSession(LLUUID, LLUUID, UInt32):Boolean
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ - OpenSim.Physics.Manager
+
+
+
+
+ - OpenSim.Physics.Manager
+
+
+
+
+ - OpenSim.Physics.Manager
+
+
+
+
+
+
+
+
+
+
+ - Plugin
+ - OpenSim.Physics.Manager.IPhysicsPlugin
+
+
+
+
+
+
+
+
+ - GetName
+
+
+
+
+
+
+
+
+ - GetScene
+
+
+
+
+
+
+
+
+
+
+
+
+ - 'heightMap'
+ - NullPhysicsScene.SetTerrain(Single[]):Void
+
+
+
+
+
+
+
+
+ - NullPhysicsScene.Simulate(Single):Void
+ - System.Int32.ToString
+ - System.Int32.ToString(System.IFormatProvider)
+
+
+
+
+
+
+
+
+
+
+
+
+ - Kinematic
+ - PhysicsActor.Kinematic:Boolean
+
+
+
+
+
+
+
+
+
+
+
+
+ - PhysicsManager.GetPhysicsScene(String):PhysicsScene
+ - System.String.Format(System.String,System.Object)
+ - System.String.Format(System.IFormatProvider,System.String,System.Object[])
+
+
+
+
+
+
+
+
+ - Plugins
+ - PhysicsManager.LoadPlugins():Void
+
+
+
+
+
+
+
+
+
+
+
+
+ - PhysicsVector.PhysicsVector(Single, Single, Single)
+ - x
+
+
+
+
+ - PhysicsVector.PhysicsVector(Single, Single, Single)
+ - y
+
+
+
+
+ - PhysicsVector.PhysicsVector(Single, Single, Single)
+ - z
+
+
+
+
+
+
+
+
+ - X
+
+
+
+
+ - X
+ - PhysicsVector.X
+
+
+
+
+
+
+
+
+ - Y
+
+
+
+
+ - Y
+ - PhysicsVector.Y
+
+
+
+
+
+
+
+
+ - Z
+
+
+
+
+ - Z
+ - PhysicsVector.Z
+
+
+
+
+
+
+
+
+ - PhysicsVector.Zero
+ - OpenSim.Physics.Manager.PhysicsVector
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ - OpenSim.RegionServer
+
+
+
+
+ - OpenSim.RegionServer
+
+
+
+
+ - OpenSim.RegionServer
+
+
+
+
+ - OpenSim.RegionServer
+
+
+
+
+ - OpenSim.RegionServer
+
+
+
+
+
+
+
+
+
+
+
+
+ - ID
+ - transactionID
+ - Id
+
+
+
+
+
+
+
+
+ - ID
+ - transactionID
+ - Id
+
+
+
+
+
+
+
+
+ - ID
+ - transactionID
+ - Id
+
+
+
+
+
+
+
+
+ - ID
+ - assetID
+ - Id
+
+
+
+
+ - AgentAssetUpload.HandleUploadPacket(AssetUploadRequestPacket, LLUUID):Void
+ - System.Int32.ToString(System.String)
+ - System.Int32.ToString(System.String,System.IFormatProvider)
+
+
+ - AgentAssetUpload.HandleUploadPacket(AssetUploadRequestPacket, LLUUID):Void
+ - System.Int32.ToString(System.String)
+ - System.Int32.ToString(System.String,System.IFormatProvider)
+
+
+
+
+ - 'assetID'
+ - AgentAssetUpload.HandleUploadPacket(AssetUploadRequestPacket, LLUUID):Void
+
+
+ - 'pack'
+ - AgentAssetUpload.HandleUploadPacket(AssetUploadRequestPacket, LLUUID):Void
+
+
+
+
+
+
+
+
+ - AgentAssetUpload.HandleXferPacket(SendXferPacketPacket):Void
+ - xfer
+ - xferPacket
+
+
+
+
+ - Xfer
+ - AgentAssetUpload.HandleXferPacket(SendXferPacketPacket):Void
+
+
+
+
+
+
+
+
+
+
+
+
+ - AssetTransaction.AssetTransaction()
+ - UploadComplete
+ - System.Boolean
+ - false
+
+
+
+
+
+
+
+
+ - AddToInventory
+
+
+
+
+
+
+
+
+ - Asset
+
+
+
+
+
+
+
+
+ - InventFolder
+
+
+
+
+
+
+
+
+ - TransactionID
+
+
+
+
+
+
+
+
+ - UploadComplete
+
+
+
+
+
+
+
+
+ - XferID
+
+
+
+
+ - Xfer
+ - AssetTransaction.XferID
+
+
+
+
+
+
+
+
+
+
+ - Grid
+ - OpenSim.Framework.Grid
+
+
+
+
+
+
+
+
+ - AssetDll
+
+
+
+
+
+
+
+
+ - AssetServer
+
+
+
+
+
+
+
+
+ - GridDll
+
+
+
+
+
+
+
+
+ - GridServer
+
+
+
+
+
+
+
+
+ - Initialise
+ - Grid.Initialise():Void
+
+
+
+
+
+
+
+
+ - Grid.LoadAssetDll(String):IAssetServer
+
+
+
+
+
+
+
+
+ - Grid.LoadGridDll(String):IGridServer
+
+
+
+
+
+
+
+
+
+
+ - Sim
+ - OpenSim.OpenSimApplication
+
+
+
+
+
+
+
+
+ - OpenSimApplication.RemoveClientCircuit(UInt32):Void
+ - circuitcode
+ - circuitcode
+
+
+
+
+
+
+
+
+ - OpenSimApplication.SendPacketTo(Byte[], Int32, SocketFlags, UInt32):Void
+ - circuitcode
+ - circuitcode
+
+
+
+
+
+
+
+
+ - StartUp
+ - method
+ - StartUp
+ - Startup
+
+
+
+
+
+
+
+
+
+
+ - Sim
+ - OpenSim.OpenSimMain
+
+
+
+
+ - OpenSim.OpenSimMain
+ - System.Timers.Timer, System.Net.Sockets.Socket
+
+
+
+
+
+
+
+
+ - OpenSimMain.OpenSimMain()
+ - loginserver
+ - System.Boolean
+ - false
+
+
+ - OpenSimMain.OpenSimMain()
+ - sandbox
+ - System.Boolean
+ - false
+
+
+
+
+
+
+
+
+ - _physicsEngine
+
+
+
+
+ - _physicsEngine
+
+
+
+
+
+
+
+
+ - OpenSimMain.LoadConfigDll(String):SimConfig
+
+
+
+
+
+
+
+
+ - loginserver
+
+
+
+
+ - loginserver
+ - OpenSimMain.loginserver
+
+
+
+
+
+
+
+
+ - sandbox
+
+
+
+
+
+
+
+
+ - Server
+
+
+
+
+
+
+
+
+ - Timer.set_Interval(Double):Void
+ - OpenSimMain.StartUp():Void
+
+
+
+
+ - OpenSimMain.StartUp():Void
+ - System.UInt32.ToString
+ - System.UInt32.ToString(System.IFormatProvider)
+
+
+ - OpenSimMain.StartUp():Void
+ - System.UInt32.ToString
+ - System.UInt32.ToString(System.IFormatProvider)
+
+
+
+
+
+
+
+
+
+
+ - Sim
+ - OpenSim.OpenSimRoot
+
+
+
+
+
+
+
+
+ - OpenSimRoot.OpenSimRoot()
+ - Sandbox
+ - System.Boolean
+ - false
+
+
+
+
+
+
+
+
+ - Application
+
+
+
+
+
+
+
+
+ - AssetCache
+
+
+
+
+
+
+
+
+ - Cfg
+
+
+
+
+ - Cfg
+ - OpenSimRoot.Cfg
+
+
+
+
+
+
+
+
+ - ClientThreads
+
+
+
+
+
+
+
+
+ - GridServers
+
+
+
+
+
+
+
+
+ - HttpServer
+
+
+
+
+
+
+
+
+ - InventoryCache
+
+
+
+
+
+
+
+
+ - LocalWorld
+
+
+
+
+
+
+
+
+ - Sandbox
+
+
+
+
+
+
+
+
+ - StartUp
+ - method
+ - StartUp
+ - Startup
+
+
+
+
+
+
+
+
+ - startuptime
+
+
+
+
+ - startuptime
+ - OpenSimRoot.startuptime
+
+
+
+
+
+
+
+
+
+
+ - Que
+ - OpenSim.QueItem
+
+
+
+
+
+
+
+
+ - Incoming
+
+
+
+
+
+
+
+
+ - Packet
+
+
+
+
+
+
+
+
+
+
+ - Sim
+ - OpenSim.SimClient
+
+
+
+
+ - OpenSim.SimClient
+ - System.Timers.Timer
+
+
+
+
+
+
+
+
+ - SimClient.SimClient(EndPoint, UseCircuitCodePacket)
+ - Sequence
+ - System.UInt32
+ - 0
+
+
+ - SimClient.SimClient(EndPoint, UseCircuitCodePacket)
+ - debug
+ - System.Boolean
+ - false
+
+
+
+
+ - Timer.Timer(Double)
+ - SimClient.SimClient(EndPoint, UseCircuitCodePacket)
+
+
+
+
+ - SimClient.SimClient(EndPoint, UseCircuitCodePacket)
+ - initialcirpack
+ - initialcirpack
+
+
+
+
+
+
+
+
+ - AgentID
+
+
+
+
+
+
+
+
+ - CircuitCode
+
+
+
+
+
+
+
+
+ - ClientAvatar
+
+
+
+
+
+
+
+
+ - NewPack
+
+
+
+
+
+
+
+
+ - SimClient.newAssetFolder
+
+
+
+
+
+
+
+
+ - NewPack
+
+
+
+
+
+
+
+
+ - Pack
+
+
+
+
+ - SimClient.ProcessInPacket(Packet):Void
+ - wear
+ - libsecondlife.Packets.AgentIsNowWearingPacket
+
+
+
+
+ - op_Equality
+ - ""
+ - SimClient.ProcessInPacket(Packet):Void
+
+
+
+
+
+
+
+
+ - SimClient.ProcessOutPacket(Packet):Void
+ - System.Exception
+
+
+
+
+ - Pack
+
+
+
+
+
+
+
+
+ - SecureSessionID
+
+
+
+
+
+
+
+
+ - SessionID
+
+
+
+
+
+
+
+
+ - userEP
+
+
+
+
+
+
+
+
+
+
+ - OpenSim.SimConsole
+ - OpenSim.Framework.Console.ConsoleBase
+
+
+
+
+ - Sim
+ - OpenSim.SimConsole
+
+
+
+
+
+
+
+
+ - SimConsole.SimConsole(ConsoleType, String, Int32)
+ - constype
+ - constype
+
+
+
+
+ - SimConsole.SimConsole(ConsoleType, String, Int32)
+ - sparam
+ - sparam
+
+
+
+
+ - SimConsole.SimConsole(ConsoleType, String, Int32)
+ - iparam
+ - iparam
+
+
+
+
+ - iparam
+ - SimConsole.SimConsole(ConsoleType, String, Int32)
+
+
+
+
+ - sparam
+ - SimConsole.SimConsole(ConsoleType, String, Int32)
+
+
+
+
+
+
+
+
+ - op_Equality
+ - ""
+ - SimConsole.CmdPrompt(String, String):String
+
+
+
+
+
+
+
+
+ - SimConsole.ConsType
+
+
+
+
+
+
+
+
+ - SimConsole.MainConsolePrompt():Void
+ - System.UInt64.ToString
+ - System.UInt64.ToString(System.IFormatProvider)
+
+
+
+
+
+
+
+
+ - 'cmdparams'
+ - SimConsole.RunCmd(String, String[]):Object
+
+
+
+
+
+
+
+
+ - SimConsole.ShowCommands(String):Void
+ - System.String.Format(System.String,System.Object[])
+ - System.String.Format(System.IFormatProvider,System.String,System.Object[])
+
+
+ - SimConsole.ShowCommands(String):Void
+ - System.String.Format(System.String,System.Object[])
+ - System.String.Format(System.IFormatProvider,System.String,System.Object[])
+
+
+
+
+
+
+
+
+
+
+
+
+ - Version
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ - ID
+ - imageID
+ - Id
+
+
+
+
+
+
+
+
+ - AssetRequests
+
+
+
+
+ - System.Collections.Generic.List`1<OpenSim.Assets.AssetRequest>
+ - AssetCache.AssetRequests
+
+
+
+
+
+
+
+
+ - Assets
+
+
+
+
+
+
+
+
+ - sourceAsset
+ - AssetCache.CloneAsset(LLUUID, AssetInfo):AssetInfo
+ - OpenSim.Assets.AssetInfo
+ - OpenSim.Framework.Assets.AssetBase
+
+
+
+
+ - AssetCache.CloneAsset(LLUUID, AssetInfo):AssetInfo
+
+
+
+
+ - newOwner
+ - AssetCache.CloneAsset(LLUUID, AssetInfo):AssetInfo
+
+
+
+
+ - 'sourceAsset'
+ - AssetCache.CloneAsset(LLUUID, AssetInfo):AssetInfo
+
+
+
+
+
+
+
+
+ - source
+ - AssetCache.CloneImage(LLUUID, TextureImage):TextureImage
+ - OpenSim.Assets.TextureImage
+ - OpenSim.Framework.Assets.AssetBase
+
+
+
+
+ - AssetCache.CloneImage(LLUUID, TextureImage):TextureImage
+
+
+
+
+ - newOwner
+ - AssetCache.CloneImage(LLUUID, TextureImage):TextureImage
+
+
+
+
+ - 'source'
+ - AssetCache.CloneImage(LLUUID, TextureImage):TextureImage
+
+
+
+
+
+
+
+
+ - ID
+ - agentID
+ - Id
+
+
+
+
+
+
+
+
+ - ID
+ - assetID
+ - Id
+
+
+
+
+
+
+
+
+ - RequestedAssets
+
+
+
+
+
+
+
+
+ - RequestedTextures
+
+
+
+
+
+
+
+
+ - AssetCache.RunAssetManager():Void
+ - System.Exception
+
+
+
+
+
+
+
+
+ - TextureRequests
+
+
+
+
+ - System.Collections.Generic.List`1<OpenSim.Assets.AssetRequest>
+ - AssetCache.TextureRequests
+
+
+
+
+
+
+
+
+ - Textures
+
+
+
+
+
+
+
+
+
+
+ - OpenSim.Assets.AssetInfo
+ - OpenSim.Framework.Assets.AssetBase
+
+
+
+
+
+
+
+
+ - AssetInfo.AssetInfo(AssetBase)
+ - a
+ - aBase
+
+
+
+
+ - 'aBase'
+ - AssetInfo.AssetInfo(AssetBase)
+
+
+
+
+
+
+
+
+
+
+
+
+ - AssetRequest.AssetRequest()
+ - DataPointer
+ - System.Int64
+ - 0
+
+
+ - AssetRequest.AssetRequest()
+ - NumPackets
+ - System.Int32
+ - 0
+
+
+ - AssetRequest.AssetRequest()
+ - PacketCounter
+ - System.Int32
+ - 0
+
+
+
+
+
+
+
+
+ - AssetInf
+
+
+
+
+
+
+
+
+ - DataPointer
+
+
+
+
+
+
+
+
+ - ImageInfo
+
+
+
+
+
+
+
+
+ - IsTextureRequest
+
+
+
+
+
+
+
+
+ - NumPackets
+
+
+
+
+ - Num
+ - AssetRequest.NumPackets
+
+
+
+
+
+
+
+
+ - PacketCounter
+
+
+
+
+
+
+
+
+ - RequestAssetID
+
+
+
+
+
+
+
+
+ - RequestUser
+
+
+
+
+
+
+
+
+ - TransferRequestID
+
+
+
+
+
+
+
+
+
+
+
+
+ - ID
+ - folderID
+ - Id
+
+
+
+
+
+
+
+
+ - ID
+ - clientID
+ - Id
+
+
+
+
+
+
+
+
+ - ID
+ - folderID
+ - Id
+
+
+
+
+
+
+
+
+ - ID
+ - folderID
+ - Id
+
+
+
+
+
+
+
+
+ - FetchItems
+
+
+
+
+
+
+
+
+ - FetchDescend
+
+
+
+
+
+
+
+
+ - ID
+ - agentID
+ - Id
+
+
+
+
+
+
+
+
+ - ID
+ - itemID
+ - Id
+
+
+
+
+
+
+
+
+
+
+ - OpenSim.Assets.TextureImage
+ - OpenSim.Framework.Assets.AssetBase
+
+
+
+
+
+
+
+
+ - TextureImage.TextureImage(AssetBase)
+ - a
+ - aBase
+
+
+
+
+ - 'aBase'
+ - TextureImage.TextureImage(AssetBase)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ - Sim
+ - OpenSim.CAPS.SimCAPSHTTPServer
+
+
+
+
+ - SimCAPSHTTPServer
+
+
+
+
+ - OpenSim.CAPS.SimCAPSHTTPServer
+ - System.Net.HttpListener
+
+
+
+
+
+
+
+
+ - SimCAPSHTTPServer.HandleRequest(Object):Void
+ - stateinfo
+ - stateinfo
+
+
+
+
+
+
+
+
+ - HTTPD
+
+
+
+
+
+
+
+
+ - Listener
+
+
+
+
+
+
+
+
+ - SimCAPSHTTPServer.LoadAdminPage():Void
+ - System.Exception
+
+
+
+
+
+
+
+
+ - SimCAPSHTTPServer.ParseLLSDXML(String):String
+
+
+
+
+ - requestBody
+ - SimCAPSHTTPServer.ParseLLSDXML(String):String
+
+
+
+
+
+
+
+
+ - SimCAPSHTTPServer.ParseREST(String, String, String):String
+ - System.Exception
+
+
+
+
+ - SimCAPSHTTPServer.ParseREST(String, String, String):String
+ - System.String.Format(System.String,System.Object[])
+ - System.String.Format(System.IFormatProvider,System.String,System.Object[])
+
+
+
+
+
+
+
+
+ - SimCAPSHTTPServer.ParseXMLRPC(String):String
+ - System.Exception
+
+
+
+
+ - SimCAPSHTTPServer.ParseXMLRPC(String):String
+
+
+
+
+ - SimCAPSHTTPServer.ParseXMLRPC(String):String
+ - System.Convert.ToUInt32(System.Object)
+ - System.Convert.ToUInt32(System.Object,System.IFormatProvider)
+
+
+
+
+
+
+
+
+ - SimCAPSHTTPServer.StartHTTP():Void
+ - System.Exception
+
+
+
+
+ - SimCAPSHTTPServer.StartHTTP():Void
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ - mesh
+
+
+
+
+ - System.Collections.Generic.List`1<OpenSim.types.Triangle>
+ - Mesh.mesh
+
+
+
+
+
+
+
+
+ - Mesh.op_Addition(Mesh, Mesh):Mesh
+ - a
+
+
+
+
+ - Mesh.op_Addition(Mesh, Mesh):Mesh
+ - b
+
+
+
+
+ - Add
+ - Mesh.op_Addition(Mesh, Mesh):Mesh
+
+
+
+
+ - Mesh
+ - Mesh.op_Addition(Mesh, Mesh):Mesh
+
+
+
+
+
+
+
+
+
+
+
+
+ - A
+
+
+
+
+ - B
+
+
+
+
+ - C
+
+
+
+
+ - Triangle.Triangle(Vector3, Vector3, Vector3)
+ - A
+
+
+
+
+ - Triangle.Triangle(Vector3, Vector3, Vector3)
+ - B
+
+
+
+
+ - Triangle.Triangle(Vector3, Vector3, Vector3)
+ - C
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ - LocalUserProfileManager.CustomiseResponse(Hashtable&, UserProfile):Void
+ - System.Int32.ToString
+ - System.Int32.ToString(System.IFormatProvider)
+
+
+ - LocalUserProfileManager.CustomiseResponse(Hashtable&, UserProfile):Void
+ - System.Int32.ToString
+ - System.Int32.ToString(System.IFormatProvider)
+
+
+
+
+ - LocalUserProfileManager.CustomiseResponse(Hashtable&, UserProfile):Void
+ - System.Single.ToString
+ - System.Single.ToString(System.IFormatProvider)
+
+
+ - LocalUserProfileManager.CustomiseResponse(Hashtable&, UserProfile):Void
+ - System.Single.ToString
+ - System.Single.ToString(System.IFormatProvider)
+
+
+ - LocalUserProfileManager.CustomiseResponse(Hashtable&, UserProfile):Void
+ - System.Single.ToString
+ - System.Single.ToString(System.IFormatProvider)
+
+
+ - LocalUserProfileManager.CustomiseResponse(Hashtable&, UserProfile):Void
+ - System.Single.ToString
+ - System.Single.ToString(System.IFormatProvider)
+
+
+ - LocalUserProfileManager.CustomiseResponse(Hashtable&, UserProfile):Void
+ - System.Single.ToString
+ - System.Single.ToString(System.IFormatProvider)
+
+
+ - LocalUserProfileManager.CustomiseResponse(Hashtable&, UserProfile):Void
+ - System.Single.ToString
+ - System.Single.ToString(System.IFormatProvider)
+
+
+
+
+
+
+
+
+
+
+ - OpenSim.UserServer.LoginServer
+ - OpenSim.Framework.Grid.LoginService
+
+
+
+
+ - OpenSim.UserServer.LoginServer
+ - System.Net.Sockets.Socket
+
+
+
+
+ - Login
+ - LoginServer
+ - LogOn
+
+
+
+
+
+
+
+
+ - LoginServer.LoginServer(IGridServer)
+ - _needPasswd
+ - System.Boolean
+ - false
+
+
+ - LoginServer.LoginServer(IGridServer)
+ - userAccounts
+ - System.Boolean
+ - false
+
+
+
+
+
+
+
+
+ - LoginServer.Authenticate(String, String, String):Boolean
+ - passwd
+ - passwd
+
+
+
+
+
+
+
+
+ - clientAddress
+
+
+
+
+
+
+
+
+ - Customise
+ - LoginServer.CustomiseLoginResponse(Hashtable, String, String):Void
+
+
+
+
+ - Login
+ - CustomiseLoginResponse
+ - LogOn
+
+
+
+
+
+
+
+
+ - LoginServer.EncodePassword(String):String
+ - System.String.ToLower
+ - System.String.ToLower(System.Globalization.CultureInfo)
+
+
+
+
+
+
+
+
+ - LoginServer.GetAgentId(String, String):LLUUID
+ - System.Int32.ToString(System.String)
+ - System.Int32.ToString(System.String,System.IFormatProvider)
+
+
+
+
+
+
+
+
+ - LoginServer.InitializeLogin():Void
+ - 4
+ - UserProfileManager.SetKeys(String, String, String, String):Void
+ - Welcome to OpenSim
+
+
+
+
+ - Sim
+ - OpenSim
+
+
+
+
+
+
+
+
+ - LoginServer.LoginRequest(StreamReader, StreamWriter):Void
+ - System.Exception
+
+
+
+
+ - LoginServer.LoginRequest(StreamReader, StreamWriter):Void
+ - System.Convert.ToInt32(System.String)
+ - System.Convert.ToInt32(System.String,System.IFormatProvider)
+
+
+
+
+ - op_Inequality
+ - ""
+ - LoginServer.LoginRequest(StreamReader, StreamWriter):Void
+
+
+
+
+
+
+
+
+ - writer
+ - LoginServer.ProcessXmlRequest(XmlRpcRequest, StreamWriter):Boolean
+ - System.IO.StreamWriter
+ - System.IO.TextWriter
+
+
+
+
+ - LoginServer.ProcessXmlRequest(XmlRpcRequest, StreamWriter):Boolean
+ - System.Int32.ToString
+ - System.Int32.ToString(System.IFormatProvider)
+
+
+
+
+ - LoginServer.ProcessXmlRequest(XmlRpcRequest, StreamWriter):Boolean
+ - System.Int32.ToString(System.String)
+ - System.Int32.ToString(System.String,System.IFormatProvider)
+
+
+
+
+ - 'request'
+ - LoginServer.ProcessXmlRequest(XmlRpcRequest, StreamWriter):Boolean
+
+
+ - 'writer'
+ - LoginServer.ProcessXmlRequest(XmlRpcRequest, StreamWriter):Boolean
+
+
+ - 'writer'
+ - LoginServer.ProcessXmlRequest(XmlRpcRequest, StreamWriter):Boolean
+
+
+
+
+
+
+
+
+ - remoteAddress
+
+
+
+
+
+
+
+
+ - LoginServer.RunLogin():Void
+ - System.Exception
+
+
+ - LoginServer.RunLogin():Void
+ - System.Exception
+
+
+
+
+ - LoginServer.RunLogin():Void
+ - clientEndPoint
+ - System.Net.IPEndPoint
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ - Avatar.Avatar()
+ - PhysicsEngineFlying
+ - System.Boolean
+ - false
+
+
+
+
+
+
+
+
+ - Avatar.Avatar(SimClient)
+ - _updateCount
+ - System.Int16
+ - 0
+
+
+ - Avatar.Avatar(SimClient)
+ - avatarAppearanceTexture
+ - libsecondlife.LLObject+TextureEntry
+ - null
+
+
+ - Avatar.Avatar(SimClient)
+ - movementflag
+ - System.Byte
+ - 0
+
+
+ - Avatar.Avatar(SimClient)
+ - updateflag
+ - System.Boolean
+ - false
+
+
+
+
+ - TheClient
+
+
+
+
+
+
+
+
+ - anim_seq
+
+
+
+
+ - anim
+ - Avatar.anim_seq
+
+
+
+
+ - anim_seq
+
+
+
+
+
+
+
+
+ - Animations
+
+
+
+
+
+
+
+
+ - RegionInfo
+
+
+
+
+ - RegionInfo
+ - Avatar.CompleteMovement(World):Void
+
+
+
+
+
+
+
+
+ - ControllingClient
+
+
+
+
+
+
+
+
+ - current_anim
+
+
+
+
+ - anim
+ - Avatar.current_anim
+
+
+
+
+ - current_anim
+
+
+
+
+
+
+
+
+ - firstname
+
+
+
+
+ - firstname
+ - Avatar.firstname
+
+
+
+
+
+
+
+
+ - lastname
+
+
+
+
+ - lastname
+ - Avatar.lastname
+
+
+
+
+
+
+
+
+ - Anims
+ - Avatar.LoadAnims():Void
+
+
+
+
+
+
+
+
+ - PhysActor
+
+
+
+
+
+
+
+
+ - PhysicsEngineFlying
+
+
+
+
+
+
+
+
+ - Anim
+ - Avatar.SendAnimPack():Void
+
+
+
+
+
+
+
+
+ - 'userInfo'
+ - Avatar.SendAppearanceToOtherAgent(SimClient):Void
+
+
+
+
+
+
+
+
+ - RegionInfo
+
+
+
+
+ - RegionInfo
+ - Avatar.SendRegionHandshake(World):Void
+
+
+
+
+
+
+
+
+
+
+
+
+ - AnimsLLUUID
+
+
+
+
+ - Anims
+ - AvatarAnimations.AnimsLLUUID
+
+
+
+
+
+
+
+
+ - AnimsNames
+
+
+
+
+ - Anims
+ - AvatarAnimations.AnimsNames
+
+
+
+
+
+
+
+
+ - Anims
+ - AvatarAnimations.LoadAnims():Void
+
+
+
+
+
+
+
+
+
+
+
+
+ - Entity.Entity()
+ - localid
+ - System.UInt32
+ - 0
+
+
+
+
+
+
+
+
+ - addForces
+
+
+
+
+
+
+
+
+ - BackUp
+ - method
+ - BackUp
+ - Backup
+
+
+
+
+
+
+
+
+ - children
+
+
+
+
+ - System.Collections.Generic.List`1<OpenSim.world.Entity>
+ - Entity.children
+
+
+
+
+
+
+
+
+ - getMesh
+
+
+
+
+
+
+
+
+ - getName
+
+
+
+
+
+
+
+
+ - localid
+
+
+
+
+ - localid
+ - Entity.localid
+
+
+
+
+
+
+
+
+ - name
+
+
+
+
+
+
+
+
+ - position
+
+
+
+
+
+
+
+
+ - rotation
+
+
+
+
+
+
+
+
+ - update
+
+
+
+
+
+
+
+
+ - uuid
+
+
+
+
+ - uuid
+ - Entity.uuid
+
+
+
+
+
+
+
+
+ - velocity
+
+
+
+
+
+
+
+
+
+
+
+
+ - X
+
+
+
+
+ - X
+ - NewForce.X
+
+
+
+
+
+
+
+
+ - Y
+
+
+
+
+ - Y
+ - NewForce.Y
+
+
+
+
+
+
+
+
+ - Z
+
+
+
+
+ - Z
+ - NewForce.Z
+
+
+
+
+
+
+
+
+
+
+ - 'UpdateFlag'
+ - updateFlag
+
+
+
+
+
+
+
+
+ - Primitive.Primitive()
+ - dirtyFlag
+ - System.Boolean
+ - false
+
+
+ - Primitive.Primitive()
+ - mesh_cutbegin
+ - System.Single
+ - 0.0
+
+
+ - Primitive.Primitive()
+ - newPrimFlag
+ - System.Boolean
+ - false
+
+
+ - Primitive.Primitive()
+ - physicsEnabled
+ - System.Boolean
+ - false
+
+
+ - Primitive.Primitive()
+ - physicstest
+ - System.Boolean
+ - false
+
+
+ - Primitive.Primitive()
+ - updateFlag
+ - System.Boolean
+ - false
+
+
+
+
+
+
+
+
+ - localID-702000
+ - Primitive.CreateFromPacket(ObjectAddPacket, LLUUID, UInt32):Void
+
+
+
+
+ - ID
+ - agentID
+ - Id
+
+
+
+
+ - ID
+ - localID
+ - Id
+
+
+
+
+ - Primitive.CreateFromPacket(ObjectAddPacket, LLUUID, UInt32):Void
+ - System.UInt32.ToString(System.String)
+ - System.UInt32.ToString(System.String,System.IFormatProvider)
+
+
+
+
+ - 'addPacket'
+ - Primitive.CreateFromPacket(ObjectAddPacket, LLUUID, UInt32):Void
+
+
+
+
+
+
+
+
+ - 'store'
+ - Primitive.CreateFromStorage(PrimData):Void
+
+
+
+
+
+
+
+
+ - dirtyFlag
+
+
+
+
+
+
+
+
+ - mesh_cutbegin
+
+
+
+
+ - cutbegin
+ - Primitive.mesh_cutbegin
+
+
+
+
+ - mesh_cutbegin
+
+
+
+
+
+
+
+
+ - mesh_cutend
+
+
+
+
+ - cutend
+ - Primitive.mesh_cutend
+
+
+
+
+ - mesh_cutend
+
+
+
+
+
+
+
+
+ - newPrimFlag
+
+
+
+
+
+
+
+
+ - PhysActor
+
+
+
+
+
+
+
+
+ - primData
+
+
+
+
+
+
+
+
+ - RemoteClient
+
+
+
+
+ - 'RemoteClient'
+ - Primitive.UpdateClient(SimClient):Void
+
+
+
+
+
+
+
+
+ - updateFlag
+
+
+
+
+
+
+
+
+ - 'pack'
+ - Primitive.UpdateObjectFlags(ObjectFlagUpdatePacket):Void
+
+
+
+
+
+
+
+
+ - 'addPacket'
+ - Primitive.UpdateShape(ObjectDataBlock):Void
+
+
+
+
+
+
+
+
+
+
+
+
+ - ScriptEngine.ScriptEngine(World)
+ - env
+ - env
+
+
+
+
+ - env
+ - ScriptEngine.ScriptEngine(World)
+
+
+
+
+
+
+
+
+ - ScriptEngine.LoadScript():Void
+
+
+
+
+
+
+
+
+
+
+
+
+ - HeightMap
+
+
+
+
+
+
+
+
+
+
+ - World
+ - OpenSim.world
+
+
+
+
+
+
+
+
+ - World.World()
+ - _localNumber
+ - System.UInt32
+ - 0
+
+
+
+
+
+
+
+
+ - _localNumber
+
+
+
+
+ - _localNumber
+
+
+
+
+
+
+
+
+ - AgentClient
+
+
+
+
+
+
+
+
+ - AgentClient
+
+
+
+
+
+
+
+
+ - DeRezPacket
+
+
+
+
+ - AgentClient
+
+
+
+
+ - World.DeRezObject(DeRezObjectPacket, SimClient):Void
+ - Rez
+ - DeRezPacket
+
+
+
+
+ - Rez
+ - World.DeRezObject(DeRezObjectPacket, SimClient):Void
+
+
+
+
+ - AgentClient
+ - World.DeRezObject(DeRezObjectPacket, SimClient):Void
+
+
+
+
+ - De
+ - World.DeRezObject(DeRezObjectPacket, SimClient):Void
+
+
+
+
+
+
+
+
+ - Entities
+
+
+
+
+
+
+
+
+ - RemoteClient
+
+
+
+
+ - Prims
+ - World.GetInitialPrims(SimClient):Void
+
+
+
+
+
+
+
+
+ - LandMap
+
+
+
+
+
+
+
+
+ - Prims
+ - World.LoadPrimsFromStorage():Void
+
+
+
+
+
+
+
+
+ - World.LoadStorageDLL(String):Boolean
+
+
+
+
+
+
+
+
+ - localStorage
+
+
+
+
+
+
+
+
+ - World.Rand
+
+
+
+
+
+
+
+
+ - Scripts
+
+
+
+
+
+
+
+
+ - RemoteClient
+
+
+
+
+ - 'RemoteClient'
+ - World.SendLayerData(SimClient):Void
+
+
+ - 'RemoteClient'
+ - World.SendLayerData(SimClient):Void
+
+
+ - 'RemoteClient'
+ - World.SendLayerData(SimClient):Void
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ - IScriptHost.Register(IScript):Boolean
+ - iscript
+ - iscript
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ - OpenSim.Storage.LocalStorageDb4o
+
+
+
+
+ - OpenSim.Storage.LocalStorageDb4o
+
+
+
+
+ - OpenSim.Storage.LocalStorageDb4o
+
+
+
+
+
+
+
+
+
+
+
+
+ - Db4LocalStorage.Db4LocalStorage()
+ - System.Exception
+
+
+
+
+
+
+
+
+ - 'receiver'
+ - Db4LocalStorage.LoadPrimitives(ILocalStorageReceiver):Void
+
+
+
+
+
+
+
+
+ - 'prim'
+ - Db4LocalStorage.StorePrim(PrimData):Void
+
+
+
+
+
+
+
+
+
+
+ - UUIDQuery
+
+
+
+
+
+
+
+
+ - 'prim'
+ - UUIDQuery.Match(PrimData):Boolean
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ - OpenSim.Physics.BasicPhysicsPlugin
+
+
+
+
+
+
+
+
+
+ - OpenSim.Physics.BasicPhysicsPlugin
+
+
+
+
+
+
+
+
+
+ - OpenSim.Physics.BasicPhysicsPlugin
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ - BasicActor.flying
+
+
+
+
+
+
+
+
+ - BasicActor.SetAcceleration(PhysicsVector):Void
+ - accel
+ - accel
+
+
+
+
+
+
+
+
+
+
+ - Plugin
+ - OpenSim.Physics.BasicPhysicsPlugin.BasicPhysicsPlugin
+
+
+
+
+ - BasicPhysicsPlugin
+ - OpenSim.Physics.BasicPhysicsPlugin
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ - OpenSim.Physics.OdePlugin
+
+
+
+
+ - OpenSim.Physics.OdePlugin
+
+
+
+
+ - OpenSim.Physics.OdePlugin
+
+
+
+
+
+
+
+
+
+
+ - OdeCharacter
+
+
+
+
+
+
+
+
+ - parent_scene
+ - OdeCharacter.OdeCharacter(OdeScene, PhysicsVector)
+
+
+
+
+ - 'pos'
+ - OdeCharacter.OdeCharacter(OdeScene, PhysicsVector)
+
+
+
+
+
+
+
+
+ - OdeCharacter.capsule_geom
+
+
+
+
+
+
+
+
+ - OdeCharacter.gravityAccel
+
+
+
+
+
+
+
+
+ - OdeCharacter.SetAcceleration(PhysicsVector):Void
+ - accel
+ - accel
+
+
+
+
+
+
+
+
+
+
+ - Plugin
+ - OpenSim.Physics.OdePlugin.OdePlugin
+
+
+
+
+ - OdePlugin
+ - OpenSim.Physics.OdePlugin
+
+
+
+
+
+
+
+
+
+
+ - OdePrim._position
+
+
+
+
+
+
+
+
+ - OdePrim.SetAcceleration(PhysicsVector):Void
+ - accel
+ - accel
+
+
+
+
+
+
+
+
+
+
+
+
+ - 'position'
+ - OdeScene.AddPrim(PhysicsVector, PhysicsVector):PhysicsActor
+
+
+ - 'size'
+ - OdeScene.AddPrim(PhysicsVector, PhysicsVector):PhysicsActor
+
+
+
+
+
+
+
+
+ - OdeScene.Land
+
+
+
+
+
+
+
+
+ - OdeScene.LandGeom
+
+
+
+
+
+
+
+
+ - 'heightMap'
+ - OdeScene.SetTerrain(Single[]):Void
+
+
+ - 'heightMap'
+ - OdeScene.SetTerrain(Single[]):Void
+
+
+
+
+
+
+
+
+ - space
+
+
+
+
+ - space
+
+
+
+
+
+
+
+
+ - world
+
+
+
+
+ - world
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ - OpenSim.Physics.PhysXPlugin
+
+
+
+
+ - OpenSim.Physics.PhysXPlugin
+
+
+
+
+ - OpenSim.Physics.PhysXPlugin
+
+
+
+
+
+
+
+
+
+
+
+
+ - PhysXCharacter.SetAcceleration(PhysicsVector):Void
+ - accel
+ - accel
+
+
+
+
+
+
+
+
+
+
+ - Plugin
+ - OpenSim.Physics.PhysXPlugin.PhysXPlugin
+
+
+
+
+ - PhysXPlugin
+ - OpenSim.Physics.PhysXPlugin
+
+
+
+
+
+
+
+
+
+
+ - PhysXPrim._position
+
+
+
+
+
+
+
+
+ - PhysXPrim.SetAcceleration(PhysicsVector):Void
+ - accel
+ - accel
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Save it for a rainy day.
+ Save it for a rainy day.
+ Save it for a rainy day.
+
+
+
+
+ No valid permission requests were found for assembly '{0}'. You should always specify the minimum security permissions using SecurityAction.RequestMinimum.
+
+
+ Sign '{0}' with a strong name key.
+
+
+ Consider merging the types defined in '{0}' with another namespace.
+
+
+ It appears that field '{0}' is never used or is only ever assigned to. Use this field or remove it.
+
+
+ Change '{0}' to be read-only by removing the property setter.
+
+
+ The compound word '{0}' in {1} '{2}' exists as a discrete term. If your usage is intended to be single word, case it as '{3}'.
+
+
+ '{0}' is marked ComVisible(true) but has the following ComVisible(false) types in its object hierarchy: {1}
+
+
+ Consider changing the type of parameter '{0}' in {1} from {2} to its base type {3}. This method appears to only require base class members in its implementation. Suppress this violation if there is a compelling reason to require the more derived type in the method signature.
+
+
+ '{0}' contains a call chain that results in a call to a virtual method defined by the class. Review the following call stack for unintended consequences: {1}
+
+
+ Modify '{0}' to catch a more specific exception than '{1}' or rethrow the exception.
+
+
+ Remove the readonly declaration from '{0}' or change the field to one that is an immutable reference type. If the reference type '{1}' is, in fact, immutable, exclude this message.
+
+
+ Make '{0}' private or internal (Friend in VB, public private in C++) and provide a public or protected property to access it.
+
+
+ Change '{0}' in {1} to use Collection<T>, ReadOnlyCollection<T> or KeyedCollection<K,V>
+
+
+ {0} initializes field {1} of type {2} to {3}. Remove this initialization as it will be done automatically by the runtime.
+
+
+ {0} passes a literal as parameter {1} of a call to {2}. Retrieve the following string argument from a resource table instead: '{3}'
+
+
+ Consider a design that does not require that '{0}' be a reference parameter.
+
+
+ {0} creates an exception of type '{1}', an exception type that is not sufficiently specific and should never be raised by user code. If this exception instance might be thrown, use a different exception type.
+
+
+ Modify the call to {0} in method {1} to set the timer interval to a value that's greater than or equal to one second.
+
+
+ Correct the casing of member name '{0}'.
+ Correct the casing of namespace name '{0}'.
+ Correct the casing of parameter name '{0}'.
+ Correct the casing of type name '{0}'.
+
+
+ Correct the spelling of the unrecognized token '{0}' in member name '{1}'.
+ Consider providing a more meaningful name than the one-letter token '{0}' in member name '{1}'.
+ Correct the spelling of the unrecognized token '{0}' in namespace '{1}'.
+ In method {0}, correct the spelling of the unrecognized token '{1}' in parameter name '{2}' or strip it entirely if it represents any sort of hungarian notation.
+ In method {0}, consider providing a more meaningful name than the one-letter parameter name '{1}'.
+ Correct the spelling of the unrecognized token '{0}' in type name '{1}'.
+
+
+ Change member names {0} and '{1}' so that they differ by more than case.
+
+
+ Remove all underscores from member '{0}'.
+ Remove all underscores from parameter '{0}'.
+ Remove all underscores from type '{0}'.
+
+
+ Rename '{0}' so that it does not end in '{1}'.
+
+
+ Correct the spelling of the unrecognized token '{0}' in the literal '{1}'.
+
+
+ Correct the capitalization of member name '{0}'.
+ Correct the capitalization of namespace name '{0}'.
+ Correct the capitalization of parameter name '{0}'.
+ Correct the capitalization of type name '{0}'.
+
+
+ Add an AssemblyVersion attribute to '{0}'.
+
+
+ '{0}' should be marked with CLSCompliantAttribute and its value should be true.
+
+
+ Mark '{0}' as ComVisible(false) at the assembly level, then mark all types within the assembly that should be exposed to Com clients as ComVisible(true).
+
+
+ The 'this' parameter (or 'Me' in VB) of {0} is never used. Mark the member as static (or Shared in VB) or use 'this'/'Me' in the method body or at least one property accessor, if appropriate.
+
+
+ Consider making '{0}' non-public or a constant.
+
+
+ Correct the potential overflow in the operation '{0}' in '{1}'.
+
+
+ Provide a method named '{0}' as a friendly alternate for operator {1}.
+
+
+ Consider adding an overload of the equality operator for '{0}' that takes the same parameters as {1}.
+
+
+ '{0}' should override Equals.
+ '{0}' should override the equality (==) and inequality (!=) operators.
+
+
+ Change parameter name '{0}' of method {1} to '{2}' in order to match the identifier as it has been declared in {3}.
+
+
+ Modify {0} to call {1} instead of {2}.
+
+
+ Make '{0}' private.
+
+
+ Add a property getter to '{0}'.
+
+
+ {0} declares a local, '{1}', of type {2}, which is never used or is only assigned to. Use this local or remove it.
+
+
+ Parameter '{0}' of {1} is never used. Remove the parameter or use it in the method body.
+
+
+ Correct the capitalization of '{0}' in member name '{1}'.
+ 'Id' is an abbreviation and therefore is not subject to acronym casing guidelines. Correct the capitalization of 'ID' in member name '{0}' by changing it to 'Id'.
+ 'Id' is an abbreviation and therefore is not subject to acronym casing guidelines. Correct the capitalization of '{0}' in parameter name '{1}' by changing it to '{2}'.
+ Correct the capitalization of '{0}' in type name '{1}'.
+
+
+ {0} makes a call to {1} that does not explicitly provide a CultureInfo. This should be replaced with a call to {2}.
+
+
+ {0} makes a call to {1} that does not explicitly provide an IFormatProvider. This should be replaced with a call to {2}.
+
+
+ Remove the public constructors from '{0}'.
+
+
+ Replace the call to String.{0}({1}) in '{2}' with a call to String.IsNullOrEmpty.
+
+
+ The type name '{0}' conflicts in whole or in part with the namespace name '{1}'. Change either name to eliminate the conflict.
+
+
+ Implement IDisposable on '{0}' as it instantiates members of the following IDisposable types: {1}
+
+
+ Implement IDisposable on '{0}'.
+
+
+ Change the type of parameter '{0}' of method {1} from string to System.Uri, or provide an overload of {1}, that allows '{0}' to be passed as a System.Uri object.
+
+
+ Replace the term '{0}' in member name '{1}' with the preferred alternate '{2}'.
+ Replace the term '{0}' in type name '{1}' with the preferred alternate '{2}'.
+
+
+ Change '{0}' to a property if appropriate.
+
+
+ Validate parameter {0} passed to externally visible method {1}.
+
+
+
+
diff --git a/OpenSim/Addons/Groups/ForeignImporter.cs b/OpenSim/Addons/Groups/ForeignImporter.cs
new file mode 100644
index 0000000000..055f76c60b
--- /dev/null
+++ b/OpenSim/Addons/Groups/ForeignImporter.cs
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSimulator Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.Collections.Generic;
+
+using OpenSim.Framework;
+using OpenSim.Region.Framework.Interfaces;
+using OpenSim.Services.Interfaces;
+
+namespace OpenSim.Groups
+{
+ public class ForeignImporter
+ {
+ IUserManagement m_UserManagement;
+ public ForeignImporter(IUserManagement uman)
+ {
+ m_UserManagement = uman;
+ }
+
+ public GroupMembersData ConvertGroupMembersData(ExtendedGroupMembersData _m)
+ {
+ GroupMembersData m = new GroupMembersData();
+ m.AcceptNotices = _m.AcceptNotices;
+ m.AgentPowers = _m.AgentPowers;
+ m.Contribution = _m.Contribution;
+ m.IsOwner = _m.IsOwner;
+ m.ListInProfile = _m.ListInProfile;
+ m.OnlineStatus = _m.OnlineStatus;
+ m.Title = _m.Title;
+
+ string url = string.Empty, first = string.Empty, last = string.Empty, tmp = string.Empty;
+ Util.ParseUniversalUserIdentifier(_m.AgentID, out m.AgentID, out url, out first, out last, out tmp);
+ if (url != string.Empty)
+ m_UserManagement.AddUser(m.AgentID, first, last, url);
+
+ return m;
+ }
+
+ public GroupRoleMembersData ConvertGroupRoleMembersData(ExtendedGroupRoleMembersData _rm)
+ {
+ GroupRoleMembersData rm = new GroupRoleMembersData();
+ rm.RoleID = _rm.RoleID;
+
+ string url = string.Empty, first = string.Empty, last = string.Empty, tmp = string.Empty;
+ Util.ParseUniversalUserIdentifier(_rm.MemberID, out rm.MemberID, out url, out first, out last, out tmp);
+ if (url != string.Empty)
+ m_UserManagement.AddUser(rm.MemberID, first, last, url);
+
+ return rm;
+ }
+
+ }
+}
diff --git a/OpenSim/Addons/Groups/GroupsExtendedData.cs b/OpenSim/Addons/Groups/GroupsExtendedData.cs
new file mode 100644
index 0000000000..c783b9eeda
--- /dev/null
+++ b/OpenSim/Addons/Groups/GroupsExtendedData.cs
@@ -0,0 +1,533 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSimulator Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.Collections.Generic;
+
+using OpenSim.Framework;
+using OpenMetaverse;
+
+namespace OpenSim.Groups
+{
+ public class ExtendedGroupRecord : GroupRecord
+ {
+ public int MemberCount;
+ public int RoleCount;
+ public string ServiceLocation;
+ public string FounderUUI;
+ }
+
+ public class ExtendedGroupMembershipData : GroupMembershipData
+ {
+ public string AccessToken;
+ }
+
+ public class ExtendedGroupMembersData
+ {
+ // This is the only difference: this is a string
+ public string AgentID;
+ public int Contribution;
+ public string OnlineStatus;
+ public ulong AgentPowers;
+ public string Title;
+ public bool IsOwner;
+ public bool ListInProfile;
+ public bool AcceptNotices;
+ public string AccessToken;
+ }
+
+ public class ExtendedGroupRoleMembersData
+ {
+ public UUID RoleID;
+ // This is the only difference: this is a string
+ public string MemberID;
+
+ }
+
+ public struct ExtendedGroupNoticeData
+ {
+ public UUID NoticeID;
+ public uint Timestamp;
+ public string FromName;
+ public string Subject;
+ public bool HasAttachment;
+ public byte AttachmentType;
+ public string AttachmentName;
+ public UUID AttachmentItemID;
+ public string AttachmentOwnerID;
+
+ public GroupNoticeData ToGroupNoticeData()
+ {
+ GroupNoticeData n = new GroupNoticeData();
+ n.FromName = this.FromName;
+ n.AssetType = this.AttachmentType;
+ n.HasAttachment = this.HasAttachment;
+ n.NoticeID = this.NoticeID;
+ n.Subject = this.Subject;
+ n.Timestamp = this.Timestamp;
+
+ return n;
+ }
+ }
+
+ public class GroupsDataUtils
+ {
+ public static string Sanitize(string s)
+ {
+ return s == null ? string.Empty : s;
+ }
+
+ public static Dictionary GroupRecord(ExtendedGroupRecord grec)
+ {
+ Dictionary dict = new Dictionary();
+ if (grec == null)
+ return dict;
+
+ dict["AllowPublish"] = grec.AllowPublish.ToString();
+ dict["Charter"] = Sanitize(grec.Charter);
+ dict["FounderID"] = grec.FounderID.ToString();
+ dict["FounderUUI"] = Sanitize(grec.FounderUUI);
+ dict["GroupID"] = grec.GroupID.ToString();
+ dict["GroupName"] = Sanitize(grec.GroupName);
+ dict["InsigniaID"] = grec.GroupPicture.ToString();
+ dict["MaturePublish"] = grec.MaturePublish.ToString();
+ dict["MembershipFee"] = grec.MembershipFee.ToString();
+ dict["OpenEnrollment"] = grec.OpenEnrollment.ToString();
+ dict["OwnerRoleID"] = grec.OwnerRoleID.ToString();
+ dict["ServiceLocation"] = Sanitize(grec.ServiceLocation);
+ dict["ShownInList"] = grec.ShowInList.ToString();
+ dict["MemberCount"] = grec.MemberCount.ToString();
+ dict["RoleCount"] = grec.RoleCount.ToString();
+
+ return dict;
+ }
+
+ public static ExtendedGroupRecord GroupRecord(Dictionary dict)
+ {
+ if (dict == null)
+ return null;
+
+ ExtendedGroupRecord grec = new ExtendedGroupRecord();
+ if (dict.ContainsKey("AllowPublish") && dict["AllowPublish"] != null)
+ grec.AllowPublish = bool.Parse(dict["AllowPublish"].ToString());
+
+ if (dict.ContainsKey("Charter") && dict["Charter"] != null)
+ grec.Charter = dict["Charter"].ToString();
+ else
+ grec.Charter = string.Empty;
+
+ if (dict.ContainsKey("FounderID") && dict["FounderID"] != null)
+ grec.FounderID = UUID.Parse(dict["FounderID"].ToString());
+
+ if (dict.ContainsKey("FounderUUI") && dict["FounderUUI"] != null)
+ grec.FounderUUI = dict["FounderUUI"].ToString();
+ else
+ grec.FounderUUI = string.Empty;
+
+ if (dict.ContainsKey("GroupID") && dict["GroupID"] != null)
+ grec.GroupID = UUID.Parse(dict["GroupID"].ToString());
+
+ if (dict.ContainsKey("GroupName") && dict["GroupName"] != null)
+ grec.GroupName = dict["GroupName"].ToString();
+ else
+ grec.GroupName = string.Empty;
+
+ if (dict.ContainsKey("InsigniaID") && dict["InsigniaID"] != null)
+ grec.GroupPicture = UUID.Parse(dict["InsigniaID"].ToString());
+
+ if (dict.ContainsKey("MaturePublish") && dict["MaturePublish"] != null)
+ grec.MaturePublish = bool.Parse(dict["MaturePublish"].ToString());
+
+ if (dict.ContainsKey("MembershipFee") && dict["MembershipFee"] != null)
+ grec.MembershipFee = Int32.Parse(dict["MembershipFee"].ToString());
+
+ if (dict.ContainsKey("OpenEnrollment") && dict["OpenEnrollment"] != null)
+ grec.OpenEnrollment = bool.Parse(dict["OpenEnrollment"].ToString());
+
+ if (dict.ContainsKey("OwnerRoleID") && dict["OwnerRoleID"] != null)
+ grec.OwnerRoleID = UUID.Parse(dict["OwnerRoleID"].ToString());
+
+ if (dict.ContainsKey("ServiceLocation") && dict["ServiceLocation"] != null)
+ grec.ServiceLocation = dict["ServiceLocation"].ToString();
+ else
+ grec.ServiceLocation = string.Empty;
+
+ if (dict.ContainsKey("ShownInList") && dict["ShownInList"] != null)
+ grec.ShowInList = bool.Parse(dict["ShownInList"].ToString());
+
+ if (dict.ContainsKey("MemberCount") && dict["MemberCount"] != null)
+ grec.MemberCount = Int32.Parse(dict["MemberCount"].ToString());
+
+ if (dict.ContainsKey("RoleCount") && dict["RoleCount"] != null)
+ grec.RoleCount = Int32.Parse(dict["RoleCount"].ToString());
+
+ return grec;
+ }
+
+ public static Dictionary GroupMembershipData(ExtendedGroupMembershipData membership)
+ {
+ Dictionary dict = new Dictionary();
+ if (membership == null)
+ return dict;
+
+ dict["AcceptNotices"] = membership.AcceptNotices.ToString();
+ dict["AccessToken"] = Sanitize(membership.AccessToken);
+ dict["Active"] = membership.Active.ToString();
+ dict["ActiveRole"] = membership.ActiveRole.ToString();
+ dict["AllowPublish"] = membership.AllowPublish.ToString();
+ dict["Charter"] = Sanitize(membership.Charter);
+ dict["Contribution"] = membership.Contribution.ToString();
+ dict["FounderID"] = membership.FounderID.ToString();
+ dict["GroupID"] = membership.GroupID.ToString();
+ dict["GroupName"] = Sanitize(membership.GroupName);
+ dict["GroupPicture"] = membership.GroupPicture.ToString();
+ dict["GroupPowers"] = membership.GroupPowers.ToString();
+ dict["GroupTitle"] = Sanitize(membership.GroupTitle);
+ dict["ListInProfile"] = membership.ListInProfile.ToString();
+ dict["MaturePublish"] = membership.MaturePublish.ToString();
+ dict["MembershipFee"] = membership.MembershipFee.ToString();
+ dict["OpenEnrollment"] = membership.OpenEnrollment.ToString();
+ dict["ShowInList"] = membership.ShowInList.ToString();
+
+ return dict;
+ }
+
+ public static ExtendedGroupMembershipData GroupMembershipData(Dictionary dict)
+ {
+ if (dict == null)
+ return null;
+
+ ExtendedGroupMembershipData membership = new ExtendedGroupMembershipData();
+
+ if (dict.ContainsKey("AcceptNotices") && dict["AcceptNotices"] != null)
+ membership.AcceptNotices = bool.Parse(dict["AcceptNotices"].ToString());
+
+ if (dict.ContainsKey("AccessToken") && dict["AccessToken"] != null)
+ membership.AccessToken = dict["AccessToken"].ToString();
+ else
+ membership.AccessToken = string.Empty;
+
+ if (dict.ContainsKey("Active") && dict["Active"] != null)
+ membership.Active = bool.Parse(dict["Active"].ToString());
+
+ if (dict.ContainsKey("ActiveRole") && dict["ActiveRole"] != null)
+ membership.ActiveRole = UUID.Parse(dict["ActiveRole"].ToString());
+
+ if (dict.ContainsKey("AllowPublish") && dict["AllowPublish"] != null)
+ membership.AllowPublish = bool.Parse(dict["AllowPublish"].ToString());
+
+ if (dict.ContainsKey("Charter") && dict["Charter"] != null)
+ membership.Charter = dict["Charter"].ToString();
+ else
+ membership.Charter = string.Empty;
+
+ if (dict.ContainsKey("Contribution") && dict["Contribution"] != null)
+ membership.Contribution = Int32.Parse(dict["Contribution"].ToString());
+
+ if (dict.ContainsKey("FounderID") && dict["FounderID"] != null)
+ membership.FounderID = UUID.Parse(dict["FounderID"].ToString());
+
+ if (dict.ContainsKey("GroupID") && dict["GroupID"] != null)
+ membership.GroupID = UUID.Parse(dict["GroupID"].ToString());
+
+ if (dict.ContainsKey("GroupName") && dict["GroupName"] != null)
+ membership.GroupName = dict["GroupName"].ToString();
+ else
+ membership.GroupName = string.Empty;
+
+ if (dict.ContainsKey("GroupPicture") && dict["GroupPicture"] != null)
+ membership.GroupPicture = UUID.Parse(dict["GroupPicture"].ToString());
+
+ if (dict.ContainsKey("GroupPowers") && dict["GroupPowers"] != null)
+ membership.GroupPowers = UInt64.Parse(dict["GroupPowers"].ToString());
+
+ if (dict.ContainsKey("GroupTitle") && dict["GroupTitle"] != null)
+ membership.GroupTitle = dict["GroupTitle"].ToString();
+ else
+ membership.GroupTitle = string.Empty;
+
+ if (dict.ContainsKey("ListInProfile") && dict["ListInProfile"] != null)
+ membership.ListInProfile = bool.Parse(dict["ListInProfile"].ToString());
+
+ if (dict.ContainsKey("MaturePublish") && dict["MaturePublish"] != null)
+ membership.MaturePublish = bool.Parse(dict["MaturePublish"].ToString());
+
+ if (dict.ContainsKey("MembershipFee") && dict["MembershipFee"] != null)
+ membership.MembershipFee = Int32.Parse(dict["MembershipFee"].ToString());
+
+ if (dict.ContainsKey("OpenEnrollment") && dict["OpenEnrollment"] != null)
+ membership.OpenEnrollment = bool.Parse(dict["OpenEnrollment"].ToString());
+
+ if (dict.ContainsKey("ShowInList") && dict["ShowInList"] != null)
+ membership.ShowInList = bool.Parse(dict["ShowInList"].ToString());
+
+ return membership;
+ }
+
+ public static Dictionary GroupMembersData(ExtendedGroupMembersData member)
+ {
+ Dictionary dict = new Dictionary();
+
+ dict["AcceptNotices"] = member.AcceptNotices.ToString();
+ dict["AccessToken"] = Sanitize(member.AccessToken);
+ dict["AgentID"] = Sanitize(member.AgentID);
+ dict["AgentPowers"] = member.AgentPowers.ToString();
+ dict["Contribution"] = member.Contribution.ToString();
+ dict["IsOwner"] = member.IsOwner.ToString();
+ dict["ListInProfile"] = member.ListInProfile.ToString();
+ dict["OnlineStatus"] = Sanitize(member.OnlineStatus);
+ dict["Title"] = Sanitize(member.Title);
+
+ return dict;
+ }
+
+ public static ExtendedGroupMembersData GroupMembersData(Dictionary dict)
+ {
+ ExtendedGroupMembersData member = new ExtendedGroupMembersData();
+
+ if (dict == null)
+ return member;
+
+ if (dict.ContainsKey("AcceptNotices") && dict["AcceptNotices"] != null)
+ member.AcceptNotices = bool.Parse(dict["AcceptNotices"].ToString());
+
+ if (dict.ContainsKey("AccessToken") && dict["AccessToken"] != null)
+ member.AccessToken = Sanitize(dict["AccessToken"].ToString());
+ else
+ member.AccessToken = string.Empty;
+
+ if (dict.ContainsKey("AgentID") && dict["AgentID"] != null)
+ member.AgentID = Sanitize(dict["AgentID"].ToString());
+ else
+ member.AgentID = UUID.Zero.ToString();
+
+ if (dict.ContainsKey("AgentPowers") && dict["AgentPowers"] != null)
+ member.AgentPowers = UInt64.Parse(dict["AgentPowers"].ToString());
+
+ if (dict.ContainsKey("Contribution") && dict["Contribution"] != null)
+ member.Contribution = Int32.Parse(dict["Contribution"].ToString());
+
+ if (dict.ContainsKey("IsOwner") && dict["IsOwner"] != null)
+ member.IsOwner = bool.Parse(dict["IsOwner"].ToString());
+
+ if (dict.ContainsKey("ListInProfile") && dict["ListInProfile"] != null)
+ member.ListInProfile = bool.Parse(dict["ListInProfile"].ToString());
+
+ if (dict.ContainsKey("OnlineStatus") && dict["OnlineStatus"] != null)
+ member.OnlineStatus = Sanitize(dict["OnlineStatus"].ToString());
+ else
+ member.OnlineStatus = string.Empty;
+
+ if (dict.ContainsKey("Title") && dict["Title"] != null)
+ member.Title = Sanitize(dict["Title"].ToString());
+ else
+ member.Title = string.Empty;
+
+ return member;
+ }
+
+ public static Dictionary GroupRolesData(GroupRolesData role)
+ {
+ Dictionary dict = new Dictionary();
+
+ dict["Description"] = Sanitize(role.Description);
+ dict["Members"] = role.Members.ToString();
+ dict["Name"] = Sanitize(role.Name);
+ dict["Powers"] = role.Powers.ToString();
+ dict["RoleID"] = role.RoleID.ToString();
+ dict["Title"] = Sanitize(role.Title);
+
+ return dict;
+ }
+
+ public static GroupRolesData GroupRolesData(Dictionary dict)
+ {
+ GroupRolesData role = new GroupRolesData();
+
+ if (dict == null)
+ return role;
+
+ if (dict.ContainsKey("Description") && dict["Description"] != null)
+ role.Description = Sanitize(dict["Description"].ToString());
+ else
+ role.Description = string.Empty;
+
+ if (dict.ContainsKey("Members") && dict["Members"] != null)
+ role.Members = Int32.Parse(dict["Members"].ToString());
+
+ if (dict.ContainsKey("Name") && dict["Name"] != null)
+ role.Name = Sanitize(dict["Name"].ToString());
+ else
+ role.Name = string.Empty;
+
+ if (dict.ContainsKey("Powers") && dict["Powers"] != null)
+ role.Powers = UInt64.Parse(dict["Powers"].ToString());
+
+ if (dict.ContainsKey("Title") && dict["Title"] != null)
+ role.Title = Sanitize(dict["Title"].ToString());
+ else
+ role.Title = string.Empty;
+
+ if (dict.ContainsKey("RoleID") && dict["RoleID"] != null)
+ role.RoleID = UUID.Parse(dict["RoleID"].ToString());
+
+ return role;
+ }
+
+ public static Dictionary GroupRoleMembersData(ExtendedGroupRoleMembersData rmember)
+ {
+ Dictionary dict = new Dictionary();
+
+ dict["RoleID"] = rmember.RoleID.ToString();
+ dict["MemberID"] = rmember.MemberID;
+ return dict;
+ }
+
+ public static ExtendedGroupRoleMembersData GroupRoleMembersData(Dictionary dict)
+ {
+ ExtendedGroupRoleMembersData rmember = new ExtendedGroupRoleMembersData();
+
+ if (dict.ContainsKey("RoleID") && dict["RoleID"] != null)
+ rmember.RoleID = new UUID(dict["RoleID"].ToString());
+
+ if (dict.ContainsKey("MemberID") && dict["MemberID"] != null)
+ rmember.MemberID = dict["MemberID"].ToString();
+
+ return rmember;
+ }
+
+ public static Dictionary GroupInviteInfo(GroupInviteInfo invite)
+ {
+ Dictionary dict = new Dictionary();
+
+ dict["InviteID"] = invite.InviteID.ToString();
+ dict["GroupID"] = invite.GroupID.ToString();
+ dict["RoleID"] = invite.RoleID.ToString();
+ dict["AgentID"] = invite.AgentID;
+
+ return dict;
+ }
+
+ public static GroupInviteInfo GroupInviteInfo(Dictionary dict)
+ {
+ if (dict == null)
+ return null;
+
+ GroupInviteInfo invite = new GroupInviteInfo();
+
+ invite.InviteID = new UUID(dict["InviteID"].ToString());
+ invite.GroupID = new UUID(dict["GroupID"].ToString());
+ invite.RoleID = new UUID(dict["RoleID"].ToString());
+ invite.AgentID = Sanitize(dict["AgentID"].ToString());
+
+ return invite;
+ }
+
+ public static Dictionary GroupNoticeData(ExtendedGroupNoticeData notice)
+ {
+ Dictionary dict = new Dictionary();
+
+ dict["NoticeID"] = notice.NoticeID.ToString();
+ dict["Timestamp"] = notice.Timestamp.ToString();
+ dict["FromName"] = Sanitize(notice.FromName);
+ dict["Subject"] = Sanitize(notice.Subject);
+ dict["HasAttachment"] = notice.HasAttachment.ToString();
+ dict["AttachmentItemID"] = notice.AttachmentItemID.ToString();
+ dict["AttachmentName"] = Sanitize(notice.AttachmentName);
+ dict["AttachmentType"] = notice.AttachmentType.ToString();
+ dict["AttachmentOwnerID"] = Sanitize(notice.AttachmentOwnerID);
+
+ return dict;
+ }
+
+ public static ExtendedGroupNoticeData GroupNoticeData(Dictionary dict)
+ {
+ ExtendedGroupNoticeData notice = new ExtendedGroupNoticeData();
+
+ if (dict == null)
+ return notice;
+
+ notice.NoticeID = new UUID(dict["NoticeID"].ToString());
+ notice.Timestamp = UInt32.Parse(dict["Timestamp"].ToString());
+ notice.FromName = Sanitize(dict["FromName"].ToString());
+ notice.Subject = Sanitize(dict["Subject"].ToString());
+ notice.HasAttachment = bool.Parse(dict["HasAttachment"].ToString());
+ notice.AttachmentItemID = new UUID(dict["AttachmentItemID"].ToString());
+ notice.AttachmentName = dict["AttachmentName"].ToString();
+ notice.AttachmentType = byte.Parse(dict["AttachmentType"].ToString());
+ notice.AttachmentOwnerID = dict["AttachmentOwnerID"].ToString();
+
+ return notice;
+ }
+
+ public static Dictionary GroupNoticeInfo(GroupNoticeInfo notice)
+ {
+ Dictionary dict = GroupNoticeData(notice.noticeData);
+
+ dict["GroupID"] = notice.GroupID.ToString();
+ dict["Message"] = Sanitize(notice.Message);
+
+ return dict;
+ }
+
+ public static GroupNoticeInfo GroupNoticeInfo(Dictionary dict)
+ {
+ GroupNoticeInfo notice = new GroupNoticeInfo();
+
+ notice.noticeData = GroupNoticeData(dict);
+ notice.GroupID = new UUID(dict["GroupID"].ToString());
+ notice.Message = Sanitize(dict["Message"].ToString());
+
+ return notice;
+ }
+
+ public static Dictionary DirGroupsReplyData(DirGroupsReplyData g)
+ {
+ Dictionary dict = new Dictionary();
+
+ dict["GroupID"] = g.groupID;
+ dict["Name"] = g.groupName;
+ dict["NMembers"] = g.members;
+ dict["SearchOrder"] = g.searchOrder;
+
+ return dict;
+ }
+
+ public static DirGroupsReplyData DirGroupsReplyData(Dictionary dict)
+ {
+ DirGroupsReplyData g;
+
+ g.groupID = new UUID(dict["GroupID"].ToString());
+ g.groupName = dict["Name"].ToString();
+ Int32.TryParse(dict["NMembers"].ToString(), out g.members);
+ float.TryParse(dict["SearchOrder"].ToString(), out g.searchOrder);
+
+ return g;
+ }
+ }
+
+}
diff --git a/OpenSim/Addons/Groups/GroupsMessagingModule.cs b/OpenSim/Addons/Groups/GroupsMessagingModule.cs
new file mode 100644
index 0000000000..e95db4120d
--- /dev/null
+++ b/OpenSim/Addons/Groups/GroupsMessagingModule.cs
@@ -0,0 +1,848 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSimulator Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using log4net;
+using Mono.Addins;
+using Nini.Config;
+using OpenMetaverse;
+using OpenMetaverse.StructuredData;
+using OpenSim.Framework;
+using OpenSim.Region.Framework.Interfaces;
+using OpenSim.Region.Framework.Scenes;
+using OpenSim.Services.Interfaces;
+using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo;
+using GridRegion = OpenSim.Services.Interfaces.GridRegion;
+
+namespace OpenSim.Groups
+{
+ [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GroupsMessagingModule")]
+ public class GroupsMessagingModule : ISharedRegionModule, IGroupsMessagingModule
+ {
+ private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+ private List m_sceneList = new List();
+ private IPresenceService m_presenceService;
+
+ private IMessageTransferModule m_msgTransferModule = null;
+ private IUserManagement m_UserManagement = null;
+ private IGroupsServicesConnector m_groupData = null;
+
+ // Config Options
+ private bool m_groupMessagingEnabled;
+ private bool m_debugEnabled;
+
+ ///
+ /// If enabled, module only tries to send group IMs to online users by querying cached presence information.
+ ///
+ private bool m_messageOnlineAgentsOnly;
+
+ ///
+ /// Cache for online users.
+ ///
+ ///
+ /// Group ID is key, presence information for online members is value.
+ /// Will only be non-null if m_messageOnlineAgentsOnly = true
+ /// We cache here so that group messages don't constantly have to re-request the online user list to avoid
+ /// attempted expensive sending of messages to offline users.
+ /// The tradeoff is that a user that comes online will not receive messages consistently from all other users
+ /// until caches have updated.
+ /// Therefore, we set the cache expiry to just 20 seconds.
+ ///
+ private ExpiringCache m_usersOnlineCache;
+
+ private int m_usersOnlineCacheExpirySeconds = 20;
+
+ private Dictionary> m_groupsAgentsDroppedFromChatSession = new Dictionary>();
+ private Dictionary> m_groupsAgentsInvitedToChatSession = new Dictionary>();
+
+ #region Region Module interfaceBase Members
+
+ public void Initialise(IConfigSource config)
+ {
+ IConfig groupsConfig = config.Configs["Groups"];
+
+ if (groupsConfig == null)
+ // Do not run this module by default.
+ return;
+
+ // if groups aren't enabled, we're not needed.
+ // if we're not specified as the connector to use, then we're not wanted
+ if ((groupsConfig.GetBoolean("Enabled", false) == false)
+ || (groupsConfig.GetString("MessagingModule", "") != Name))
+ {
+ m_groupMessagingEnabled = false;
+ return;
+ }
+
+ m_groupMessagingEnabled = groupsConfig.GetBoolean("MessagingEnabled", true);
+
+ if (!m_groupMessagingEnabled)
+ return;
+
+ m_messageOnlineAgentsOnly = groupsConfig.GetBoolean("MessageOnlineUsersOnly", false);
+
+ if (m_messageOnlineAgentsOnly)
+ {
+ m_usersOnlineCache = new ExpiringCache();
+ }
+ else
+ {
+ m_log.Error("[Groups.Messaging]: GroupsMessagingModule V2 requires MessageOnlineUsersOnly = true");
+ m_groupMessagingEnabled = false;
+ return;
+ }
+
+ m_debugEnabled = groupsConfig.GetBoolean("MessagingDebugEnabled", m_debugEnabled);
+
+ m_log.InfoFormat(
+ "[Groups.Messaging]: GroupsMessagingModule enabled with MessageOnlineOnly = {0}, DebugEnabled = {1}",
+ m_messageOnlineAgentsOnly, m_debugEnabled);
+ }
+
+ public void AddRegion(Scene scene)
+ {
+ if (!m_groupMessagingEnabled)
+ return;
+
+ scene.RegisterModuleInterface(this);
+ m_sceneList.Add(scene);
+
+ scene.EventManager.OnNewClient += OnNewClient;
+ scene.EventManager.OnMakeRootAgent += OnMakeRootAgent;
+ scene.EventManager.OnMakeChildAgent += OnMakeChildAgent;
+ scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage;
+ scene.EventManager.OnClientLogin += OnClientLogin;
+
+ scene.AddCommand(
+ "Debug",
+ this,
+ "debug groups messaging verbose",
+ "debug groups messaging verbose ",
+ "This setting turns on very verbose groups messaging debugging",
+ HandleDebugGroupsMessagingVerbose);
+ }
+
+ public void RegionLoaded(Scene scene)
+ {
+ if (!m_groupMessagingEnabled)
+ return;
+
+ if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
+
+ m_groupData = scene.RequestModuleInterface();
+
+ // No groups module, no groups messaging
+ if (m_groupData == null)
+ {
+ m_log.Error("[Groups.Messaging]: Could not get IGroupsServicesConnector, GroupsMessagingModule is now disabled.");
+ RemoveRegion(scene);
+ return;
+ }
+
+ m_msgTransferModule = scene.RequestModuleInterface();
+
+ // No message transfer module, no groups messaging
+ if (m_msgTransferModule == null)
+ {
+ m_log.Error("[Groups.Messaging]: Could not get MessageTransferModule");
+ RemoveRegion(scene);
+ return;
+ }
+
+ m_UserManagement = scene.RequestModuleInterface();
+
+ // No groups module, no groups messaging
+ if (m_UserManagement == null)
+ {
+ m_log.Error("[Groups.Messaging]: Could not get IUserManagement, GroupsMessagingModule is now disabled.");
+ RemoveRegion(scene);
+ return;
+ }
+
+ if (m_presenceService == null)
+ m_presenceService = scene.PresenceService;
+ }
+
+ public void RemoveRegion(Scene scene)
+ {
+ if (!m_groupMessagingEnabled)
+ return;
+
+ if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
+
+ m_sceneList.Remove(scene);
+ scene.EventManager.OnNewClient -= OnNewClient;
+ scene.EventManager.OnIncomingInstantMessage -= OnGridInstantMessage;
+ scene.EventManager.OnClientLogin -= OnClientLogin;
+ scene.UnregisterModuleInterface(this);
+ }
+
+ public void Close()
+ {
+ if (!m_groupMessagingEnabled)
+ return;
+
+ if (m_debugEnabled) m_log.Debug("[Groups.Messaging]: Shutting down GroupsMessagingModule module.");
+
+ m_sceneList.Clear();
+
+ m_groupData = null;
+ m_msgTransferModule = null;
+ }
+
+ public Type ReplaceableInterface
+ {
+ get { return null; }
+ }
+
+ public string Name
+ {
+ get { return "Groups Messaging Module V2"; }
+ }
+
+ public void PostInitialise()
+ {
+ // NoOp
+ }
+
+ #endregion
+
+ private void HandleDebugGroupsMessagingVerbose(object modules, string[] args)
+ {
+ if (args.Length < 5)
+ {
+ MainConsole.Instance.Output("Usage: debug groups messaging verbose ");
+ return;
+ }
+
+ bool verbose = false;
+ if (!bool.TryParse(args[4], out verbose))
+ {
+ MainConsole.Instance.Output("Usage: debug groups messaging verbose ");
+ return;
+ }
+
+ m_debugEnabled = verbose;
+
+ MainConsole.Instance.OutputFormat("{0} verbose logging set to {1}", Name, m_debugEnabled);
+ }
+
+ ///
+ /// Not really needed, but does confirm that the group exists.
+ ///
+ public bool StartGroupChatSession(UUID agentID, UUID groupID)
+ {
+ if (m_debugEnabled)
+ m_log.DebugFormat("[Groups.Messaging]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
+
+ GroupRecord groupInfo = m_groupData.GetGroupRecord(agentID.ToString(), groupID, null);
+
+ if (groupInfo != null)
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ public void SendMessageToGroup(GridInstantMessage im, UUID groupID)
+ {
+ SendMessageToGroup(im, groupID, UUID.Zero, null);
+ }
+
+ public void SendMessageToGroup(
+ GridInstantMessage im, UUID groupID, UUID sendingAgentForGroupCalls, Func 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 groupMembers = m_groupData.GetGroupMembers(UUID.Zero.ToString(), groupID);
+
+ int groupMembersCount = groupMembers.Count;
+ PresenceInfo[] onlineAgents = null;
+
+ // In V2 we always only send to online members.
+ // Sending to offline members is not an option.
+ string[] t1 = groupMembers.ConvertAll(gmd => gmd.AgentID.ToString()).ToArray();
+
+ // We cache in order not to overwhelm the presence service on large grids with many groups. This does
+ // mean that members coming online will not see all group members until after m_usersOnlineCacheExpirySeconds has elapsed.
+ // (assuming this is the same across all grid simulators).
+ if (!m_usersOnlineCache.TryGetValue(groupID, out onlineAgents))
+ {
+ onlineAgents = m_presenceService.GetAgents(t1);
+ m_usersOnlineCache.Add(groupID, onlineAgents, m_usersOnlineCacheExpirySeconds);
+ }
+
+ HashSet onlineAgentsUuidSet = new HashSet();
+ Array.ForEach(onlineAgents, pi => onlineAgentsUuidSet.Add(pi.UserID));
+
+ groupMembers = groupMembers.Where(gmd => onlineAgentsUuidSet.Contains(gmd.AgentID.ToString())).ToList();
+
+// if (m_debugEnabled)
+// m_log.DebugFormat(
+// "[Groups.Messaging]: SendMessageToGroup called for group {0} with {1} visible members, {2} online",
+// groupID, groupMembersCount, groupMembers.Count());
+
+ im.imSessionID = groupID.Guid;
+ im.fromGroup = true;
+ IClientAPI thisClient = GetActiveClient(fromAgentID);
+ if (thisClient != null)
+ {
+ im.RegionID = thisClient.Scene.RegionInfo.RegionID.Guid;
+ }
+
+ if ((im.binaryBucket == null) || (im.binaryBucket.Length == 0) || ((im.binaryBucket.Length == 1 && im.binaryBucket[0] == 0)))
+ {
+ ExtendedGroupRecord groupInfo = m_groupData.GetGroupRecord(UUID.Zero.ToString(), groupID, null);
+ if (groupInfo != null)
+ im.binaryBucket = Util.StringToBytes256(groupInfo.GroupName);
+ }
+
+ // Send to self first of all
+ im.toAgentID = im.fromAgentID;
+ im.fromGroup = true;
+ ProcessMessageFromGroupSession(im);
+
+ List regions = new List();
+ List clientsAlreadySent = new List();
+
+ // Then send to everybody else
+ foreach (GroupMembersData member in groupMembers)
+ {
+ if (member.AgentID.Guid == im.fromAgentID)
+ continue;
+
+ if (clientsAlreadySent.Contains(member.AgentID))
+ continue;
+
+ clientsAlreadySent.Add(member.AgentID);
+
+ if (sendCondition != null)
+ {
+ if (!sendCondition(member))
+ {
+ if (m_debugEnabled)
+ m_log.DebugFormat(
+ "[Groups.Messaging]: Not sending to {0} as they do not fulfill send condition",
+ member.AgentID);
+
+ continue;
+ }
+ }
+ else if (hasAgentDroppedGroupChatSession(member.AgentID.ToString(), groupID))
+ {
+ // Don't deliver messages to people who have dropped this session
+ if (m_debugEnabled)
+ m_log.DebugFormat("[Groups.Messaging]: {0} has dropped session, not delivering to them", member.AgentID);
+
+ continue;
+ }
+
+ im.toAgentID = member.AgentID.Guid;
+
+ IClientAPI client = GetActiveClient(member.AgentID);
+ if (client == null)
+ {
+ // If they're not local, forward across the grid
+ // BUT do it only once per region, please! Sim would be even better!
+ if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Delivering to {0} via Grid", member.AgentID);
+
+ bool reallySend = true;
+ if (onlineAgents != null)
+ {
+ PresenceInfo presence = onlineAgents.First(p => p.UserID == member.AgentID.ToString());
+ if (regions.Contains(presence.RegionID))
+ reallySend = false;
+ else
+ regions.Add(presence.RegionID);
+ }
+
+ if (reallySend)
+ {
+ // We have to create a new IM structure because the transfer module
+ // uses async send
+ GridInstantMessage msg = new GridInstantMessage(im, true);
+ m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { });
+ }
+ }
+ else
+ {
+ // Deliver locally, directly
+ if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Passing to ProcessMessageFromGroupSession to deliver to {0} locally", client.Name);
+
+ ProcessMessageFromGroupSession(im);
+ }
+
+ }
+
+ if (m_debugEnabled)
+ m_log.DebugFormat(
+ "[Groups.Messaging]: SendMessageToGroup for group {0} with {1} visible members, {2} online took {3}ms",
+ groupID, groupMembersCount, groupMembers.Count(), Environment.TickCount - requestStartTick);
+ }
+
+ #region SimGridEventHandlers
+
+ void OnClientLogin(IClientAPI client)
+ {
+ if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: OnInstantMessage registered for {0}", client.Name);
+ }
+
+ private void OnNewClient(IClientAPI client)
+ {
+ if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: OnInstantMessage registered for {0}", client.Name);
+
+ ResetAgentGroupChatSessions(client.AgentId.ToString());
+ }
+
+ void OnMakeRootAgent(ScenePresence sp)
+ {
+ sp.ControllingClient.OnInstantMessage += OnInstantMessage;
+ }
+
+ void OnMakeChildAgent(ScenePresence sp)
+ {
+ sp.ControllingClient.OnInstantMessage -= OnInstantMessage;
+ }
+
+
+ private void OnGridInstantMessage(GridInstantMessage msg)
+ {
+ // The instant message module will only deliver messages of dialog types:
+ // MessageFromAgent, StartTyping, StopTyping, MessageFromObject
+ //
+ // Any other message type will not be delivered to a client by the
+ // Instant Message Module
+
+ UUID regionID = new UUID(msg.RegionID);
+ if (m_debugEnabled)
+ {
+ m_log.DebugFormat("[Groups.Messaging]: {0} called, IM from region {1}",
+ System.Reflection.MethodBase.GetCurrentMethod().Name, regionID);
+
+ DebugGridInstantMessage(msg);
+ }
+
+ // Incoming message from a group
+ if ((msg.fromGroup == true) && (msg.dialog == (byte)InstantMessageDialog.SessionSend))
+ {
+ // We have to redistribute the message across all members of the group who are here
+ // on this sim
+
+ UUID GroupID = new UUID(msg.imSessionID);
+
+ Scene aScene = m_sceneList[0];
+ GridRegion regionOfOrigin = aScene.GridService.GetRegionByUUID(aScene.RegionInfo.ScopeID, regionID);
+
+ List groupMembers = m_groupData.GetGroupMembers(UUID.Zero.ToString(), GroupID);
+
+ //if (m_debugEnabled)
+ // foreach (GroupMembersData m in groupMembers)
+ // m_log.DebugFormat("[Groups.Messaging]: member {0}", m.AgentID);
+
+ foreach (Scene s in m_sceneList)
+ {
+ s.ForEachScenePresence(sp =>
+ {
+ // If we got this via grid messaging, it's because the caller thinks
+ // that the root agent is here. We should only send the IM to root agents.
+ if (sp.IsChildAgent)
+ return;
+
+ GroupMembersData m = groupMembers.Find(gmd =>
+ {
+ return gmd.AgentID == sp.UUID;
+ });
+ if (m.AgentID == UUID.Zero)
+ {
+ if (m_debugEnabled)
+ m_log.DebugFormat("[Groups.Messaging]: skipping agent {0} because he is not a member of the group", sp.UUID);
+ return;
+ }
+
+ // Check if the user has an agent in the region where
+ // the IM came from, and if so, skip it, because the IM
+ // was already sent via that agent
+ if (regionOfOrigin != null)
+ {
+ AgentCircuitData aCircuit = s.AuthenticateHandler.GetAgentCircuitData(sp.UUID);
+ if (aCircuit != null)
+ {
+ if (aCircuit.ChildrenCapSeeds.Keys.Contains(regionOfOrigin.RegionHandle))
+ {
+ if (m_debugEnabled)
+ m_log.DebugFormat("[Groups.Messaging]: skipping agent {0} because he has an agent in region of origin", sp.UUID);
+ return;
+ }
+ else
+ {
+ if (m_debugEnabled)
+ m_log.DebugFormat("[Groups.Messaging]: not skipping agent {0}", sp.UUID);
+ }
+ }
+ }
+
+ UUID AgentID = sp.UUID;
+ msg.toAgentID = AgentID.Guid;
+
+ if (!hasAgentDroppedGroupChatSession(AgentID.ToString(), GroupID))
+ {
+ if (!hasAgentBeenInvitedToGroupChatSession(AgentID.ToString(), GroupID))
+ AddAgentToSession(AgentID, GroupID, msg);
+ else
+ {
+ if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Passing to ProcessMessageFromGroupSession to deliver to {0} locally", sp.Name);
+
+ ProcessMessageFromGroupSession(msg);
+ }
+ }
+ });
+
+ }
+ }
+ }
+
+ private void ProcessMessageFromGroupSession(GridInstantMessage msg)
+ {
+ if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Session message from {0} going to agent {1}", msg.fromAgentName, msg.toAgentID);
+
+ UUID AgentID = new UUID(msg.fromAgentID);
+ UUID GroupID = new UUID(msg.imSessionID);
+ UUID toAgentID = new UUID(msg.toAgentID);
+
+ switch (msg.dialog)
+ {
+ case (byte)InstantMessageDialog.SessionAdd:
+ AgentInvitedToGroupChatSession(AgentID.ToString(), GroupID);
+ break;
+
+ case (byte)InstantMessageDialog.SessionDrop:
+ AgentDroppedFromGroupChatSession(AgentID.ToString(), GroupID);
+ break;
+
+ case (byte)InstantMessageDialog.SessionSend:
+ // User hasn't dropped, so they're in the session,
+ // maybe we should deliver it.
+ IClientAPI client = GetActiveClient(new UUID(msg.toAgentID));
+ if (client != null)
+ {
+ // Deliver locally, directly
+ if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Delivering to {0} locally", client.Name);
+
+ if (!hasAgentDroppedGroupChatSession(toAgentID.ToString(), GroupID))
+ {
+ if (!hasAgentBeenInvitedToGroupChatSession(toAgentID.ToString(), GroupID))
+ // This actually sends the message too, so no need to resend it
+ // with client.SendInstantMessage
+ AddAgentToSession(toAgentID, GroupID, msg);
+ else
+ client.SendInstantMessage(msg);
+ }
+ }
+ else
+ {
+ m_log.WarnFormat("[Groups.Messaging]: Received a message over the grid for a client that isn't here: {0}", msg.toAgentID);
+ }
+ break;
+
+ default:
+ m_log.WarnFormat("[Groups.Messaging]: I don't know how to proccess a {0} message.", ((InstantMessageDialog)msg.dialog).ToString());
+ break;
+ }
+ }
+
+ private void AddAgentToSession(UUID AgentID, UUID GroupID, GridInstantMessage msg)
+ {
+ // Agent not in session and hasn't dropped from session
+ // Add them to the session for now, and Invite them
+ AgentInvitedToGroupChatSession(AgentID.ToString(), GroupID);
+
+ IClientAPI activeClient = GetActiveClient(AgentID);
+ if (activeClient != null)
+ {
+ GroupRecord groupInfo = m_groupData.GetGroupRecord(UUID.Zero.ToString(), GroupID, null);
+ if (groupInfo != null)
+ {
+ if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Sending chatterbox invite instant message");
+
+ // 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();
+ 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)
+ );
+
+ eq.ChatterBoxSessionAgentListUpdates(
+ new UUID(GroupID)
+ , AgentID
+ , new UUID(msg.toAgentID)
+ , false //canVoiceChat
+ , false //isModerator
+ , false //text mute
+ );
+ }
+ }
+ }
+
+ #endregion
+
+
+ #region ClientEvents
+ private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im)
+ {
+ if (m_debugEnabled)
+ {
+ m_log.DebugFormat("[Groups.Messaging]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
+
+ DebugGridInstantMessage(im);
+ }
+
+ // Start group IM session
+ if ((im.dialog == (byte)InstantMessageDialog.SessionGroupStart))
+ {
+ if (m_debugEnabled) m_log.InfoFormat("[Groups.Messaging]: imSessionID({0}) toAgentID({1})", im.imSessionID, im.toAgentID);
+
+ UUID GroupID = new UUID(im.imSessionID);
+ UUID AgentID = new UUID(im.fromAgentID);
+
+ GroupRecord groupInfo = m_groupData.GetGroupRecord(UUID.Zero.ToString(), GroupID, null);
+
+ if (groupInfo != null)
+ {
+ AgentInvitedToGroupChatSession(AgentID.ToString(), GroupID);
+
+ ChatterBoxSessionStartReplyViaCaps(remoteClient, groupInfo.GroupName, GroupID);
+
+ IEventQueue queue = remoteClient.Scene.RequestModuleInterface();
+ queue.ChatterBoxSessionAgentListUpdates(
+ GroupID
+ , AgentID
+ , new UUID(im.toAgentID)
+ , false //canVoiceChat
+ , false //isModerator
+ , false //text mute
+ );
+ }
+ }
+
+ // Send a message from locally connected client to a group
+ if ((im.dialog == (byte)InstantMessageDialog.SessionSend))
+ {
+ UUID GroupID = new UUID(im.imSessionID);
+ UUID AgentID = new UUID(im.fromAgentID);
+
+ if (m_debugEnabled)
+ m_log.DebugFormat("[Groups.Messaging]: Send message to session for group {0} with session ID {1}", GroupID, im.imSessionID.ToString());
+
+ //If this agent is sending a message, then they want to be in the session
+ AgentInvitedToGroupChatSession(AgentID.ToString(), GroupID);
+
+ SendMessageToGroup(im, GroupID);
+ }
+ }
+
+ #endregion
+
+ void ChatterBoxSessionStartReplyViaCaps(IClientAPI remoteClient, string groupName, UUID groupID)
+ {
+ if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
+
+ OSDMap moderatedMap = new OSDMap(4);
+ moderatedMap.Add("voice", OSD.FromBoolean(false));
+
+ OSDMap sessionMap = new OSDMap(4);
+ sessionMap.Add("moderated_mode", moderatedMap);
+ sessionMap.Add("session_name", OSD.FromString(groupName));
+ sessionMap.Add("type", OSD.FromInteger(0));
+ sessionMap.Add("voice_enabled", OSD.FromBoolean(false));
+
+ OSDMap bodyMap = new OSDMap(4);
+ bodyMap.Add("session_id", OSD.FromUUID(groupID));
+ bodyMap.Add("temp_session_id", OSD.FromUUID(groupID));
+ bodyMap.Add("success", OSD.FromBoolean(true));
+ bodyMap.Add("session_info", sessionMap);
+
+ IEventQueue queue = remoteClient.Scene.RequestModuleInterface();
+
+ if (queue != null)
+ {
+ queue.Enqueue(queue.BuildEvent("ChatterBoxSessionStartReply", bodyMap), remoteClient.AgentId);
+ }
+ }
+
+ private void DebugGridInstantMessage(GridInstantMessage im)
+ {
+ // Don't log any normal IMs (privacy!)
+ if (m_debugEnabled && im.dialog != (byte)InstantMessageDialog.MessageFromAgent)
+ {
+ m_log.WarnFormat("[Groups.Messaging]: IM: fromGroup({0})", im.fromGroup ? "True" : "False");
+ m_log.WarnFormat("[Groups.Messaging]: IM: Dialog({0})", ((InstantMessageDialog)im.dialog).ToString());
+ m_log.WarnFormat("[Groups.Messaging]: IM: fromAgentID({0})", im.fromAgentID.ToString());
+ m_log.WarnFormat("[Groups.Messaging]: IM: fromAgentName({0})", im.fromAgentName.ToString());
+ m_log.WarnFormat("[Groups.Messaging]: IM: imSessionID({0})", im.imSessionID.ToString());
+ m_log.WarnFormat("[Groups.Messaging]: IM: message({0})", im.message.ToString());
+ m_log.WarnFormat("[Groups.Messaging]: IM: offline({0})", im.offline.ToString());
+ m_log.WarnFormat("[Groups.Messaging]: IM: toAgentID({0})", im.toAgentID.ToString());
+ m_log.WarnFormat("[Groups.Messaging]: IM: binaryBucket({0})", OpenMetaverse.Utils.BytesToHexString(im.binaryBucket, "BinaryBucket"));
+ }
+ }
+
+ #region Client Tools
+
+ ///
+ /// Try to find an active IClientAPI reference for agentID giving preference to root connections
+ ///
+ private IClientAPI GetActiveClient(UUID agentID)
+ {
+ if (m_debugEnabled) m_log.WarnFormat("[Groups.Messaging]: Looking for local client {0}", agentID);
+
+ IClientAPI child = null;
+
+ // Try root avatar first
+ foreach (Scene scene in m_sceneList)
+ {
+ ScenePresence sp = scene.GetScenePresence(agentID);
+ if (sp != null)
+ {
+ if (!sp.IsChildAgent)
+ {
+ if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Found root agent for client : {0}", sp.ControllingClient.Name);
+ return sp.ControllingClient;
+ }
+ else
+ {
+ if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Found child agent for client : {0}", sp.ControllingClient.Name);
+ child = sp.ControllingClient;
+ }
+ }
+ }
+
+ // If we didn't find a root, then just return whichever child we found, or null if none
+ if (child == null)
+ {
+ if (m_debugEnabled) m_log.WarnFormat("[Groups.Messaging]: Could not find local client for agent : {0}", agentID);
+ }
+ else
+ {
+ if (m_debugEnabled) m_log.WarnFormat("[Groups.Messaging]: Returning child agent for client : {0}", child.Name);
+ }
+ return child;
+ }
+
+ #endregion
+
+ #region GroupSessionTracking
+
+ public void ResetAgentGroupChatSessions(string agentID)
+ {
+ foreach (List agentList in m_groupsAgentsDroppedFromChatSession.Values)
+ agentList.Remove(agentID);
+
+ foreach (List agentList in m_groupsAgentsInvitedToChatSession.Values)
+ agentList.Remove(agentID);
+ }
+
+ public bool hasAgentBeenInvitedToGroupChatSession(string agentID, UUID groupID)
+ {
+ // If we're tracking this group, and we can find them in the tracking, then they've been invited
+ return m_groupsAgentsInvitedToChatSession.ContainsKey(groupID)
+ && m_groupsAgentsInvitedToChatSession[groupID].Contains(agentID);
+ }
+
+ public bool hasAgentDroppedGroupChatSession(string agentID, UUID groupID)
+ {
+ // If we're tracking drops for this group,
+ // and we find them, well... then they've dropped
+ return m_groupsAgentsDroppedFromChatSession.ContainsKey(groupID)
+ && m_groupsAgentsDroppedFromChatSession[groupID].Contains(agentID);
+ }
+
+ public void AgentDroppedFromGroupChatSession(string agentID, UUID groupID)
+ {
+ if (m_groupsAgentsDroppedFromChatSession.ContainsKey(groupID))
+ {
+ // If not in dropped list, add
+ if (!m_groupsAgentsDroppedFromChatSession[groupID].Contains(agentID))
+ {
+ m_groupsAgentsDroppedFromChatSession[groupID].Add(agentID);
+ }
+ }
+ }
+
+ public void AgentInvitedToGroupChatSession(string agentID, UUID groupID)
+ {
+ // Add Session Status if it doesn't exist for this session
+ CreateGroupChatSessionTracking(groupID);
+
+ // If nessesary, remove from dropped list
+ if (m_groupsAgentsDroppedFromChatSession[groupID].Contains(agentID))
+ {
+ m_groupsAgentsDroppedFromChatSession[groupID].Remove(agentID);
+ }
+
+ // Add to invited
+ if (!m_groupsAgentsInvitedToChatSession[groupID].Contains(agentID))
+ m_groupsAgentsInvitedToChatSession[groupID].Add(agentID);
+ }
+
+ private void CreateGroupChatSessionTracking(UUID groupID)
+ {
+ if (!m_groupsAgentsDroppedFromChatSession.ContainsKey(groupID))
+ {
+ m_groupsAgentsDroppedFromChatSession.Add(groupID, new List());
+ m_groupsAgentsInvitedToChatSession.Add(groupID, new List());
+ }
+
+ }
+ #endregion
+
+ }
+}
diff --git a/OpenSim/Addons/Groups/GroupsModule.cs b/OpenSim/Addons/Groups/GroupsModule.cs
new file mode 100644
index 0000000000..d121d1a8ce
--- /dev/null
+++ b/OpenSim/Addons/Groups/GroupsModule.cs
@@ -0,0 +1,1467 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSimulator Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Timers;
+using log4net;
+using Mono.Addins;
+using Nini.Config;
+using OpenMetaverse;
+using OpenMetaverse.StructuredData;
+using OpenSim.Framework;
+using OpenSim.Region.Framework.Interfaces;
+using OpenSim.Region.Framework.Scenes;
+using OpenSim.Services.Interfaces;
+using DirFindFlags = OpenMetaverse.DirectoryManager.DirFindFlags;
+
+namespace OpenSim.Groups
+{
+ [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GroupsModule")]
+ public class GroupsModule : ISharedRegionModule, IGroupsModule
+ {
+ private static readonly ILog m_log =
+ LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+ private List m_sceneList = new List();
+
+ private IMessageTransferModule m_msgTransferModule = null;
+
+ private IGroupsServicesConnector m_groupData = null;
+ private IUserManagement m_UserManagement;
+
+ // Configuration settings
+ private bool m_groupsEnabled = false;
+ private bool m_groupNoticesEnabled = true;
+ private bool m_debugEnabled = false;
+ private int m_levelGroupCreate = 0;
+
+ #region Region Module interfaceBase Members
+
+ public void Initialise(IConfigSource config)
+ {
+ IConfig groupsConfig = config.Configs["Groups"];
+
+ if (groupsConfig == null)
+ {
+ // Do not run this module by default.
+ return;
+ }
+ else
+ {
+ m_groupsEnabled = groupsConfig.GetBoolean("Enabled", false);
+ if (!m_groupsEnabled)
+ {
+ return;
+ }
+
+ if (groupsConfig.GetString("Module", "Default") != Name)
+ {
+ m_groupsEnabled = false;
+
+ return;
+ }
+
+ m_log.InfoFormat("[Groups]: Initializing {0}", this.Name);
+
+ m_groupNoticesEnabled = groupsConfig.GetBoolean("NoticesEnabled", true);
+ m_debugEnabled = groupsConfig.GetBoolean("DebugEnabled", false);
+ m_levelGroupCreate = groupsConfig.GetInt("LevelGroupCreate", 0);
+ }
+ }
+
+ public void AddRegion(Scene scene)
+ {
+ if (m_groupsEnabled)
+ {
+ scene.RegisterModuleInterface(this);
+ scene.AddCommand(
+ "Debug",
+ this,
+ "debug groups verbose",
+ "debug groups verbose ",
+ "This setting turns on very verbose groups debugging",
+ HandleDebugGroupsVerbose);
+ }
+ }
+
+ private void HandleDebugGroupsVerbose(object modules, string[] args)
+ {
+ if (args.Length < 4)
+ {
+ MainConsole.Instance.Output("Usage: debug groups verbose ");
+ return;
+ }
+
+ bool verbose = false;
+ if (!bool.TryParse(args[3], out verbose))
+ {
+ MainConsole.Instance.Output("Usage: debug groups verbose ");
+ return;
+ }
+
+ m_debugEnabled = verbose;
+
+ MainConsole.Instance.OutputFormat("{0} verbose logging set to {1}", Name, m_debugEnabled);
+ }
+
+ public void RegionLoaded(Scene scene)
+ {
+ if (!m_groupsEnabled)
+ return;
+
+ if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
+
+ scene.EventManager.OnNewClient += OnNewClient;
+ scene.EventManager.OnMakeRootAgent += OnMakeRoot;
+ scene.EventManager.OnMakeChildAgent += OnMakeChild;
+ scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage;
+ // The InstantMessageModule itself doesn't do this,
+ // so lets see if things explode if we don't do it
+ // scene.EventManager.OnClientClosed += OnClientClosed;
+
+ if (m_groupData == null)
+ {
+ m_groupData = scene.RequestModuleInterface();
+
+ // No Groups Service Connector, then nothing works...
+ if (m_groupData == null)
+ {
+ m_groupsEnabled = false;
+ m_log.Error("[Groups]: Could not get IGroupsServicesConnector");
+ RemoveRegion(scene);
+ return;
+ }
+ }
+
+ if (m_msgTransferModule == null)
+ {
+ m_msgTransferModule = scene.RequestModuleInterface();
+
+ // No message transfer module, no notices, group invites, rejects, ejects, etc
+ if (m_msgTransferModule == null)
+ {
+ m_log.Warn("[Groups]: Could not get MessageTransferModule");
+ }
+ }
+
+ if (m_UserManagement == null)
+ {
+ m_UserManagement = scene.RequestModuleInterface();
+ if (m_UserManagement == null)
+ m_log.Warn("[Groups]: Could not get UserManagementModule");
+ }
+
+ lock (m_sceneList)
+ {
+ m_sceneList.Add(scene);
+ }
+
+
+ }
+
+ public void RemoveRegion(Scene scene)
+ {
+ if (!m_groupsEnabled)
+ return;
+
+ if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
+
+ scene.EventManager.OnNewClient -= OnNewClient;
+ scene.EventManager.OnMakeRootAgent -= OnMakeRoot;
+ scene.EventManager.OnMakeChildAgent -= OnMakeChild;
+ scene.EventManager.OnIncomingInstantMessage -= OnGridInstantMessage;
+
+ lock (m_sceneList)
+ {
+ m_sceneList.Remove(scene);
+ }
+ }
+
+ public void Close()
+ {
+ if (!m_groupsEnabled)
+ return;
+
+ if (m_debugEnabled) m_log.Debug("[Groups]: Shutting down Groups module.");
+ }
+
+ public Type ReplaceableInterface
+ {
+ get { return null; }
+ }
+
+ public string Name
+ {
+ get { return "Groups Module V2"; }
+ }
+
+ public void PostInitialise()
+ {
+ // NoOp
+ }
+
+ #endregion
+
+ #region EventHandlers
+ private void OnNewClient(IClientAPI client)
+ {
+ if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
+
+ client.OnAgentDataUpdateRequest += OnAgentDataUpdateRequest;
+ client.OnRequestAvatarProperties += OnRequestAvatarProperties;
+ }
+
+ private void OnMakeRoot(ScenePresence sp)
+ {
+ if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
+
+ sp.ControllingClient.OnUUIDGroupNameRequest += HandleUUIDGroupNameRequest;
+ // Used for Notices and Group Invites/Accept/Reject
+ sp.ControllingClient.OnInstantMessage += OnInstantMessage;
+
+ // Send client their groups information.
+ SendAgentGroupDataUpdate(sp.ControllingClient, sp.UUID);
+ }
+
+ private void OnMakeChild(ScenePresence sp)
+ {
+ if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
+
+ sp.ControllingClient.OnUUIDGroupNameRequest -= HandleUUIDGroupNameRequest;
+ // Used for Notices and Group Invites/Accept/Reject
+ sp.ControllingClient.OnInstantMessage -= OnInstantMessage;
+ }
+
+ private void OnRequestAvatarProperties(IClientAPI remoteClient, UUID avatarID)
+ {
+ if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
+
+ //GroupMembershipData[] avatarGroups = m_groupData.GetAgentGroupMemberships(GetRequestingAgentID(remoteClient), avatarID).ToArray();
+ GroupMembershipData[] avatarGroups = GetProfileListedGroupMemberships(remoteClient, avatarID);
+ remoteClient.SendAvatarGroupsReply(avatarID, avatarGroups);
+ }
+
+ /*
+ * This becomes very problematic in a shared module. In a shared module you may have more then one
+ * reference to IClientAPI's, one for 0 or 1 root connections, and 0 or more child connections.
+ * The OnClientClosed event does not provide anything to indicate which one of those should be closed
+ * nor does it provide what scene it was from so that the specific reference can be looked up.
+ * The InstantMessageModule.cs does not currently worry about unregistering the handles,
+ * and it should be an issue, since it's the client that references us not the other way around
+ * , so as long as we don't keep a reference to the client laying around, the client can still be GC'ed
+ private void OnClientClosed(UUID AgentId)
+ {
+ if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
+
+ lock (m_ActiveClients)
+ {
+ if (m_ActiveClients.ContainsKey(AgentId))
+ {
+ IClientAPI client = m_ActiveClients[AgentId];
+ client.OnUUIDGroupNameRequest -= HandleUUIDGroupNameRequest;
+ client.OnAgentDataUpdateRequest -= OnAgentDataUpdateRequest;
+ client.OnDirFindQuery -= OnDirFindQuery;
+ client.OnInstantMessage -= OnInstantMessage;
+
+ m_ActiveClients.Remove(AgentId);
+ }
+ else
+ {
+ if (m_debugEnabled) m_log.WarnFormat("[Groups]: Client closed that wasn't registered here.");
+ }
+
+
+ }
+ }
+ */
+
+ private void OnAgentDataUpdateRequest(IClientAPI remoteClient, UUID dataForAgentID, UUID sessionID)
+ {
+ if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
+
+ UUID activeGroupID = UUID.Zero;
+ string activeGroupTitle = string.Empty;
+ string activeGroupName = string.Empty;
+ ulong activeGroupPowers = (ulong)GroupPowers.None;
+
+ GroupMembershipData membership = m_groupData.GetAgentActiveMembership(GetRequestingAgentIDStr(remoteClient), dataForAgentID.ToString());
+ if (membership != null)
+ {
+ activeGroupID = membership.GroupID;
+ activeGroupTitle = membership.GroupTitle;
+ activeGroupPowers = membership.GroupPowers;
+ }
+
+ SendAgentDataUpdate(remoteClient, dataForAgentID, activeGroupID, activeGroupName, activeGroupPowers, activeGroupTitle);
+
+ SendScenePresenceUpdate(dataForAgentID, activeGroupTitle);
+ }
+
+ private void HandleUUIDGroupNameRequest(UUID GroupID, IClientAPI remoteClient)
+ {
+ if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
+
+ string GroupName;
+
+ GroupRecord group = m_groupData.GetGroupRecord(GetRequestingAgentIDStr(remoteClient), GroupID, null);
+ if (group != null)
+ {
+ GroupName = group.GroupName;
+ }
+ else
+ {
+ GroupName = "Unknown";
+ }
+
+ remoteClient.SendGroupNameReply(GroupID, GroupName);
+ }
+
+ private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im)
+ {
+ if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
+
+ //m_log.DebugFormat("[Groups]: IM From {0} to {1} msg {2} type {3}", im.fromAgentID, im.toAgentID, im.message, (InstantMessageDialog)im.dialog);
+ // Group invitations
+ if ((im.dialog == (byte)InstantMessageDialog.GroupInvitationAccept) || (im.dialog == (byte)InstantMessageDialog.GroupInvitationDecline))
+ {
+ UUID inviteID = new UUID(im.imSessionID);
+ GroupInviteInfo inviteInfo = m_groupData.GetAgentToGroupInvite(GetRequestingAgentIDStr(remoteClient), inviteID);
+
+ if (inviteInfo == null)
+ {
+ if (m_debugEnabled) m_log.WarnFormat("[Groups]: Received an Invite IM for an invite that does not exist {0}.", inviteID);
+ return;
+ }
+
+ //m_log.DebugFormat("[XXX]: Invite is for Agent {0} to Group {1}.", inviteInfo.AgentID, inviteInfo.GroupID);
+
+ UUID fromAgentID = new UUID(im.fromAgentID);
+ UUID invitee = UUID.Zero;
+ string tmp = string.Empty;
+ Util.ParseUniversalUserIdentifier(inviteInfo.AgentID, out invitee, out tmp, out tmp, out tmp, out tmp);
+ if ((inviteInfo != null) && (fromAgentID == invitee))
+ {
+ // Accept
+ if (im.dialog == (byte)InstantMessageDialog.GroupInvitationAccept)
+ {
+ //m_log.DebugFormat("[XXX]: Received an accept invite notice.");
+
+ // and the sessionid is the role
+ string reason = string.Empty;
+ if (!m_groupData.AddAgentToGroup(GetRequestingAgentIDStr(remoteClient), invitee.ToString(), inviteInfo.GroupID, inviteInfo.RoleID, string.Empty, out reason))
+ remoteClient.SendAgentAlertMessage("Unable to add you to the group: " + reason, false);
+ else
+ {
+ GridInstantMessage msg = new GridInstantMessage();
+ msg.imSessionID = UUID.Zero.Guid;
+ msg.fromAgentID = UUID.Zero.Guid;
+ msg.toAgentID = invitee.Guid;
+ msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
+ msg.fromAgentName = "Groups";
+ msg.message = string.Format("You have been added to the group.");
+ msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.MessageBox;
+ msg.fromGroup = false;
+ msg.offline = (byte)0;
+ msg.ParentEstateID = 0;
+ msg.Position = Vector3.Zero;
+ msg.RegionID = UUID.Zero.Guid;
+ msg.binaryBucket = new byte[0];
+
+ OutgoingInstantMessage(msg, invitee);
+
+ UpdateAllClientsWithGroupInfo(invitee);
+ }
+
+ m_groupData.RemoveAgentToGroupInvite(GetRequestingAgentIDStr(remoteClient), inviteID);
+
+ }
+
+ // Reject
+ if (im.dialog == (byte)InstantMessageDialog.GroupInvitationDecline)
+ {
+ if (m_debugEnabled) m_log.DebugFormat("[Groups]: Received a reject invite notice.");
+ m_groupData.RemoveAgentToGroupInvite(GetRequestingAgentIDStr(remoteClient), inviteID);
+
+ m_groupData.RemoveAgentFromGroup(GetRequestingAgentIDStr(remoteClient), inviteInfo.AgentID, inviteInfo.GroupID);
+ }
+ }
+ }
+
+ // Group notices
+ if ((im.dialog == (byte)InstantMessageDialog.GroupNotice))
+ {
+ if (!m_groupNoticesEnabled)
+ {
+ return;
+ }
+
+ UUID GroupID = new UUID(im.toAgentID);
+ if (m_groupData.GetGroupRecord(GetRequestingAgentIDStr(remoteClient), GroupID, null) != null)
+ {
+ UUID NoticeID = UUID.Random();
+ string Subject = im.message.Substring(0, im.message.IndexOf('|'));
+ string Message = im.message.Substring(Subject.Length + 1);
+
+ InventoryItemBase item = null;
+ bool hasAttachment = false;
+
+ if (im.binaryBucket.Length >= 1 && im.binaryBucket[0] > 0)
+ {
+ hasAttachment = true;
+ string binBucket = OpenMetaverse.Utils.BytesToString(im.binaryBucket);
+ binBucket = binBucket.Remove(0, 14).Trim();
+
+ OSD binBucketOSD = OSDParser.DeserializeLLSDXml(binBucket);
+ if (binBucketOSD is OSDMap)
+ {
+ OSDMap binBucketMap = (OSDMap)binBucketOSD;
+
+ UUID itemID = binBucketMap["item_id"].AsUUID();
+ UUID ownerID = binBucketMap["owner_id"].AsUUID();
+ item = new InventoryItemBase(itemID, ownerID);
+ item = m_sceneList[0].InventoryService.GetItem(item);
+ }
+ else
+ m_log.DebugFormat("[Groups]: Received OSD with unexpected type: {0}", binBucketOSD.GetType());
+ }
+
+ if (m_groupData.AddGroupNotice(GetRequestingAgentIDStr(remoteClient), GroupID, NoticeID, im.fromAgentName, Subject, Message,
+ hasAttachment,
+ (byte)(item == null ? 0 : item.AssetType),
+ item == null ? null : item.Name,
+ item == null ? UUID.Zero : item.ID,
+ item == null ? UUID.Zero.ToString() : item.Owner.ToString()))
+ {
+ if (OnNewGroupNotice != null)
+ {
+ OnNewGroupNotice(GroupID, NoticeID);
+ }
+
+
+ // Send notice out to everyone that wants notices
+ foreach (GroupMembersData member in m_groupData.GetGroupMembers(GetRequestingAgentIDStr(remoteClient), GroupID))
+ {
+ if (member.AcceptNotices)
+ {
+ // Build notice IIM, one of reach, because the sending may be async
+ GridInstantMessage msg = CreateGroupNoticeIM(UUID.Zero, NoticeID, (byte)OpenMetaverse.InstantMessageDialog.GroupNotice);
+ msg.toAgentID = member.AgentID.Guid;
+ OutgoingInstantMessage(msg, member.AgentID);
+ }
+ }
+ }
+ }
+ }
+
+ if (im.dialog == (byte)InstantMessageDialog.GroupNoticeInventoryAccepted)
+ {
+ if (im.binaryBucket.Length < 16) // Invalid
+ return;
+
+ //// 16 bytes are the UUID. Maybe.
+// UUID folderID = new UUID(im.binaryBucket, 0);
+ UUID noticeID = new UUID(im.imSessionID);
+
+ GroupNoticeInfo notice = m_groupData.GetGroupNotice(remoteClient.AgentId.ToString(), noticeID);
+ if (notice != null)
+ {
+ UUID giver = new UUID(im.toAgentID);
+ string tmp = string.Empty;
+ Util.ParseUniversalUserIdentifier(notice.noticeData.AttachmentOwnerID, out giver, out tmp, out tmp, out tmp, out tmp);
+
+ m_log.DebugFormat("[Groups]: Giving inventory from {0} to {1}", giver, remoteClient.AgentId);
+ string message;
+ InventoryItemBase itemCopy = ((Scene)(remoteClient.Scene)).GiveInventoryItem(remoteClient.AgentId,
+ giver, notice.noticeData.AttachmentItemID, out message);
+
+ if (itemCopy == null)
+ {
+ remoteClient.SendAgentAlertMessage(message, false);
+ return;
+ }
+
+ remoteClient.SendInventoryItemCreateUpdate(itemCopy, 0);
+ }
+
+ }
+
+ // Interop, received special 210 code for ejecting a group member
+ // this only works within the comms servers domain, and won't work hypergrid
+ // TODO:FIXME: Use a presense server of some kind to find out where the
+ // client actually is, and try contacting that region directly to notify them,
+ // or provide the notification via xmlrpc update queue
+ if ((im.dialog == 210))
+ {
+ // This is sent from the region that the ejectee was ejected from
+ // if it's being delivered here, then the ejectee is here
+ // so we need to send local updates to the agent.
+
+ UUID ejecteeID = new UUID(im.toAgentID);
+
+ im.dialog = (byte)InstantMessageDialog.MessageFromAgent;
+ OutgoingInstantMessage(im, ejecteeID);
+
+ IClientAPI ejectee = GetActiveClient(ejecteeID);
+ if (ejectee != null)
+ {
+ UUID groupID = new UUID(im.imSessionID);
+ ejectee.SendAgentDropGroup(groupID);
+ }
+ }
+ }
+
+ private void OnGridInstantMessage(GridInstantMessage msg)
+ {
+ if (m_debugEnabled) m_log.InfoFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
+
+ // Trigger the above event handler
+ OnInstantMessage(null, msg);
+
+ // If a message from a group arrives here, it may need to be forwarded to a local client
+ if (msg.fromGroup == true)
+ {
+ switch (msg.dialog)
+ {
+ case (byte)InstantMessageDialog.GroupInvitation:
+ case (byte)InstantMessageDialog.GroupNotice:
+ UUID toAgentID = new UUID(msg.toAgentID);
+ IClientAPI localClient = GetActiveClient(toAgentID);
+ if (localClient != null)
+ {
+ localClient.SendInstantMessage(msg);
+ }
+ break;
+ }
+ }
+ }
+
+ #endregion
+
+ #region IGroupsModule Members
+
+ public event NewGroupNotice OnNewGroupNotice;
+
+ public GroupRecord GetGroupRecord(UUID GroupID)
+ {
+ return m_groupData.GetGroupRecord(UUID.Zero.ToString(), GroupID, null);
+ }
+
+ public GroupRecord GetGroupRecord(string name)
+ {
+ return m_groupData.GetGroupRecord(UUID.Zero.ToString(), UUID.Zero, name);
+ }
+
+ public void ActivateGroup(IClientAPI remoteClient, UUID groupID)
+ {
+ if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
+
+ m_groupData.SetAgentActiveGroup(GetRequestingAgentIDStr(remoteClient), GetRequestingAgentIDStr(remoteClient), groupID);
+
+ // Changing active group changes title, active powers, all kinds of things
+ // anyone who is in any region that can see this client, should probably be
+ // updated with new group info. At a minimum, they should get ScenePresence
+ // updated with new title.
+ UpdateAllClientsWithGroupInfo(remoteClient.AgentId);
+ }
+
+ ///
+ /// Get the Role Titles for an Agent, for a specific group
+ ///
+ public List GroupTitlesRequest(IClientAPI remoteClient, UUID groupID)
+ {
+ if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
+
+ List agentRoles = m_groupData.GetAgentGroupRoles(GetRequestingAgentIDStr(remoteClient), GetRequestingAgentIDStr(remoteClient), groupID);
+ GroupMembershipData agentMembership = m_groupData.GetAgentGroupMembership(GetRequestingAgentIDStr(remoteClient), GetRequestingAgentIDStr(remoteClient), groupID);
+
+ List titles = new List();
+ foreach (GroupRolesData role in agentRoles)
+ {
+ GroupTitlesData title = new GroupTitlesData();
+ title.Name = role.Name;
+ if (agentMembership != null)
+ {
+ title.Selected = agentMembership.ActiveRole == role.RoleID;
+ }
+ title.UUID = role.RoleID;
+
+ titles.Add(title);
+ }
+
+ return titles;
+ }
+
+ public List GroupMembersRequest(IClientAPI remoteClient, UUID groupID)
+ {
+ if (m_debugEnabled)
+ m_log.DebugFormat(
+ "[Groups]: GroupMembersRequest called for {0} from client {1}", groupID, remoteClient.Name);
+
+ List data = m_groupData.GetGroupMembers(GetRequestingAgentIDStr(remoteClient), groupID);
+
+ if (m_debugEnabled)
+ {
+ foreach (GroupMembersData member in data)
+ {
+ m_log.DebugFormat("[Groups]: Member({0}) - IsOwner({1})", member.AgentID, member.IsOwner);
+ }
+ }
+
+ return data;
+
+ }
+
+ public List GroupRoleDataRequest(IClientAPI remoteClient, UUID groupID)
+ {
+ if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
+
+ List data = m_groupData.GetGroupRoles(GetRequestingAgentIDStr(remoteClient), groupID);
+
+ return data;
+ }
+
+ public List GroupRoleMembersRequest(IClientAPI remoteClient, UUID groupID)
+ {
+ if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
+
+ List data = m_groupData.GetGroupRoleMembers(GetRequestingAgentIDStr(remoteClient), groupID);
+
+ if (m_debugEnabled)
+ {
+ foreach (GroupRoleMembersData member in data)
+ {
+ m_log.DebugFormat("[Groups]: Member({0}) - Role({1})", member.MemberID, member.RoleID);
+ }
+ }
+ return data;
+ }
+
+ public GroupProfileData GroupProfileRequest(IClientAPI remoteClient, UUID groupID)
+ {
+ if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
+
+ GroupProfileData profile = new GroupProfileData();
+
+ // just to get the OwnerRole...
+ ExtendedGroupRecord groupInfo = m_groupData.GetGroupRecord(GetRequestingAgentIDStr(remoteClient), groupID, string.Empty);
+ GroupMembershipData memberInfo = m_groupData.GetAgentGroupMembership(GetRequestingAgentIDStr(remoteClient), GetRequestingAgentIDStr(remoteClient), groupID);
+ if (groupInfo != null)
+ {
+ profile.AllowPublish = groupInfo.AllowPublish;
+ profile.Charter = groupInfo.Charter;
+ profile.FounderID = groupInfo.FounderID;
+ profile.GroupID = groupID;
+ profile.GroupMembershipCount = groupInfo.MemberCount;
+ profile.GroupRolesCount = groupInfo.RoleCount;
+ profile.InsigniaID = groupInfo.GroupPicture;
+ profile.MaturePublish = groupInfo.MaturePublish;
+ profile.MembershipFee = groupInfo.MembershipFee;
+ profile.Money = 0;
+ profile.Name = groupInfo.GroupName;
+ profile.OpenEnrollment = groupInfo.OpenEnrollment;
+ profile.OwnerRole = groupInfo.OwnerRoleID;
+ profile.ShowInList = groupInfo.ShowInList;
+ }
+ if (memberInfo != null)
+ {
+ profile.MemberTitle = memberInfo.GroupTitle;
+ profile.PowersMask = memberInfo.GroupPowers;
+ }
+
+ return profile;
+ }
+
+ public GroupMembershipData[] GetMembershipData(UUID agentID)
+ {
+ if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
+
+ return m_groupData.GetAgentGroupMemberships(UUID.Zero.ToString(), agentID.ToString()).ToArray();
+ }
+
+ public GroupMembershipData GetMembershipData(UUID groupID, UUID agentID)
+ {
+ if (m_debugEnabled)
+ m_log.DebugFormat(
+ "[Groups]: {0} called with groupID={1}, agentID={2}",
+ System.Reflection.MethodBase.GetCurrentMethod().Name, groupID, agentID);
+
+ return m_groupData.GetAgentGroupMembership(UUID.Zero.ToString(), agentID.ToString(), groupID);
+ }
+
+ public void UpdateGroupInfo(IClientAPI remoteClient, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish)
+ {
+ if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
+
+ // Note: Permissions checking for modification rights is handled by the Groups Server/Service
+ string reason = string.Empty;
+ if (!m_groupData.UpdateGroup(GetRequestingAgentIDStr(remoteClient), groupID, charter, showInList, insigniaID, membershipFee,
+ openEnrollment, allowPublish, maturePublish, out reason))
+ remoteClient.SendAgentAlertMessage(reason, false);
+ }
+
+ public void SetGroupAcceptNotices(IClientAPI remoteClient, UUID groupID, bool acceptNotices, bool listInProfile)
+ {
+ // Note: Permissions checking for modification rights is handled by the Groups Server/Service
+ if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
+
+ m_groupData.UpdateMembership(GetRequestingAgentIDStr(remoteClient), GetRequestingAgentIDStr(remoteClient), groupID, acceptNotices, listInProfile);
+ }
+
+ public UUID CreateGroup(IClientAPI remoteClient, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish)
+ {
+ if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called in {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, remoteClient.Scene.RegionInfo.RegionName);
+
+ if (m_groupData.GetGroupRecord(GetRequestingAgentIDStr(remoteClient), UUID.Zero, name) != null)
+ {
+ remoteClient.SendCreateGroupReply(UUID.Zero, false, "A group with the same name already exists.");
+ return UUID.Zero;
+ }
+
+ // check user level
+ ScenePresence avatar = null;
+ Scene scene = (Scene)remoteClient.Scene;
+ scene.TryGetScenePresence(remoteClient.AgentId, out avatar);
+
+ if (avatar != null)
+ {
+ if (avatar.UserLevel < m_levelGroupCreate)
+ {
+ remoteClient.SendCreateGroupReply(UUID.Zero, false, String.Format("Insufficient permissions to create a group. Requires level {0}", m_levelGroupCreate));
+ return UUID.Zero;
+ }
+ }
+
+ // check funds
+ // is there is a money module present ?
+ IMoneyModule money = scene.RequestModuleInterface();
+ if (money != null)
+ {
+ // do the transaction, that is if the agent has got sufficient funds
+ if (!money.AmountCovered(remoteClient.AgentId, money.GroupCreationCharge)) {
+ remoteClient.SendCreateGroupReply(UUID.Zero, false, "Insufficient funds to create a group.");
+ return UUID.Zero;
+ }
+ }
+
+ string reason = string.Empty;
+ UUID groupID = m_groupData.CreateGroup(remoteClient.AgentId, name, charter, showInList, insigniaID, membershipFee, openEnrollment,
+ allowPublish, maturePublish, remoteClient.AgentId, out reason);
+
+ if (groupID != UUID.Zero)
+ {
+ if (money != null)
+ money.ApplyCharge(remoteClient.AgentId, money.GroupCreationCharge, MoneyTransactionType.GroupCreate);
+
+ remoteClient.SendCreateGroupReply(groupID, true, "Group created successfullly");
+
+ // Update the founder with new group information.
+ SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient));
+ }
+ else
+ remoteClient.SendCreateGroupReply(groupID, false, reason);
+
+ return groupID;
+ }
+
+ public GroupNoticeData[] GroupNoticesListRequest(IClientAPI remoteClient, UUID groupID)
+ {
+ if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
+
+ // ToDo: check if agent is a member of group and is allowed to see notices?
+
+ List notices = m_groupData.GetGroupNotices(GetRequestingAgentIDStr(remoteClient), groupID);
+ List os_notices = new List();
+ foreach (ExtendedGroupNoticeData n in notices)
+ {
+ GroupNoticeData osn = n.ToGroupNoticeData();
+ os_notices.Add(osn);
+ }
+
+ return os_notices.ToArray();
+ }
+
+ ///
+ /// Get the title of the agent's current role.
+ ///
+ public string GetGroupTitle(UUID avatarID)
+ {
+ if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
+
+ GroupMembershipData membership = m_groupData.GetAgentActiveMembership(UUID.Zero.ToString(), avatarID.ToString());
+ if (membership != null)
+ {
+ return membership.GroupTitle;
+ }
+ return string.Empty;
+ }
+
+ ///
+ /// Change the current Active Group Role for Agent
+ ///
+ public void GroupTitleUpdate(IClientAPI remoteClient, UUID groupID, UUID titleRoleID)
+ {
+ if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
+
+ m_groupData.SetAgentActiveGroupRole(GetRequestingAgentIDStr(remoteClient), GetRequestingAgentIDStr(remoteClient), groupID, titleRoleID);
+
+ // TODO: Not sure what all is needed here, but if the active group role change is for the group
+ // the client currently has set active, then we need to do a scene presence update too
+ // if (m_groupData.GetAgentActiveMembership(GetRequestingAgentID(remoteClient)).GroupID == GroupID)
+
+ UpdateAllClientsWithGroupInfo(GetRequestingAgentID(remoteClient));
+ }
+
+
+ public void GroupRoleUpdate(IClientAPI remoteClient, UUID groupID, UUID roleID, string name, string description, string title, ulong powers, byte updateType)
+ {
+ if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
+
+ // Security Checks are handled in the Groups Service.
+
+ switch ((OpenMetaverse.GroupRoleUpdate)updateType)
+ {
+ case OpenMetaverse.GroupRoleUpdate.Create:
+ string reason = string.Empty;
+ if (!m_groupData.AddGroupRole(GetRequestingAgentIDStr(remoteClient), groupID, UUID.Random(), name, description, title, powers, out reason))
+ remoteClient.SendAgentAlertMessage("Unable to create role: " + reason, false);
+ break;
+
+ case OpenMetaverse.GroupRoleUpdate.Delete:
+ m_groupData.RemoveGroupRole(GetRequestingAgentIDStr(remoteClient), groupID, roleID);
+ break;
+
+ case OpenMetaverse.GroupRoleUpdate.UpdateAll:
+ case OpenMetaverse.GroupRoleUpdate.UpdateData:
+ case OpenMetaverse.GroupRoleUpdate.UpdatePowers:
+ if (m_debugEnabled)
+ {
+ GroupPowers gp = (GroupPowers)powers;
+ m_log.DebugFormat("[Groups]: Role ({0}) updated with Powers ({1}) ({2})", name, powers.ToString(), gp.ToString());
+ }
+ m_groupData.UpdateGroupRole(GetRequestingAgentIDStr(remoteClient), groupID, roleID, name, description, title, powers);
+ break;
+
+ case OpenMetaverse.GroupRoleUpdate.NoUpdate:
+ default:
+ // No Op
+ break;
+
+ }
+
+ // TODO: This update really should send out updates for everyone in the role that just got changed.
+ SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient));
+ }
+
+ public void GroupRoleChanges(IClientAPI remoteClient, UUID groupID, UUID roleID, UUID memberID, uint changes)
+ {
+ if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
+ // Todo: Security check
+
+ switch (changes)
+ {
+ case 0:
+ // Add
+ m_groupData.AddAgentToGroupRole(GetRequestingAgentIDStr(remoteClient), memberID.ToString(), groupID, roleID);
+
+ break;
+ case 1:
+ // Remove
+ m_groupData.RemoveAgentFromGroupRole(GetRequestingAgentIDStr(remoteClient), memberID.ToString(), groupID, roleID);
+
+ break;
+ default:
+ m_log.ErrorFormat("[Groups]: {0} does not understand changes == {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, changes);
+ break;
+ }
+
+ // TODO: This update really should send out updates for everyone in the role that just got changed.
+ SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient));
+ }
+
+ public void GroupNoticeRequest(IClientAPI remoteClient, UUID groupNoticeID)
+ {
+ if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called for notice {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, groupNoticeID);
+
+ GridInstantMessage msg = CreateGroupNoticeIM(remoteClient.AgentId, groupNoticeID, (byte)InstantMessageDialog.GroupNoticeRequested);
+
+ OutgoingInstantMessage(msg, GetRequestingAgentID(remoteClient));
+ }
+
+ public GridInstantMessage CreateGroupNoticeIM(UUID agentID, UUID groupNoticeID, byte dialog)
+ {
+ if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
+
+ GridInstantMessage msg = new GridInstantMessage();
+ byte[] bucket;
+
+ msg.imSessionID = groupNoticeID.Guid;
+ msg.toAgentID = agentID.Guid;
+ msg.dialog = dialog;
+ // msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.GroupNotice;
+ msg.fromGroup = true;
+ msg.offline = (byte)0;
+ msg.ParentEstateID = 0;
+ msg.Position = Vector3.Zero;
+ msg.RegionID = UUID.Zero.Guid;
+
+ GroupNoticeInfo info = m_groupData.GetGroupNotice(agentID.ToString(), groupNoticeID);
+ if (info != null)
+ {
+ msg.fromAgentID = info.GroupID.Guid;
+ msg.timestamp = info.noticeData.Timestamp;
+ msg.fromAgentName = info.noticeData.FromName;
+ msg.message = info.noticeData.Subject + "|" + info.Message;
+ if (info.noticeData.HasAttachment)
+ {
+ byte[] name = System.Text.Encoding.UTF8.GetBytes(info.noticeData.AttachmentName);
+ bucket = new byte[19 + name.Length];
+ bucket[0] = 1; // has attachment?
+ bucket[1] = info.noticeData.AttachmentType; // attachment type
+ name.CopyTo(bucket, 18);
+ }
+ else
+ {
+ bucket = new byte[19];
+ bucket[0] = 0; // Has att?
+ bucket[1] = 0; // type
+ bucket[18] = 0; // null terminated
+ }
+
+ info.GroupID.ToBytes(bucket, 2);
+ msg.binaryBucket = bucket;
+ }
+ else
+ {
+ m_log.DebugFormat("[Groups]: Group Notice {0} not found, composing empty message.", groupNoticeID);
+ msg.fromAgentID = UUID.Zero.Guid;
+ msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); ;
+ msg.fromAgentName = string.Empty;
+ msg.message = string.Empty;
+ msg.binaryBucket = new byte[0];
+ }
+
+ return msg;
+ }
+
+ public void SendAgentGroupDataUpdate(IClientAPI remoteClient)
+ {
+ if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
+
+ // Send agent information about his groups
+ SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient));
+ }
+
+ public void JoinGroupRequest(IClientAPI remoteClient, UUID groupID)
+ {
+ if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
+
+ string reason = string.Empty;
+ // Should check to see if OpenEnrollment, or if there's an outstanding invitation
+ if (m_groupData.AddAgentToGroup(GetRequestingAgentIDStr(remoteClient), GetRequestingAgentIDStr(remoteClient), groupID, UUID.Zero, string.Empty, out reason))
+ {
+
+ remoteClient.SendJoinGroupReply(groupID, true);
+
+ // Should this send updates to everyone in the group?
+ SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient));
+
+ if (reason != string.Empty)
+ // A warning
+ remoteClient.SendAlertMessage("Warning: " + reason);
+ }
+ else
+ remoteClient.SendJoinGroupReply(groupID, false);
+ }
+
+ public void LeaveGroupRequest(IClientAPI remoteClient, UUID groupID)
+ {
+ if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
+
+ m_groupData.RemoveAgentFromGroup(GetRequestingAgentIDStr(remoteClient), GetRequestingAgentIDStr(remoteClient), groupID);
+
+ remoteClient.SendLeaveGroupReply(groupID, true);
+
+ remoteClient.SendAgentDropGroup(groupID);
+
+ // SL sends out notifcations to the group messaging session that the person has left
+ // Should this also update everyone who is in the group?
+ SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient));
+ }
+
+ public void EjectGroupMemberRequest(IClientAPI remoteClient, UUID groupID, UUID ejecteeID)
+ {
+ EjectGroupMember(remoteClient, GetRequestingAgentID(remoteClient), groupID, ejecteeID);
+ }
+
+ public void EjectGroupMember(IClientAPI remoteClient, UUID agentID, UUID groupID, UUID ejecteeID)
+ {
+ if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
+
+ // Todo: Security check?
+ m_groupData.RemoveAgentFromGroup(agentID.ToString(), ejecteeID.ToString(), groupID);
+
+ string agentName;
+ RegionInfo regionInfo;
+
+ // remoteClient provided or just agentID?
+ if (remoteClient != null)
+ {
+ agentName = remoteClient.Name;
+ regionInfo = remoteClient.Scene.RegionInfo;
+ remoteClient.SendEjectGroupMemberReply(agentID, groupID, true);
+ }
+ else
+ {
+ IClientAPI client = GetActiveClient(agentID);
+
+ if (client != null)
+ {
+ agentName = client.Name;
+ regionInfo = client.Scene.RegionInfo;
+ client.SendEjectGroupMemberReply(agentID, groupID, true);
+ }
+ else
+ {
+ regionInfo = m_sceneList[0].RegionInfo;
+ UserAccount acc = m_sceneList[0].UserAccountService.GetUserAccount(regionInfo.ScopeID, agentID);
+
+ if (acc != null)
+ {
+ agentName = acc.FirstName + " " + acc.LastName;
+ }
+ else
+ {
+ agentName = "Unknown member";
+ }
+ }
+ }
+
+ GroupRecord groupInfo = m_groupData.GetGroupRecord(agentID.ToString(), groupID, null);
+
+ UserAccount account = m_sceneList[0].UserAccountService.GetUserAccount(regionInfo.ScopeID, ejecteeID);
+ if ((groupInfo == null) || (account == null))
+ {
+ return;
+ }
+
+ // Send Message to Ejectee
+ GridInstantMessage msg = new GridInstantMessage();
+
+ msg.imSessionID = UUID.Zero.Guid;
+ msg.fromAgentID = agentID.Guid;
+ // msg.fromAgentID = info.GroupID;
+ msg.toAgentID = ejecteeID.Guid;
+ //msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
+ msg.timestamp = 0;
+ msg.fromAgentName = agentName;
+ msg.message = string.Format("You have been ejected from '{1}' by {0}.", agentName, groupInfo.GroupName);
+ msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.MessageFromAgent;
+ msg.fromGroup = false;
+ msg.offline = (byte)0;
+ msg.ParentEstateID = 0;
+ msg.Position = Vector3.Zero;
+ msg.RegionID = regionInfo.RegionID.Guid;
+ msg.binaryBucket = new byte[0];
+ OutgoingInstantMessage(msg, ejecteeID);
+
+ // Message to ejector
+ // Interop, received special 210 code for ejecting a group member
+ // this only works within the comms servers domain, and won't work hypergrid
+ // TODO:FIXME: Use a presense server of some kind to find out where the
+ // client actually is, and try contacting that region directly to notify them,
+ // or provide the notification via xmlrpc update queue
+
+ msg = new GridInstantMessage();
+ msg.imSessionID = UUID.Zero.Guid;
+ msg.fromAgentID = agentID.Guid;
+ msg.toAgentID = agentID.Guid;
+ msg.timestamp = 0;
+ msg.fromAgentName = agentName;
+ if (account != null)
+ {
+ msg.message = string.Format("{2} has been ejected from '{1}' by {0}.", agentName, groupInfo.GroupName, account.FirstName + " " + account.LastName);
+ }
+ else
+ {
+ msg.message = string.Format("{2} has been ejected from '{1}' by {0}.", agentName, groupInfo.GroupName, "Unknown member");
+ }
+ msg.dialog = (byte)210; //interop
+ msg.fromGroup = false;
+ msg.offline = (byte)0;
+ msg.ParentEstateID = 0;
+ msg.Position = Vector3.Zero;
+ msg.RegionID = regionInfo.RegionID.Guid;
+ msg.binaryBucket = new byte[0];
+ OutgoingInstantMessage(msg, agentID);
+
+
+ // SL sends out messages to everyone in the group
+ // Who all should receive updates and what should they be updated with?
+ UpdateAllClientsWithGroupInfo(ejecteeID);
+ }
+
+ public void InviteGroupRequest(IClientAPI remoteClient, UUID groupID, UUID invitedAgentID, UUID roleID)
+ {
+ InviteGroup(remoteClient, GetRequestingAgentID(remoteClient), groupID, invitedAgentID, roleID);
+ }
+
+ public void InviteGroup(IClientAPI remoteClient, UUID agentID, UUID groupID, UUID invitedAgentID, UUID roleID)
+ {
+ if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
+
+ string agentName = m_UserManagement.GetUserName(agentID);
+ RegionInfo regionInfo = m_sceneList[0].RegionInfo;
+
+ GroupRecord group = m_groupData.GetGroupRecord(agentID.ToString(), groupID, null);
+ if (group == null)
+ {
+ m_log.DebugFormat("[Groups]: No such group {0}", groupID);
+ return;
+ }
+
+ // Todo: Security check, probably also want to send some kind of notification
+ UUID InviteID = UUID.Random();
+
+ if (m_groupData.AddAgentToGroupInvite(agentID.ToString(), InviteID, groupID, roleID, invitedAgentID.ToString()))
+ {
+ if (m_msgTransferModule != null)
+ {
+ Guid inviteUUID = InviteID.Guid;
+
+ GridInstantMessage msg = new GridInstantMessage();
+
+ msg.imSessionID = inviteUUID;
+
+ // msg.fromAgentID = agentID.Guid;
+ msg.fromAgentID = groupID.Guid;
+ msg.toAgentID = invitedAgentID.Guid;
+ //msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
+ msg.timestamp = 0;
+ msg.fromAgentName = agentName;
+ msg.message = string.Format("{0} has invited you to join a group called {1}. There is no cost to join this group.", agentName, group.GroupName);
+ msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.GroupInvitation;
+ msg.fromGroup = true;
+ msg.offline = (byte)0;
+ msg.ParentEstateID = 0;
+ msg.Position = Vector3.Zero;
+ msg.RegionID = regionInfo.RegionID.Guid;
+ msg.binaryBucket = new byte[20];
+
+ OutgoingInstantMessage(msg, invitedAgentID);
+ }
+ }
+ }
+
+ public List FindGroups(IClientAPI remoteClient, string query)
+ {
+ return m_groupData.FindGroups(GetRequestingAgentIDStr(remoteClient), query);
+ }
+
+ #endregion
+
+ #region Client/Update Tools
+
+ ///
+ /// Try to find an active IClientAPI reference for agentID giving preference to root connections
+ ///
+ private IClientAPI GetActiveClient(UUID agentID)
+ {
+ IClientAPI child = null;
+
+ // Try root avatar first
+ foreach (Scene scene in m_sceneList)
+ {
+ ScenePresence sp = scene.GetScenePresence(agentID);
+ if (sp != null)
+ {
+ if (!sp.IsChildAgent)
+ {
+ return sp.ControllingClient;
+ }
+ else
+ {
+ child = sp.ControllingClient;
+ }
+ }
+ }
+
+ // If we didn't find a root, then just return whichever child we found, or null if none
+ return child;
+ }
+
+ ///
+ /// Send 'remoteClient' the group membership 'data' for agent 'dataForAgentID'.
+ ///
+ private void SendGroupMembershipInfoViaCaps(IClientAPI remoteClient, UUID dataForAgentID, GroupMembershipData[] data)
+ {
+ if (m_debugEnabled) m_log.InfoFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
+
+ // NPCs currently don't have a CAPs structure or event queues. There is a strong argument for conveying this information
+ // to them anyway since it makes writing server-side bots a lot easier, but for now we don't do anything.
+ if (remoteClient.SceneAgent.PresenceType == PresenceType.Npc)
+ return;
+
+ OSDArray AgentData = new OSDArray(1);
+ OSDMap AgentDataMap = new OSDMap(1);
+ AgentDataMap.Add("AgentID", OSD.FromUUID(dataForAgentID));
+ AgentData.Add(AgentDataMap);
+
+ OSDArray GroupData = new OSDArray(data.Length);
+ OSDArray NewGroupData = new OSDArray(data.Length);
+
+ foreach (GroupMembershipData membership in data)
+ {
+ if (GetRequestingAgentID(remoteClient) != dataForAgentID)
+ {
+ if (!membership.ListInProfile)
+ {
+ // If we're sending group info to remoteclient about another agent,
+ // filter out groups the other agent doesn't want to share.
+ continue;
+ }
+ }
+
+ OSDMap GroupDataMap = new OSDMap(6);
+ OSDMap NewGroupDataMap = new OSDMap(1);
+
+ GroupDataMap.Add("GroupID", OSD.FromUUID(membership.GroupID));
+ GroupDataMap.Add("GroupPowers", OSD.FromULong(membership.GroupPowers));
+ GroupDataMap.Add("AcceptNotices", OSD.FromBoolean(membership.AcceptNotices));
+ GroupDataMap.Add("GroupInsigniaID", OSD.FromUUID(membership.GroupPicture));
+ GroupDataMap.Add("Contribution", OSD.FromInteger(membership.Contribution));
+ GroupDataMap.Add("GroupName", OSD.FromString(membership.GroupName));
+ NewGroupDataMap.Add("ListInProfile", OSD.FromBoolean(membership.ListInProfile));
+
+ GroupData.Add(GroupDataMap);
+ NewGroupData.Add(NewGroupDataMap);
+ }
+
+ OSDMap llDataStruct = new OSDMap(3);
+ llDataStruct.Add("AgentData", AgentData);
+ llDataStruct.Add("GroupData", GroupData);
+ llDataStruct.Add("NewGroupData", NewGroupData);
+
+ if (m_debugEnabled)
+ {
+ m_log.InfoFormat("[Groups]: {0}", OSDParser.SerializeJsonString(llDataStruct));
+ }
+
+ IEventQueue queue = remoteClient.Scene.RequestModuleInterface();
+
+ if (queue != null)
+ {
+ queue.Enqueue(queue.BuildEvent("AgentGroupDataUpdate", llDataStruct), GetRequestingAgentID(remoteClient));
+ }
+ }
+
+ private void SendScenePresenceUpdate(UUID AgentID, string Title)
+ {
+ if (m_debugEnabled) m_log.DebugFormat("[Groups]: Updating scene title for {0} with title: {1}", AgentID, Title);
+
+ ScenePresence presence = null;
+
+ foreach (Scene scene in m_sceneList)
+ {
+ presence = scene.GetScenePresence(AgentID);
+ if (presence != null)
+ {
+ if (presence.Grouptitle != Title)
+ {
+ presence.Grouptitle = Title;
+
+ if (! presence.IsChildAgent)
+ presence.SendAvatarDataToAllClients();
+ }
+ }
+ }
+ }
+
+ ///
+ /// Send updates to all clients who might be interested in groups data for dataForClientID
+ ///
+ private void UpdateAllClientsWithGroupInfo(UUID dataForClientID)
+ {
+ if (m_debugEnabled) m_log.InfoFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
+
+ // TODO: Probably isn't nessesary to update every client in every scene.
+ // Need to examine client updates and do only what's nessesary.
+ lock (m_sceneList)
+ {
+ foreach (Scene scene in m_sceneList)
+ {
+ scene.ForEachClient(delegate(IClientAPI client) { SendAgentGroupDataUpdate(client, dataForClientID); });
+ }
+ }
+ }
+
+ ///
+ /// Update remoteClient with group information about dataForAgentID
+ ///
+ private void SendAgentGroupDataUpdate(IClientAPI remoteClient, UUID dataForAgentID)
+ {
+ if (m_debugEnabled) m_log.InfoFormat("[Groups]: {0} called for {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, remoteClient.Name);
+
+ // TODO: All the client update functions need to be reexamined because most do too much and send too much stuff
+
+ OnAgentDataUpdateRequest(remoteClient, dataForAgentID, UUID.Zero);
+
+ // Need to send a group membership update to the client
+ // UDP version doesn't seem to behave nicely. But we're going to send it out here
+ // with an empty group membership to hopefully remove groups being displayed due
+ // to the core Groups Stub
+ //remoteClient.SendGroupMembership(new GroupMembershipData[0]);
+
+ GroupMembershipData[] membershipArray = GetProfileListedGroupMemberships(remoteClient, dataForAgentID);
+ SendGroupMembershipInfoViaCaps(remoteClient, dataForAgentID, membershipArray);
+
+ //remoteClient.SendAvatarGroupsReply(dataForAgentID, membershipArray);
+ if (remoteClient.AgentId == dataForAgentID)
+ remoteClient.RefreshGroupMembership();
+ }
+
+ ///
+ /// Get a list of groups memberships for the agent that are marked "ListInProfile"
+ /// (unless that agent has a godLike aspect, in which case get all groups)
+ ///
+ ///
+ ///
+ private GroupMembershipData[] GetProfileListedGroupMemberships(IClientAPI requestingClient, UUID dataForAgentID)
+ {
+ List membershipData = m_groupData.GetAgentGroupMemberships(requestingClient.AgentId.ToString(), dataForAgentID.ToString());
+ GroupMembershipData[] membershipArray;
+
+ // cScene and property accessor 'isGod' are in support of the opertions to bypass 'hidden' group attributes for
+ // those with a GodLike aspect.
+ Scene cScene = (Scene)requestingClient.Scene;
+ bool isGod = cScene.Permissions.IsGod(requestingClient.AgentId);
+
+ if (isGod)
+ {
+ membershipArray = membershipData.ToArray();
+ }
+ else
+ {
+ if (requestingClient.AgentId != dataForAgentID)
+ {
+ Predicate showInProfile = delegate(GroupMembershipData membership)
+ {
+ return membership.ListInProfile;
+ };
+
+ membershipArray = membershipData.FindAll(showInProfile).ToArray();
+ }
+ else
+ {
+ membershipArray = membershipData.ToArray();
+ }
+ }
+
+ if (m_debugEnabled)
+ {
+ m_log.InfoFormat("[Groups]: Get group membership information for {0} requested by {1}", dataForAgentID, requestingClient.AgentId);
+ foreach (GroupMembershipData membership in membershipArray)
+ {
+ m_log.InfoFormat("[Groups]: {0} :: {1} - {2} - {3}", dataForAgentID, membership.GroupName, membership.GroupTitle, membership.GroupPowers);
+ }
+ }
+
+ return membershipArray;
+ }
+
+
+ private void SendAgentDataUpdate(IClientAPI remoteClient, UUID dataForAgentID, UUID activeGroupID, string activeGroupName, ulong activeGroupPowers, string activeGroupTitle)
+ {
+ if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
+
+ // TODO: All the client update functions need to be reexamined because most do too much and send too much stuff
+ string firstname = "Unknown", lastname = "Unknown";
+ string name = m_UserManagement.GetUserName(dataForAgentID);
+ if (!string.IsNullOrEmpty(name))
+ {
+ string[] parts = name.Split(new char[] { ' ' });
+ if (parts.Length >= 2)
+ {
+ firstname = parts[0];
+ lastname = parts[1];
+ }
+ }
+
+ remoteClient.SendAgentDataUpdate(dataForAgentID, activeGroupID, firstname,
+ lastname, activeGroupPowers, activeGroupName,
+ activeGroupTitle);
+ }
+
+ #endregion
+
+ #region IM Backed Processes
+
+ private void OutgoingInstantMessage(GridInstantMessage msg, UUID msgTo)
+ {
+ if (m_debugEnabled) m_log.InfoFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
+
+ IClientAPI localClient = GetActiveClient(msgTo);
+ if (localClient != null)
+ {
+ if (m_debugEnabled) m_log.InfoFormat("[Groups]: MsgTo ({0}) is local, delivering directly", localClient.Name);
+ localClient.SendInstantMessage(msg);
+ }
+ else if (m_msgTransferModule != null)
+ {
+ if (m_debugEnabled) m_log.InfoFormat("[Groups]: MsgTo ({0}) is not local, delivering via TransferModule", msgTo);
+ m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { if (m_debugEnabled) m_log.DebugFormat("[Groups]: Message Sent: {0}", success?"Succeeded":"Failed"); });
+ }
+ }
+
+ public void NotifyChange(UUID groupID)
+ {
+ // Notify all group members of a chnge in group roles and/or
+ // permissions
+ //
+ }
+
+ #endregion
+
+ private string GetRequestingAgentIDStr(IClientAPI client)
+ {
+ return GetRequestingAgentID(client).ToString();
+ }
+
+ private UUID GetRequestingAgentID(IClientAPI client)
+ {
+ UUID requestingAgentID = UUID.Zero;
+ if (client != null)
+ {
+ requestingAgentID = client.AgentId;
+ }
+ return requestingAgentID;
+ }
+
+ }
+
+}
diff --git a/OpenSim/Addons/Groups/Hypergrid/GroupsServiceHGConnector.cs b/OpenSim/Addons/Groups/Hypergrid/GroupsServiceHGConnector.cs
new file mode 100644
index 0000000000..653dbac8bd
--- /dev/null
+++ b/OpenSim/Addons/Groups/Hypergrid/GroupsServiceHGConnector.cs
@@ -0,0 +1,289 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSimulator Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+
+using OpenSim.Framework;
+using OpenSim.Server.Base;
+
+using OpenMetaverse;
+using log4net;
+
+namespace OpenSim.Groups
+{
+ public class GroupsServiceHGConnector
+ {
+ private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+ private string m_ServerURI;
+ private object m_Lock = new object();
+
+ public GroupsServiceHGConnector(string url)
+ {
+ m_ServerURI = url;
+ if (!m_ServerURI.EndsWith("/"))
+ m_ServerURI += "/";
+
+ m_log.DebugFormat("[Groups.HGConnector]: Groups server at {0}", m_ServerURI);
+ }
+
+ public bool CreateProxy(string RequestingAgentID, string AgentID, string accessToken, UUID groupID, string url, string name, out string reason)
+ {
+ reason = string.Empty;
+
+ Dictionary sendData = new Dictionary();
+ sendData["RequestingAgentID"] = RequestingAgentID;
+ sendData["AgentID"] = AgentID.ToString();
+ sendData["AccessToken"] = accessToken;
+ sendData["GroupID"] = groupID.ToString();
+ sendData["Location"] = url;
+ sendData["Name"] = name;
+ Dictionary ret = MakeRequest("POSTGROUP", sendData);
+
+ if (ret == null)
+ return false;
+
+ if (!ret.ContainsKey("RESULT"))
+ return false;
+
+ if (ret["RESULT"].ToString().ToLower() != "true")
+ {
+ reason = ret["REASON"].ToString();
+ return false;
+ }
+
+ return true;
+
+ }
+
+ public void RemoveAgentFromGroup(string AgentID, UUID GroupID, string token)
+ {
+ Dictionary sendData = new Dictionary();
+ sendData["AgentID"] = AgentID;
+ sendData["GroupID"] = GroupID.ToString();
+ sendData["AccessToken"] = GroupsDataUtils.Sanitize(token);
+ MakeRequest("REMOVEAGENTFROMGROUP", sendData);
+ }
+
+ public ExtendedGroupRecord GetGroupRecord(string RequestingAgentID, UUID GroupID, string GroupName, string token)
+ {
+ if (GroupID == UUID.Zero && (GroupName == null || (GroupName != null && GroupName == string.Empty)))
+ return null;
+
+ Dictionary sendData = new Dictionary();
+ if (GroupID != UUID.Zero)
+ sendData["GroupID"] = GroupID.ToString();
+ if (!string.IsNullOrEmpty(GroupName))
+ sendData["Name"] = GroupsDataUtils.Sanitize(GroupName);
+
+ sendData["RequestingAgentID"] = RequestingAgentID;
+ sendData["AccessToken"] = GroupsDataUtils.Sanitize(token);
+
+ Dictionary ret = MakeRequest("GETGROUP", sendData);
+
+ if (ret == null)
+ return null;
+
+ if (!ret.ContainsKey("RESULT"))
+ return null;
+
+ if (ret["RESULT"].ToString() == "NULL")
+ return null;
+
+ return GroupsDataUtils.GroupRecord((Dictionary)ret["RESULT"]);
+ }
+
+ public List GetGroupMembers(string RequestingAgentID, UUID GroupID, string token)
+ {
+ List members = new List();
+
+ Dictionary sendData = new Dictionary();
+ sendData["GroupID"] = GroupID.ToString();
+ sendData["RequestingAgentID"] = RequestingAgentID;
+ sendData["AccessToken"] = GroupsDataUtils.Sanitize(token);
+ Dictionary ret = MakeRequest("GETGROUPMEMBERS", sendData);
+
+ if (ret == null)
+ return members;
+
+ if (!ret.ContainsKey("RESULT"))
+ return members;
+
+ if (ret["RESULT"].ToString() == "NULL")
+ return members;
+ foreach (object v in ((Dictionary)ret["RESULT"]).Values)
+ {
+ ExtendedGroupMembersData m = GroupsDataUtils.GroupMembersData((Dictionary)v);
+ members.Add(m);
+ }
+
+ return members;
+ }
+
+ public List GetGroupRoles(string RequestingAgentID, UUID GroupID, string token)
+ {
+ List roles = new List();
+
+ Dictionary sendData = new Dictionary();
+ sendData["GroupID"] = GroupID.ToString();
+ sendData["RequestingAgentID"] = RequestingAgentID;
+ sendData["AccessToken"] = GroupsDataUtils.Sanitize(token);
+ Dictionary ret = MakeRequest("GETGROUPROLES", sendData);
+
+ if (ret == null)
+ return roles;
+
+ if (!ret.ContainsKey("RESULT"))
+ return roles;
+
+ if (ret["RESULT"].ToString() == "NULL")
+ return roles;
+ foreach (object v in ((Dictionary)ret["RESULT"]).Values)
+ {
+ GroupRolesData m = GroupsDataUtils.GroupRolesData((Dictionary)v);
+ roles.Add(m);
+ }
+
+ return roles;
+ }
+
+ public List GetGroupRoleMembers(string RequestingAgentID, UUID GroupID, string token)
+ {
+ List rmembers = new List();
+
+ Dictionary sendData = new Dictionary();
+ sendData["GroupID"] = GroupID.ToString();
+ sendData["RequestingAgentID"] = RequestingAgentID;
+ sendData["AccessToken"] = GroupsDataUtils.Sanitize(token);
+ Dictionary ret = MakeRequest("GETROLEMEMBERS", sendData);
+
+ if (ret == null)
+ return rmembers;
+
+ if (!ret.ContainsKey("RESULT"))
+ return rmembers;
+
+ if (ret["RESULT"].ToString() == "NULL")
+ return rmembers;
+
+ foreach (object v in ((Dictionary)ret["RESULT"]).Values)
+ {
+ ExtendedGroupRoleMembersData m = GroupsDataUtils.GroupRoleMembersData((Dictionary)v);
+ rmembers.Add(m);
+ }
+
+ return rmembers;
+ }
+
+ public bool AddNotice(string RequestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message,
+ bool hasAttachment, byte attType, string attName, UUID attItemID, string attOwnerID)
+ {
+ Dictionary sendData = new Dictionary();
+ sendData["GroupID"] = groupID.ToString();
+ sendData["NoticeID"] = noticeID.ToString();
+ sendData["FromName"] = GroupsDataUtils.Sanitize(fromName);
+ sendData["Subject"] = GroupsDataUtils.Sanitize(subject);
+ sendData["Message"] = GroupsDataUtils.Sanitize(message);
+ sendData["HasAttachment"] = hasAttachment.ToString();
+ if (hasAttachment)
+ {
+ sendData["AttachmentType"] = attType.ToString();
+ sendData["AttachmentName"] = attName.ToString();
+ sendData["AttachmentItemID"] = attItemID.ToString();
+ sendData["AttachmentOwnerID"] = attOwnerID;
+ }
+ sendData["RequestingAgentID"] = RequestingAgentID;
+
+ Dictionary ret = MakeRequest("ADDNOTICE", sendData);
+
+ if (ret == null)
+ return false;
+
+ if (!ret.ContainsKey("RESULT"))
+ return false;
+
+ if (ret["RESULT"].ToString().ToLower() != "true")
+ return false;
+
+ return true;
+ }
+
+ public bool VerifyNotice(UUID noticeID, UUID groupID)
+ {
+ Dictionary sendData = new Dictionary();
+ sendData["NoticeID"] = noticeID.ToString();
+ sendData["GroupID"] = groupID.ToString();
+ Dictionary ret = MakeRequest("VERIFYNOTICE", sendData);
+
+ if (ret == null)
+ return false;
+
+ if (!ret.ContainsKey("RESULT"))
+ return false;
+
+ if (ret["RESULT"].ToString().ToLower() != "true")
+ return false;
+
+ return true;
+ }
+
+ //
+ //
+ //
+ //
+ //
+
+ #region Make Request
+
+ private Dictionary MakeRequest(string method, Dictionary sendData)
+ {
+ sendData["METHOD"] = method;
+
+ string reply = string.Empty;
+ lock (m_Lock)
+ reply = SynchronousRestFormsRequester.MakeRequest("POST",
+ m_ServerURI + "hg-groups",
+ ServerUtils.BuildQueryString(sendData));
+
+ //m_log.DebugFormat("[XXX]: reply was {0}", reply);
+
+ if (string.IsNullOrEmpty(reply))
+ return null;
+
+ Dictionary replyData = ServerUtils.ParseXmlResponse(
+ reply);
+
+ return replyData;
+ }
+ #endregion
+
+ }
+}
diff --git a/OpenSim/Addons/Groups/Hypergrid/GroupsServiceHGConnectorModule.cs b/OpenSim/Addons/Groups/Hypergrid/GroupsServiceHGConnectorModule.cs
new file mode 100644
index 0000000000..7d57de190b
--- /dev/null
+++ b/OpenSim/Addons/Groups/Hypergrid/GroupsServiceHGConnectorModule.cs
@@ -0,0 +1,707 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSimulator Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+
+using OpenSim.Framework;
+using OpenSim.Framework.Monitoring;
+using OpenSim.Framework.Servers;
+using OpenSim.Region.Framework.Scenes;
+using OpenSim.Region.Framework.Interfaces;
+using OpenSim.Services.Interfaces;
+
+using OpenMetaverse;
+using Mono.Addins;
+using log4net;
+using Nini.Config;
+
+namespace OpenSim.Groups
+{
+ [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GroupsServiceHGConnectorModule")]
+ public class GroupsServiceHGConnectorModule : ISharedRegionModule, IGroupsServicesConnector
+ {
+ private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+ private bool m_Enabled = false;
+ private IGroupsServicesConnector m_LocalGroupsConnector;
+ private string m_LocalGroupsServiceLocation;
+ private IUserManagement m_UserManagement;
+ private IOfflineIMService m_OfflineIM;
+ private IMessageTransferModule m_Messaging;
+ private List m_Scenes;
+ private ForeignImporter m_ForeignImporter;
+ private string m_ServiceLocation;
+ private IConfigSource m_Config;
+
+ private Dictionary m_NetworkConnectors = new Dictionary();
+ private RemoteConnectorCacheWrapper m_CacheWrapper; // for caching info of external group services
+
+ #region ISharedRegionModule
+
+ public void Initialise(IConfigSource config)
+ {
+ IConfig groupsConfig = config.Configs["Groups"];
+ if (groupsConfig == null)
+ return;
+
+ if ((groupsConfig.GetBoolean("Enabled", false) == false)
+ || (groupsConfig.GetString("ServicesConnectorModule", string.Empty) != Name))
+ {
+ return;
+ }
+
+ m_Config = config;
+ m_ServiceLocation = groupsConfig.GetString("LocalService", "local"); // local or remote
+ m_LocalGroupsServiceLocation = groupsConfig.GetString("GroupsExternalURI", "http://127.0.0.1");
+ m_Scenes = new List();
+
+ m_Enabled = true;
+
+ m_log.DebugFormat("[Groups]: Initializing {0} with LocalService {1}", this.Name, m_ServiceLocation);
+ }
+
+ public string Name
+ {
+ get { return "Groups HG Service Connector"; }
+ }
+
+ public Type ReplaceableInterface
+ {
+ get { return null; }
+ }
+
+ public void AddRegion(Scene scene)
+ {
+ if (!m_Enabled)
+ return;
+
+ m_log.DebugFormat("[Groups]: Registering {0} with {1}", this.Name, scene.RegionInfo.RegionName);
+ scene.RegisterModuleInterface(this);
+ m_Scenes.Add(scene);
+
+ scene.EventManager.OnNewClient += OnNewClient;
+ }
+
+ public void RemoveRegion(Scene scene)
+ {
+ if (!m_Enabled)
+ return;
+
+ scene.UnregisterModuleInterface(this);
+ m_Scenes.Remove(scene);
+ }
+
+ public void RegionLoaded(Scene scene)
+ {
+ if (!m_Enabled)
+ return;
+
+ if (m_UserManagement == null)
+ {
+ m_UserManagement = scene.RequestModuleInterface();
+ m_OfflineIM = scene.RequestModuleInterface();
+ m_Messaging = scene.RequestModuleInterface();
+ m_ForeignImporter = new ForeignImporter(m_UserManagement);
+
+ if (m_ServiceLocation.Equals("local"))
+ {
+ m_LocalGroupsConnector = new GroupsServiceLocalConnectorModule(m_Config, m_UserManagement);
+ // Also, if local, create the endpoint for the HGGroupsService
+ new HGGroupsServiceRobustConnector(m_Config, MainServer.Instance, string.Empty,
+ scene.RequestModuleInterface(), scene.RequestModuleInterface());
+
+ }
+ else
+ m_LocalGroupsConnector = new GroupsServiceRemoteConnectorModule(m_Config, m_UserManagement);
+
+ m_CacheWrapper = new RemoteConnectorCacheWrapper(m_UserManagement);
+ }
+
+ }
+
+ public void PostInitialise()
+ {
+ }
+
+ public void Close()
+ {
+ }
+
+ #endregion
+
+ private void OnNewClient(IClientAPI client)
+ {
+ client.OnCompleteMovementToRegion += OnCompleteMovementToRegion;
+ }
+
+ void OnCompleteMovementToRegion(IClientAPI client, bool arg2)
+ {
+ object sp = null;
+ if (client.Scene.TryGetScenePresence(client.AgentId, out sp))
+ {
+ if (sp is ScenePresence && ((ScenePresence)sp).PresenceType != PresenceType.Npc)
+ {
+ AgentCircuitData aCircuit = ((ScenePresence)sp).Scene.AuthenticateHandler.GetAgentCircuitData(client.AgentId);
+ if (aCircuit != null && (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0 &&
+ m_OfflineIM != null && m_Messaging != null)
+ {
+ List ims = m_OfflineIM.GetMessages(aCircuit.AgentID);
+ if (ims != null && ims.Count > 0)
+ foreach (GridInstantMessage im in ims)
+ m_Messaging.SendInstantMessage(im, delegate(bool success) { });
+ }
+ }
+ }
+ }
+
+ #region IGroupsServicesConnector
+
+ public UUID CreateGroup(UUID RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment,
+ bool allowPublish, bool maturePublish, UUID founderID, out string reason)
+ {
+ reason = string.Empty;
+ if (m_UserManagement.IsLocalGridUser(RequestingAgentID))
+ return m_LocalGroupsConnector.CreateGroup(RequestingAgentID, name, charter, showInList, insigniaID,
+ membershipFee, openEnrollment, allowPublish, maturePublish, founderID, out reason);
+ else
+ {
+ reason = "Only local grid users are allowed to create a new group";
+ return UUID.Zero;
+ }
+ }
+
+ public bool UpdateGroup(string RequestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee,
+ bool openEnrollment, bool allowPublish, bool maturePublish, out string reason)
+ {
+ reason = string.Empty;
+ string url = string.Empty;
+ string name = string.Empty;
+ if (IsLocal(groupID, out url, out name))
+ return m_LocalGroupsConnector.UpdateGroup(AgentUUI(RequestingAgentID), groupID, charter, showInList, insigniaID, membershipFee,
+ openEnrollment, allowPublish, maturePublish, out reason);
+ else
+ {
+ reason = "Changes to remote group not allowed. Please go to the group's original world.";
+ return false;
+ }
+ }
+
+ public ExtendedGroupRecord GetGroupRecord(string RequestingAgentID, UUID GroupID, string GroupName)
+ {
+ string url = string.Empty;
+ string name = string.Empty;
+ if (IsLocal(GroupID, out url, out name))
+ return m_LocalGroupsConnector.GetGroupRecord(AgentUUI(RequestingAgentID), GroupID, GroupName);
+ else if (url != string.Empty)
+ {
+ ExtendedGroupMembershipData membership = m_LocalGroupsConnector.GetAgentGroupMembership(RequestingAgentID, RequestingAgentID, GroupID);
+ string accessToken = string.Empty;
+ if (membership != null)
+ accessToken = membership.AccessToken;
+ else
+ return null;
+
+ GroupsServiceHGConnector c = GetConnector(url);
+ if (c != null)
+ {
+ ExtendedGroupRecord grec = m_CacheWrapper.GetGroupRecord(RequestingAgentID, GroupID, GroupName, delegate
+ {
+ return c.GetGroupRecord(AgentUUIForOutside(RequestingAgentID), GroupID, GroupName, accessToken);
+ });
+
+ if (grec != null)
+ ImportForeigner(grec.FounderUUI);
+ return grec;
+ }
+ }
+
+ return null;
+ }
+
+ public List FindGroups(string RequestingAgentID, string search)
+ {
+ return m_LocalGroupsConnector.FindGroups(AgentUUI(RequestingAgentID), search);
+ }
+
+ public List GetGroupMembers(string RequestingAgentID, UUID GroupID)
+ {
+ string url = string.Empty, gname = string.Empty;
+ if (IsLocal(GroupID, out url, out gname))
+ {
+ string agentID = AgentUUI(RequestingAgentID);
+ return m_LocalGroupsConnector.GetGroupMembers(agentID, GroupID);
+ }
+ else if (!string.IsNullOrEmpty(url))
+ {
+ ExtendedGroupMembershipData membership = m_LocalGroupsConnector.GetAgentGroupMembership(RequestingAgentID, RequestingAgentID, GroupID);
+ string accessToken = string.Empty;
+ if (membership != null)
+ accessToken = membership.AccessToken;
+ else
+ return null;
+
+ GroupsServiceHGConnector c = GetConnector(url);
+ if (c != null)
+ {
+ return m_CacheWrapper.GetGroupMembers(RequestingAgentID, GroupID, delegate
+ {
+ return c.GetGroupMembers(AgentUUIForOutside(RequestingAgentID), GroupID, accessToken);
+ });
+
+ }
+ }
+ return new List();
+ }
+
+ public bool AddGroupRole(string RequestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers, out string reason)
+ {
+ reason = string.Empty;
+ string url = string.Empty, gname = string.Empty;
+
+ if (IsLocal(groupID, out url, out gname))
+ return m_LocalGroupsConnector.AddGroupRole(AgentUUI(RequestingAgentID), groupID, roleID, name, description, title, powers, out reason);
+ else
+ {
+ reason = "Operation not allowed outside this group's origin world.";
+ return false;
+ }
+ }
+
+ public bool UpdateGroupRole(string RequestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers)
+ {
+ string url = string.Empty, gname = string.Empty;
+
+ if (IsLocal(groupID, out url, out gname))
+ return m_LocalGroupsConnector.UpdateGroupRole(AgentUUI(RequestingAgentID), groupID, roleID, name, description, title, powers);
+ else
+ {
+ return false;
+ }
+
+ }
+
+ public void RemoveGroupRole(string RequestingAgentID, UUID groupID, UUID roleID)
+ {
+ string url = string.Empty, gname = string.Empty;
+
+ if (IsLocal(groupID, out url, out gname))
+ m_LocalGroupsConnector.RemoveGroupRole(AgentUUI(RequestingAgentID), groupID, roleID);
+ else
+ {
+ return;
+ }
+ }
+
+ public List GetGroupRoles(string RequestingAgentID, UUID groupID)
+ {
+ string url = string.Empty, gname = string.Empty;
+
+ if (IsLocal(groupID, out url, out gname))
+ return m_LocalGroupsConnector.GetGroupRoles(AgentUUI(RequestingAgentID), groupID);
+ else if (!string.IsNullOrEmpty(url))
+ {
+ ExtendedGroupMembershipData membership = m_LocalGroupsConnector.GetAgentGroupMembership(RequestingAgentID, RequestingAgentID, groupID);
+ string accessToken = string.Empty;
+ if (membership != null)
+ accessToken = membership.AccessToken;
+ else
+ return null;
+
+ GroupsServiceHGConnector c = GetConnector(url);
+ if (c != null)
+ {
+ return m_CacheWrapper.GetGroupRoles(RequestingAgentID, groupID, delegate
+ {
+ return c.GetGroupRoles(AgentUUIForOutside(RequestingAgentID), groupID, accessToken);
+ });
+
+ }
+ }
+
+ return new List();
+ }
+
+ public List GetGroupRoleMembers(string RequestingAgentID, UUID groupID)
+ {
+ string url = string.Empty, gname = string.Empty;
+
+ if (IsLocal(groupID, out url, out gname))
+ return m_LocalGroupsConnector.GetGroupRoleMembers(AgentUUI(RequestingAgentID), groupID);
+ else if (!string.IsNullOrEmpty(url))
+ {
+ ExtendedGroupMembershipData membership = m_LocalGroupsConnector.GetAgentGroupMembership(RequestingAgentID, RequestingAgentID, groupID);
+ string accessToken = string.Empty;
+ if (membership != null)
+ accessToken = membership.AccessToken;
+ else
+ return null;
+
+ GroupsServiceHGConnector c = GetConnector(url);
+ if (c != null)
+ {
+ return m_CacheWrapper.GetGroupRoleMembers(RequestingAgentID, groupID, delegate
+ {
+ return c.GetGroupRoleMembers(AgentUUIForOutside(RequestingAgentID), groupID, accessToken);
+ });
+
+ }
+ }
+
+ return new List();
+ }
+
+ public bool AddAgentToGroup(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID, string token, out string reason)
+ {
+ string url = string.Empty;
+ string name = string.Empty;
+ reason = string.Empty;
+
+ UUID uid = new UUID(AgentID);
+ if (IsLocal(GroupID, out url, out name))
+ {
+ if (m_UserManagement.IsLocalGridUser(uid)) // local user
+ {
+ // normal case: local group, local user
+ return m_LocalGroupsConnector.AddAgentToGroup(AgentUUI(RequestingAgentID), AgentUUI(AgentID), GroupID, RoleID, token, out reason);
+ }
+ else // local group, foreign user
+ {
+ // the user is accepting the invitation, or joining, where the group resides
+ token = UUID.Random().ToString();
+ bool success = m_LocalGroupsConnector.AddAgentToGroup(AgentUUI(RequestingAgentID), AgentUUI(AgentID), GroupID, RoleID, token, out reason);
+
+ if (success)
+ {
+ // Here we always return true. The user has been added to the local group,
+ // independent of whether the remote operation succeeds or not
+ url = m_UserManagement.GetUserServerURL(uid, "GroupsServerURI");
+ if (url == string.Empty)
+ {
+ reason = "You don't have an accessible groups server in your home world. You membership to this group in only within this grid.";
+ return true;
+ }
+
+ GroupsServiceHGConnector c = GetConnector(url);
+ if (c != null)
+ c.CreateProxy(AgentUUI(RequestingAgentID), AgentID, token, GroupID, m_LocalGroupsServiceLocation, name, out reason);
+ return true;
+ }
+ return false;
+ }
+ }
+ else if (m_UserManagement.IsLocalGridUser(uid)) // local user
+ {
+ // foreign group, local user. She's been added already by the HG service.
+ // Let's just check
+ if (m_LocalGroupsConnector.GetAgentGroupMembership(AgentUUI(RequestingAgentID), AgentUUI(AgentID), GroupID) != null)
+ return true;
+ }
+
+ reason = "Operation not allowed outside this group's origin world";
+ return false;
+ }
+
+
+ public void RemoveAgentFromGroup(string RequestingAgentID, string AgentID, UUID GroupID)
+ {
+ string url = string.Empty, name = string.Empty;
+ if (!IsLocal(GroupID, out url, out name) && url != string.Empty)
+ {
+ ExtendedGroupMembershipData membership = m_LocalGroupsConnector.GetAgentGroupMembership(AgentUUI(RequestingAgentID), AgentUUI(AgentID), GroupID);
+ if (membership != null)
+ {
+ GroupsServiceHGConnector c = GetConnector(url);
+ if (c != null)
+ c.RemoveAgentFromGroup(AgentUUIForOutside(AgentID), GroupID, membership.AccessToken);
+ }
+ }
+
+ // remove from local service
+ m_LocalGroupsConnector.RemoveAgentFromGroup(AgentUUI(RequestingAgentID), AgentUUI(AgentID), GroupID);
+ }
+
+ public bool AddAgentToGroupInvite(string RequestingAgentID, UUID inviteID, UUID groupID, UUID roleID, string agentID)
+ {
+ string url = string.Empty, gname = string.Empty;
+
+ if (IsLocal(groupID, out url, out gname))
+ return m_LocalGroupsConnector.AddAgentToGroupInvite(AgentUUI(RequestingAgentID), inviteID, groupID, roleID, AgentUUI(agentID));
+ else
+ return false;
+ }
+
+ public GroupInviteInfo GetAgentToGroupInvite(string RequestingAgentID, UUID inviteID)
+ {
+ return m_LocalGroupsConnector.GetAgentToGroupInvite(AgentUUI(RequestingAgentID), inviteID); ;
+ }
+
+ public void RemoveAgentToGroupInvite(string RequestingAgentID, UUID inviteID)
+ {
+ m_LocalGroupsConnector.RemoveAgentToGroupInvite(AgentUUI(RequestingAgentID), inviteID);
+ }
+
+ public void AddAgentToGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID)
+ {
+ string url = string.Empty, gname = string.Empty;
+
+ if (IsLocal(GroupID, out url, out gname))
+ m_LocalGroupsConnector.AddAgentToGroupRole(AgentUUI(RequestingAgentID), AgentUUI(AgentID), GroupID, RoleID);
+
+ }
+
+ public void RemoveAgentFromGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID)
+ {
+ string url = string.Empty, gname = string.Empty;
+
+ if (IsLocal(GroupID, out url, out gname))
+ m_LocalGroupsConnector.RemoveAgentFromGroupRole(AgentUUI(RequestingAgentID), AgentUUI(AgentID), GroupID, RoleID);
+ }
+
+ public List GetAgentGroupRoles(string RequestingAgentID, string AgentID, UUID GroupID)
+ {
+ string url = string.Empty, gname = string.Empty;
+
+ if (IsLocal(GroupID, out url, out gname))
+ return m_LocalGroupsConnector.GetAgentGroupRoles(AgentUUI(RequestingAgentID), AgentUUI(AgentID), GroupID);
+ else
+ return new List();
+ }
+
+ public void SetAgentActiveGroup(string RequestingAgentID, string AgentID, UUID GroupID)
+ {
+ string url = string.Empty, gname = string.Empty;
+
+ if (IsLocal(GroupID, out url, out gname))
+ m_LocalGroupsConnector.SetAgentActiveGroup(AgentUUI(RequestingAgentID), AgentUUI(AgentID), GroupID);
+ }
+
+ public ExtendedGroupMembershipData GetAgentActiveMembership(string RequestingAgentID, string AgentID)
+ {
+ return m_LocalGroupsConnector.GetAgentActiveMembership(AgentUUI(RequestingAgentID), AgentUUI(AgentID));
+ }
+
+ public void SetAgentActiveGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID)
+ {
+ string url = string.Empty, gname = string.Empty;
+
+ if (IsLocal(GroupID, out url, out gname))
+ m_LocalGroupsConnector.SetAgentActiveGroupRole(AgentUUI(RequestingAgentID), AgentUUI(AgentID), GroupID, RoleID);
+ }
+
+ public void UpdateMembership(string RequestingAgentID, string AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile)
+ {
+ m_LocalGroupsConnector.UpdateMembership(AgentUUI(RequestingAgentID), AgentUUI(AgentID), GroupID, AcceptNotices, ListInProfile);
+ }
+
+ public ExtendedGroupMembershipData GetAgentGroupMembership(string RequestingAgentID, string AgentID, UUID GroupID)
+ {
+ string url = string.Empty, gname = string.Empty;
+
+ if (IsLocal(GroupID, out url, out gname))
+ return m_LocalGroupsConnector.GetAgentGroupMembership(AgentUUI(RequestingAgentID), AgentUUI(AgentID), GroupID);
+ else
+ return null;
+ }
+
+ public List GetAgentGroupMemberships(string RequestingAgentID, string AgentID)
+ {
+ return m_LocalGroupsConnector.GetAgentGroupMemberships(AgentUUI(RequestingAgentID), AgentUUI(AgentID));
+ }
+
+ public bool AddGroupNotice(string RequestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message,
+ bool hasAttachment, byte attType, string attName, UUID attItemID, string attOwnerID)
+ {
+ string url = string.Empty, gname = string.Empty;
+
+ if (IsLocal(groupID, out url, out gname))
+ {
+ if (m_LocalGroupsConnector.AddGroupNotice(AgentUUI(RequestingAgentID), groupID, noticeID, fromName, subject, message,
+ hasAttachment, attType, attName, attItemID, AgentUUI(attOwnerID)))
+ {
+ // then send the notice to every grid for which there are members in this group
+ List members = m_LocalGroupsConnector.GetGroupMembers(AgentUUI(RequestingAgentID), groupID);
+ List urls = new List();
+ foreach (GroupMembersData m in members)
+ {
+ if (!m_UserManagement.IsLocalGridUser(m.AgentID))
+ {
+ string gURL = m_UserManagement.GetUserServerURL(m.AgentID, "GroupsServerURI");
+ if (!urls.Contains(gURL))
+ urls.Add(gURL);
+ }
+ }
+
+ // so we have the list of urls to send the notice to
+ // this may take a long time...
+ WorkManager.RunInThread(delegate
+ {
+ foreach (string u in urls)
+ {
+ GroupsServiceHGConnector c = GetConnector(u);
+ if (c != null)
+ {
+ c.AddNotice(AgentUUIForOutside(RequestingAgentID), groupID, noticeID, fromName, subject, message,
+ hasAttachment, attType, attName, attItemID, AgentUUIForOutside(attOwnerID));
+ }
+ }
+ }, null, string.Format("AddGroupNotice (agent {0}, group {1})", RequestingAgentID, groupID));
+
+ return true;
+ }
+
+ return false;
+ }
+ else
+ return false;
+ }
+
+ public GroupNoticeInfo GetGroupNotice(string RequestingAgentID, UUID noticeID)
+ {
+ GroupNoticeInfo notice = m_LocalGroupsConnector.GetGroupNotice(AgentUUI(RequestingAgentID), noticeID);
+
+ if (notice != null && notice.noticeData.HasAttachment && notice.noticeData.AttachmentOwnerID != null)
+ ImportForeigner(notice.noticeData.AttachmentOwnerID);
+
+ return notice;
+ }
+
+ public List GetGroupNotices(string RequestingAgentID, UUID GroupID)
+ {
+ return m_LocalGroupsConnector.GetGroupNotices(AgentUUI(RequestingAgentID), GroupID);
+ }
+
+ #endregion
+
+ #region hypergrid groups
+
+ private string AgentUUI(string AgentIDStr)
+ {
+ UUID AgentID = UUID.Zero;
+ try
+ {
+ AgentID = new UUID(AgentIDStr);
+ }
+ catch (FormatException)
+ {
+ return AgentID.ToString();
+ }
+
+ if (m_UserManagement.IsLocalGridUser(AgentID))
+ return AgentID.ToString();
+
+ AgentCircuitData agent = null;
+ foreach (Scene scene in m_Scenes)
+ {
+ agent = scene.AuthenticateHandler.GetAgentCircuitData(AgentID);
+ if (agent != null)
+ break;
+ }
+ if (agent != null)
+ return Util.ProduceUserUniversalIdentifier(agent);
+
+ // we don't know anything about this foreign user
+ // try asking the user management module, which may know more
+ return m_UserManagement.GetUserUUI(AgentID);
+
+ }
+
+ private string AgentUUIForOutside(string AgentIDStr)
+ {
+ UUID AgentID = UUID.Zero;
+ try
+ {
+ AgentID = new UUID(AgentIDStr);
+ }
+ catch (FormatException)
+ {
+ return AgentID.ToString();
+ }
+
+ AgentCircuitData agent = null;
+ foreach (Scene scene in m_Scenes)
+ {
+ agent = scene.AuthenticateHandler.GetAgentCircuitData(AgentID);
+ if (agent != null)
+ break;
+ }
+ if (agent == null) // oops
+ return AgentID.ToString();
+
+ return Util.ProduceUserUniversalIdentifier(agent);
+ }
+
+ private UUID ImportForeigner(string uID)
+ {
+ UUID userID = UUID.Zero;
+ string url = string.Empty, first = string.Empty, last = string.Empty, tmp = string.Empty;
+ if (Util.ParseUniversalUserIdentifier(uID, out userID, out url, out first, out last, out tmp))
+ m_UserManagement.AddUser(userID, first, last, url);
+
+ return userID;
+ }
+
+ private bool IsLocal(UUID groupID, out string serviceLocation, out string name)
+ {
+ serviceLocation = string.Empty;
+ name = string.Empty;
+ if (groupID.Equals(UUID.Zero))
+ return true;
+
+ ExtendedGroupRecord group = m_LocalGroupsConnector.GetGroupRecord(UUID.Zero.ToString(), groupID, string.Empty);
+ if (group == null)
+ {
+ //m_log.DebugFormat("[XXX]: IsLocal? group {0} not found -- no.", groupID);
+ return false;
+ }
+
+ serviceLocation = group.ServiceLocation;
+ name = group.GroupName;
+ bool isLocal = (group.ServiceLocation == string.Empty);
+ //m_log.DebugFormat("[XXX]: IsLocal? {0}", isLocal);
+ return isLocal;
+ }
+
+ private GroupsServiceHGConnector GetConnector(string url)
+ {
+ lock (m_NetworkConnectors)
+ {
+ if (m_NetworkConnectors.ContainsKey(url))
+ return m_NetworkConnectors[url];
+
+ GroupsServiceHGConnector c = new GroupsServiceHGConnector(url);
+ m_NetworkConnectors[url] = c;
+ }
+
+ return m_NetworkConnectors[url];
+ }
+ #endregion
+ }
+}
diff --git a/OpenSim/Addons/Groups/Hypergrid/HGGroupsServiceRobustConnector.cs b/OpenSim/Addons/Groups/Hypergrid/HGGroupsServiceRobustConnector.cs
new file mode 100644
index 0000000000..f60c1a5f68
--- /dev/null
+++ b/OpenSim/Addons/Groups/Hypergrid/HGGroupsServiceRobustConnector.cs
@@ -0,0 +1,444 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSimulator Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.Reflection;
+using System.Text;
+using System.Xml;
+using System.Collections.Generic;
+using System.IO;
+using Nini.Config;
+using OpenSim.Framework;
+using OpenSim.Server.Base;
+using OpenSim.Services.Interfaces;
+using OpenSim.Framework.Servers.HttpServer;
+using OpenSim.Server.Handlers.Base;
+using log4net;
+using OpenMetaverse;
+
+namespace OpenSim.Groups
+{
+ public class HGGroupsServiceRobustConnector : ServiceConnector
+ {
+ private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+ private HGGroupsService m_GroupsService;
+ private string m_ConfigName = "Groups";
+
+ // Called by Robust shell
+ public HGGroupsServiceRobustConnector(IConfigSource config, IHttpServer server, string configName) :
+ this(config, server, configName, null, null)
+ {
+ }
+
+ // Called by the sim-bound module
+ public HGGroupsServiceRobustConnector(IConfigSource config, IHttpServer server, string configName, IOfflineIMService im, IUserAccountService users) :
+ base(config, server, configName)
+ {
+ if (configName != String.Empty)
+ m_ConfigName = configName;
+
+ m_log.DebugFormat("[Groups.RobustHGConnector]: Starting with config name {0}", m_ConfigName);
+
+ string homeURI = Util.GetConfigVarFromSections(config, "HomeURI",
+ new string[] { "Startup", "Hypergrid", m_ConfigName}, string.Empty);
+ if (homeURI == string.Empty)
+ throw new Exception(String.Format("[Groups.RobustHGConnector]: please provide the HomeURI [Startup] or in section {0}", m_ConfigName));
+
+ IConfig cnf = config.Configs[m_ConfigName];
+ if (cnf == null)
+ throw new Exception(String.Format("[Groups.RobustHGConnector]: {0} section does not exist", m_ConfigName));
+
+ if (im == null)
+ {
+ string imDll = cnf.GetString("OfflineIMService", string.Empty);
+ if (imDll == string.Empty)
+ throw new Exception(String.Format("[Groups.RobustHGConnector]: please provide OfflineIMService in section {0}", m_ConfigName));
+
+ Object[] args = new Object[] { config };
+ im = ServerUtils.LoadPlugin(imDll, args);
+ }
+
+ if (users == null)
+ {
+ string usersDll = cnf.GetString("UserAccountService", string.Empty);
+ if (usersDll == string.Empty)
+ throw new Exception(String.Format("[Groups.RobustHGConnector]: please provide UserAccountService in section {0}", m_ConfigName));
+
+ Object[] args = new Object[] { config };
+ users = ServerUtils.LoadPlugin(usersDll, args);
+ }
+
+ m_GroupsService = new HGGroupsService(config, im, users, homeURI);
+
+ server.AddStreamHandler(new HGGroupsServicePostHandler(m_GroupsService));
+ }
+
+ }
+
+ public class HGGroupsServicePostHandler : BaseStreamHandler
+ {
+ private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+ private HGGroupsService m_GroupsService;
+
+ public HGGroupsServicePostHandler(HGGroupsService service) :
+ base("POST", "/hg-groups")
+ {
+ m_GroupsService = service;
+ }
+
+ protected override byte[] ProcessRequest(string path, Stream requestData,
+ IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
+ {
+ StreamReader sr = new StreamReader(requestData);
+ string body = sr.ReadToEnd();
+ sr.Close();
+ body = body.Trim();
+
+ //m_log.DebugFormat("[XXX]: query String: {0}", body);
+
+ try
+ {
+ Dictionary request =
+ ServerUtils.ParseQueryString(body);
+
+ if (!request.ContainsKey("METHOD"))
+ return FailureResult();
+
+ string method = request["METHOD"].ToString();
+ request.Remove("METHOD");
+
+ m_log.DebugFormat("[Groups.RobustHGConnector]: {0}", method);
+ switch (method)
+ {
+ case "POSTGROUP":
+ return HandleAddGroupProxy(request);
+ case "REMOVEAGENTFROMGROUP":
+ return HandleRemoveAgentFromGroup(request);
+ case "GETGROUP":
+ return HandleGetGroup(request);
+ case "ADDNOTICE":
+ return HandleAddNotice(request);
+ case "VERIFYNOTICE":
+ return HandleVerifyNotice(request);
+ case "GETGROUPMEMBERS":
+ return HandleGetGroupMembers(request);
+ case "GETGROUPROLES":
+ return HandleGetGroupRoles(request);
+ case "GETROLEMEMBERS":
+ return HandleGetRoleMembers(request);
+
+ }
+ m_log.DebugFormat("[Groups.RobustHGConnector]: unknown method request: {0}", method);
+ }
+ catch (Exception e)
+ {
+ m_log.Error(string.Format("[Groups.RobustHGConnector]: Exception {0} ", e.Message), e);
+ }
+
+ return FailureResult();
+ }
+
+ byte[] HandleAddGroupProxy(Dictionary request)
+ {
+ Dictionary result = new Dictionary();
+
+ if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("GroupID")
+ || !request.ContainsKey("AgentID")
+ || !request.ContainsKey("AccessToken") || !request.ContainsKey("Location"))
+ NullResult(result, "Bad network data");
+
+ else
+ {
+ string RequestingAgentID = request["RequestingAgentID"].ToString();
+ string agentID = request["AgentID"].ToString();
+ UUID groupID = new UUID(request["GroupID"].ToString());
+ string accessToken = request["AccessToken"].ToString();
+ string location = request["Location"].ToString();
+ string name = string.Empty;
+ if (request.ContainsKey("Name"))
+ name = request["Name"].ToString();
+
+ string reason = string.Empty;
+ bool success = m_GroupsService.CreateGroupProxy(RequestingAgentID, agentID, accessToken, groupID, location, name, out reason);
+ result["REASON"] = reason;
+ result["RESULT"] = success.ToString();
+ }
+
+ string xmlString = ServerUtils.BuildXmlResponse(result);
+
+ //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
+ return Util.UTF8NoBomEncoding.GetBytes(xmlString);
+ }
+
+ byte[] HandleRemoveAgentFromGroup(Dictionary request)
+ {
+ Dictionary result = new Dictionary();
+
+ if (!request.ContainsKey("AccessToken") || !request.ContainsKey("AgentID") ||
+ !request.ContainsKey("GroupID"))
+ NullResult(result, "Bad network data");
+ else
+ {
+ UUID groupID = new UUID(request["GroupID"].ToString());
+ string agentID = request["AgentID"].ToString();
+ string token = request["AccessToken"].ToString();
+
+ if (!m_GroupsService.RemoveAgentFromGroup(agentID, agentID, groupID, token))
+ NullResult(result, "Internal error");
+ else
+ result["RESULT"] = "true";
+ }
+
+ //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
+ return Util.UTF8NoBomEncoding.GetBytes(ServerUtils.BuildXmlResponse(result));
+ }
+
+ byte[] HandleGetGroup(Dictionary request)
+ {
+ Dictionary result = new Dictionary();
+
+ if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("AccessToken"))
+ NullResult(result, "Bad network data");
+ else
+ {
+ string RequestingAgentID = request["RequestingAgentID"].ToString();
+ string token = request["AccessToken"].ToString();
+
+ UUID groupID = UUID.Zero;
+ string groupName = string.Empty;
+
+ if (request.ContainsKey("GroupID"))
+ groupID = new UUID(request["GroupID"].ToString());
+ if (request.ContainsKey("Name"))
+ groupName = request["Name"].ToString();
+
+ ExtendedGroupRecord grec = m_GroupsService.GetGroupRecord(RequestingAgentID, groupID, groupName, token);
+ if (grec == null)
+ NullResult(result, "Group not found");
+ else
+ result["RESULT"] = GroupsDataUtils.GroupRecord(grec);
+ }
+
+ string xmlString = ServerUtils.BuildXmlResponse(result);
+
+ //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
+ return Util.UTF8NoBomEncoding.GetBytes(xmlString);
+ }
+
+ byte[] HandleGetGroupMembers(Dictionary request)
+ {
+ Dictionary result = new Dictionary();
+
+ if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("GroupID") || !request.ContainsKey("AccessToken"))
+ NullResult(result, "Bad network data");
+ else
+ {
+ UUID groupID = new UUID(request["GroupID"].ToString());
+ string requestingAgentID = request["RequestingAgentID"].ToString();
+ string token = request["AccessToken"].ToString();
+
+ List members = m_GroupsService.GetGroupMembers(requestingAgentID, groupID, token);
+ if (members == null || (members != null && members.Count == 0))
+ {
+ NullResult(result, "No members");
+ }
+ else
+ {
+ Dictionary dict = new Dictionary();
+ int i = 0;
+ foreach (ExtendedGroupMembersData m in members)
+ {
+ dict["m-" + i++] = GroupsDataUtils.GroupMembersData(m);
+ }
+
+ result["RESULT"] = dict;
+ }
+ }
+
+ string xmlString = ServerUtils.BuildXmlResponse(result);
+
+ //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
+ return Util.UTF8NoBomEncoding.GetBytes(xmlString);
+ }
+
+ byte[] HandleGetGroupRoles(Dictionary request)
+ {
+ Dictionary result = new Dictionary();
+
+ if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("GroupID") || !request.ContainsKey("AccessToken"))
+ NullResult(result, "Bad network data");
+ else
+ {
+ UUID groupID = new UUID(request["GroupID"].ToString());
+ string requestingAgentID = request["RequestingAgentID"].ToString();
+ string token = request["AccessToken"].ToString();
+
+ List roles = m_GroupsService.GetGroupRoles(requestingAgentID, groupID, token);
+ if (roles == null || (roles != null && roles.Count == 0))
+ {
+ NullResult(result, "No members");
+ }
+ else
+ {
+ Dictionary dict = new Dictionary();
+ int i = 0;
+ foreach (GroupRolesData r in roles)
+ dict["r-" + i++] = GroupsDataUtils.GroupRolesData(r);
+
+ result["RESULT"] = dict;
+ }
+ }
+
+ string xmlString = ServerUtils.BuildXmlResponse(result);
+
+ //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
+ return Util.UTF8NoBomEncoding.GetBytes(xmlString);
+ }
+
+ byte[] HandleGetRoleMembers(Dictionary request)
+ {
+ Dictionary result = new Dictionary();
+
+ if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("GroupID") || !request.ContainsKey("AccessToken"))
+ NullResult(result, "Bad network data");
+ else
+ {
+ UUID groupID = new UUID(request["GroupID"].ToString());
+ string requestingAgentID = request["RequestingAgentID"].ToString();
+ string token = request["AccessToken"].ToString();
+
+ List rmembers = m_GroupsService.GetGroupRoleMembers(requestingAgentID, groupID, token);
+ if (rmembers == null || (rmembers != null && rmembers.Count == 0))
+ {
+ NullResult(result, "No members");
+ }
+ else
+ {
+ Dictionary dict = new Dictionary();
+ int i = 0;
+ foreach (ExtendedGroupRoleMembersData rm in rmembers)
+ dict["rm-" + i++] = GroupsDataUtils.GroupRoleMembersData(rm);
+
+ result["RESULT"] = dict;
+ }
+ }
+
+ string xmlString = ServerUtils.BuildXmlResponse(result);
+
+ //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
+ return Util.UTF8NoBomEncoding.GetBytes(xmlString);
+ }
+
+ byte[] HandleAddNotice(Dictionary request)
+ {
+ Dictionary result = new Dictionary();
+
+ if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("GroupID") || !request.ContainsKey("NoticeID") ||
+ !request.ContainsKey("FromName") || !request.ContainsKey("Subject") || !request.ContainsKey("Message") ||
+ !request.ContainsKey("HasAttachment"))
+ NullResult(result, "Bad network data");
+
+ else
+ {
+
+ bool hasAtt = bool.Parse(request["HasAttachment"].ToString());
+ byte attType = 0;
+ string attName = string.Empty;
+ string attOwner = string.Empty;
+ UUID attItem = UUID.Zero;
+ if (request.ContainsKey("AttachmentType"))
+ attType = byte.Parse(request["AttachmentType"].ToString());
+ if (request.ContainsKey("AttachmentName"))
+ attName = request["AttachmentType"].ToString();
+ if (request.ContainsKey("AttachmentItemID"))
+ attItem = new UUID(request["AttachmentItemID"].ToString());
+ if (request.ContainsKey("AttachmentOwnerID"))
+ attOwner = request["AttachmentOwnerID"].ToString();
+
+ bool success = m_GroupsService.AddNotice(request["RequestingAgentID"].ToString(), new UUID(request["GroupID"].ToString()),
+ new UUID(request["NoticeID"].ToString()), request["FromName"].ToString(), request["Subject"].ToString(),
+ request["Message"].ToString(), hasAtt, attType, attName, attItem, attOwner);
+
+ result["RESULT"] = success.ToString();
+ }
+
+ string xmlString = ServerUtils.BuildXmlResponse(result);
+
+ //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
+ return Util.UTF8NoBomEncoding.GetBytes(xmlString);
+ }
+
+ byte[] HandleVerifyNotice(Dictionary request)
+ {
+ Dictionary result = new Dictionary();
+
+ if (!request.ContainsKey("NoticeID") || !request.ContainsKey("GroupID"))
+ NullResult(result, "Bad network data");
+
+ else
+ {
+ UUID noticeID = new UUID(request["NoticeID"].ToString());
+ UUID groupID = new UUID(request["GroupID"].ToString());
+
+ bool success = m_GroupsService.VerifyNotice(noticeID, groupID);
+ //m_log.DebugFormat("[XXX]: VerifyNotice returned {0}", success);
+ result["RESULT"] = success.ToString();
+ }
+
+ string xmlString = ServerUtils.BuildXmlResponse(result);
+
+ //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
+ return Util.UTF8NoBomEncoding.GetBytes(xmlString);
+ }
+
+ //
+ //
+ //
+ //
+ //
+
+ #region Helpers
+
+ private void NullResult(Dictionary result, string reason)
+ {
+ result["RESULT"] = "NULL";
+ result["REASON"] = reason;
+ }
+
+ private byte[] FailureResult()
+ {
+ Dictionary result = new Dictionary();
+ NullResult(result, "Unknown method");
+ string xmlString = ServerUtils.BuildXmlResponse(result);
+ return Util.UTF8NoBomEncoding.GetBytes(xmlString);
+ }
+
+ #endregion
+ }
+}
diff --git a/OpenSim/Addons/Groups/IGroupsServicesConnector.cs b/OpenSim/Addons/Groups/IGroupsServicesConnector.cs
new file mode 100644
index 0000000000..a09b59e238
--- /dev/null
+++ b/OpenSim/Addons/Groups/IGroupsServicesConnector.cs
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSimulator Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.Collections.Generic;
+using OpenMetaverse;
+using OpenSim.Framework;
+
+namespace OpenSim.Groups
+{
+ public interface IGroupsServicesConnector
+ {
+ UUID CreateGroup(UUID RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee,
+ bool openEnrollment, bool allowPublish, bool maturePublish, UUID founderID, out string reason);
+ bool UpdateGroup(string RequestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee,
+ bool openEnrollment, bool allowPublish, bool maturePublish, out string reason);
+ ExtendedGroupRecord GetGroupRecord(string RequestingAgentID, UUID GroupID, string GroupName);
+ List FindGroups(string RequestingAgentID, string search);
+ List GetGroupMembers(string RequestingAgentID, UUID GroupID);
+
+ bool AddGroupRole(string RequestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers, out string reason);
+ bool UpdateGroupRole(string RequestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers);
+ void RemoveGroupRole(string RequestingAgentID, UUID groupID, UUID roleID);
+ List GetGroupRoles(string RequestingAgentID, UUID GroupID);
+ List GetGroupRoleMembers(string RequestingAgentID, UUID GroupID);
+
+ bool AddAgentToGroup(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID, string token, out string reason);
+ void RemoveAgentFromGroup(string RequestingAgentID, string AgentID, UUID GroupID);
+
+ bool AddAgentToGroupInvite(string RequestingAgentID, UUID inviteID, UUID groupID, UUID roleID, string agentID);
+ GroupInviteInfo GetAgentToGroupInvite(string RequestingAgentID, UUID inviteID);
+ void RemoveAgentToGroupInvite(string RequestingAgentID, UUID inviteID);
+
+ void AddAgentToGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID);
+ void RemoveAgentFromGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID);
+ List GetAgentGroupRoles(string RequestingAgentID, string AgentID, UUID GroupID);
+
+ void SetAgentActiveGroup(string RequestingAgentID, string AgentID, UUID GroupID);
+ ExtendedGroupMembershipData GetAgentActiveMembership(string RequestingAgentID, string AgentID);
+
+ void SetAgentActiveGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID);
+ void UpdateMembership(string RequestingAgentID, string AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile);
+
+ ///
+ /// Get information about a specific group to which the user belongs.
+ ///
+ /// The agent requesting the information.
+ /// The agent requested.
+ /// The group requested.
+ ///
+ /// If the user is a member of the group then the data structure is returned. If not, then null is returned.
+ ///
+ ExtendedGroupMembershipData GetAgentGroupMembership(string RequestingAgentID, string AgentID, UUID GroupID);
+
+ ///
+ /// Get information about the groups to which a user belongs.
+ ///
+ /// The agent requesting the information.
+ /// The agent requested.
+ ///
+ /// Information about the groups to which the user belongs. If the user belongs to no groups then an empty
+ /// list is returned.
+ ///
+ List GetAgentGroupMemberships(string RequestingAgentID, string AgentID);
+
+ bool AddGroupNotice(string RequestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message,
+ bool hasAttachment, byte attType, string attName, UUID attItemID, string attOwnerID);
+ GroupNoticeInfo GetGroupNotice(string RequestingAgentID, UUID noticeID);
+ List GetGroupNotices(string RequestingAgentID, UUID GroupID);
+
+ }
+
+ public class GroupInviteInfo
+ {
+ public UUID GroupID = UUID.Zero;
+ public UUID RoleID = UUID.Zero;
+ public string AgentID = string.Empty;
+ public UUID InviteID = UUID.Zero;
+ }
+
+ public class GroupNoticeInfo
+ {
+ public ExtendedGroupNoticeData noticeData = new ExtendedGroupNoticeData();
+ public UUID GroupID = UUID.Zero;
+ public string Message = string.Empty;
+ }
+
+}
diff --git a/OpenSim/Addons/Groups/Local/GroupsServiceLocalConnectorModule.cs b/OpenSim/Addons/Groups/Local/GroupsServiceLocalConnectorModule.cs
new file mode 100644
index 0000000000..8e30df5755
--- /dev/null
+++ b/OpenSim/Addons/Groups/Local/GroupsServiceLocalConnectorModule.cs
@@ -0,0 +1,326 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSimulator Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+
+using OpenSim.Framework;
+using OpenSim.Region.Framework.Scenes;
+using OpenSim.Region.Framework.Interfaces;
+using OpenSim.Services.Interfaces;
+
+using OpenMetaverse;
+using Mono.Addins;
+using log4net;
+using Nini.Config;
+
+namespace OpenSim.Groups
+{
+ [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GroupsServiceLocalConnectorModule")]
+ public class GroupsServiceLocalConnectorModule : ISharedRegionModule, IGroupsServicesConnector
+ {
+ private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+ private bool m_Enabled = false;
+ private GroupsService m_GroupsService;
+ private IUserManagement m_UserManagement;
+ private List m_Scenes;
+ private ForeignImporter m_ForeignImporter;
+
+ #region constructors
+ public GroupsServiceLocalConnectorModule()
+ {
+ }
+
+ public GroupsServiceLocalConnectorModule(IConfigSource config, IUserManagement uman)
+ {
+ Init(config);
+ m_UserManagement = uman;
+ m_ForeignImporter = new ForeignImporter(uman);
+ }
+ #endregion
+
+ private void Init(IConfigSource config)
+ {
+ m_GroupsService = new GroupsService(config);
+ m_Scenes = new List();
+ }
+
+ #region ISharedRegionModule
+
+ public void Initialise(IConfigSource config)
+ {
+ IConfig groupsConfig = config.Configs["Groups"];
+ if (groupsConfig == null)
+ return;
+
+ if ((groupsConfig.GetBoolean("Enabled", false) == false)
+ || (groupsConfig.GetString("ServicesConnectorModule", string.Empty) != Name))
+ {
+ return;
+ }
+
+ Init(config);
+ m_Enabled = true;
+
+ m_log.DebugFormat("[Groups]: Initializing {0}", this.Name);
+ }
+
+ public string Name
+ {
+ get { return "Groups Local Service Connector"; }
+ }
+
+ public Type ReplaceableInterface
+ {
+ get { return null; }
+ }
+
+ public void AddRegion(Scene scene)
+ {
+ if (!m_Enabled)
+ return;
+
+ m_log.DebugFormat("[Groups]: Registering {0} with {1}", this.Name, scene.RegionInfo.RegionName);
+ scene.RegisterModuleInterface(this);
+ m_Scenes.Add(scene);
+ }
+
+ public void RemoveRegion(Scene scene)
+ {
+ if (!m_Enabled)
+ return;
+
+ scene.UnregisterModuleInterface(this);
+ m_Scenes.Remove(scene);
+ }
+
+ public void RegionLoaded(Scene scene)
+ {
+ if (!m_Enabled)
+ return;
+
+ if (m_UserManagement == null)
+ {
+ m_UserManagement = scene.RequestModuleInterface();
+ m_ForeignImporter = new ForeignImporter(m_UserManagement);
+ }
+ }
+
+ public void PostInitialise()
+ {
+ }
+
+ public void Close()
+ {
+ }
+
+ #endregion
+
+ #region IGroupsServicesConnector
+
+ public UUID CreateGroup(UUID RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment,
+ bool allowPublish, bool maturePublish, UUID founderID, out string reason)
+ {
+ m_log.DebugFormat("[Groups]: Creating group {0}", name);
+ reason = string.Empty;
+ return m_GroupsService.CreateGroup(RequestingAgentID.ToString(), name, charter, showInList, insigniaID,
+ membershipFee, openEnrollment, allowPublish, maturePublish, founderID, out reason);
+ }
+
+ public bool UpdateGroup(string RequestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee,
+ bool openEnrollment, bool allowPublish, bool maturePublish, out string reason)
+ {
+ reason = string.Empty;
+ m_GroupsService.UpdateGroup(RequestingAgentID, groupID, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish);
+ return true;
+ }
+
+ public ExtendedGroupRecord GetGroupRecord(string RequestingAgentID, UUID GroupID, string GroupName)
+ {
+ if (GroupID != UUID.Zero)
+ return m_GroupsService.GetGroupRecord(RequestingAgentID, GroupID);
+ else if (GroupName != null)
+ return m_GroupsService.GetGroupRecord(RequestingAgentID, GroupName);
+
+ return null;
+ }
+
+ public List FindGroups(string RequestingAgentID, string search)
+ {
+ return m_GroupsService.FindGroups(RequestingAgentID, search);
+ }
+
+ public List GetGroupMembers(string RequestingAgentID, UUID GroupID)
+ {
+ List _members = m_GroupsService.GetGroupMembers(RequestingAgentID, GroupID);
+ if (_members != null && _members.Count > 0)
+ {
+ List members = _members.ConvertAll(new Converter(m_ForeignImporter.ConvertGroupMembersData));
+ return members;
+ }
+
+ return new List();
+ }
+
+ public bool AddGroupRole(string RequestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers, out string reason)
+ {
+ return m_GroupsService.AddGroupRole(RequestingAgentID, groupID, roleID, name, description, title, powers, out reason);
+ }
+
+ public bool UpdateGroupRole(string RequestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers)
+ {
+ return m_GroupsService.UpdateGroupRole(RequestingAgentID, groupID, roleID, name, description, title, powers);
+ }
+
+ public void RemoveGroupRole(string RequestingAgentID, UUID groupID, UUID roleID)
+ {
+ m_GroupsService.RemoveGroupRole(RequestingAgentID, groupID, roleID);
+ }
+
+ public List GetGroupRoles(string RequestingAgentID, UUID GroupID)
+ {
+ return m_GroupsService.GetGroupRoles(RequestingAgentID, GroupID);
+ }
+
+ public List GetGroupRoleMembers(string RequestingAgentID, UUID GroupID)
+ {
+ List _rm = m_GroupsService.GetGroupRoleMembers(RequestingAgentID, GroupID);
+ if (_rm != null && _rm.Count > 0)
+ {
+ List rm = _rm.ConvertAll(new Converter(m_ForeignImporter.ConvertGroupRoleMembersData));
+ return rm;
+ }
+
+ return new List();
+
+ }
+
+ public bool AddAgentToGroup(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID, string token, out string reason)
+ {
+ return m_GroupsService.AddAgentToGroup(RequestingAgentID, AgentID, GroupID, RoleID, token, out reason);
+ }
+
+ public void RemoveAgentFromGroup(string RequestingAgentID, string AgentID, UUID GroupID)
+ {
+ m_GroupsService.RemoveAgentFromGroup(RequestingAgentID, AgentID, GroupID);
+ }
+
+ public bool AddAgentToGroupInvite(string RequestingAgentID, UUID inviteID, UUID groupID, UUID roleID, string agentID)
+ {
+ return m_GroupsService.AddAgentToGroupInvite(RequestingAgentID, inviteID, groupID, roleID, agentID);
+ }
+
+ public GroupInviteInfo GetAgentToGroupInvite(string RequestingAgentID, UUID inviteID)
+ {
+ return m_GroupsService.GetAgentToGroupInvite(RequestingAgentID, inviteID); ;
+ }
+
+ public void RemoveAgentToGroupInvite(string RequestingAgentID, UUID inviteID)
+ {
+ m_GroupsService.RemoveAgentToGroupInvite(RequestingAgentID, inviteID);
+ }
+
+ public void AddAgentToGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID)
+ {
+ m_GroupsService.AddAgentToGroupRole(RequestingAgentID, AgentID, GroupID, RoleID);
+ }
+
+ public void RemoveAgentFromGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID)
+ {
+ m_GroupsService.RemoveAgentFromGroupRole(RequestingAgentID, AgentID, GroupID, RoleID);
+ }
+
+ public List GetAgentGroupRoles(string RequestingAgentID, string AgentID, UUID GroupID)
+ {
+ return m_GroupsService.GetAgentGroupRoles(RequestingAgentID, AgentID, GroupID);
+ }
+
+ public void SetAgentActiveGroup(string RequestingAgentID, string AgentID, UUID GroupID)
+ {
+ m_GroupsService.SetAgentActiveGroup(RequestingAgentID, AgentID, GroupID);
+ }
+
+ public ExtendedGroupMembershipData GetAgentActiveMembership(string RequestingAgentID, string AgentID)
+ {
+ return m_GroupsService.GetAgentActiveMembership(RequestingAgentID, AgentID);
+ }
+
+ public void SetAgentActiveGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID)
+ {
+ m_GroupsService.SetAgentActiveGroupRole(RequestingAgentID, AgentID, GroupID, RoleID);
+ }
+
+ public void UpdateMembership(string RequestingAgentID, string AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile)
+ {
+ m_GroupsService.UpdateMembership(RequestingAgentID, AgentID, GroupID, AcceptNotices, ListInProfile);
+ }
+
+ public ExtendedGroupMembershipData GetAgentGroupMembership(string RequestingAgentID, string AgentID, UUID GroupID)
+ {
+ return m_GroupsService.GetAgentGroupMembership(RequestingAgentID, AgentID, GroupID); ;
+ }
+
+ public List GetAgentGroupMemberships(string RequestingAgentID, string AgentID)
+ {
+ return m_GroupsService.GetAgentGroupMemberships(RequestingAgentID, AgentID);
+ }
+
+ public bool AddGroupNotice(string RequestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message,
+ bool hasAttachment, byte attType, string attName, UUID attItemID, string attOwnerID)
+ {
+ return m_GroupsService.AddGroupNotice(RequestingAgentID, groupID, noticeID, fromName, subject, message,
+ hasAttachment, attType, attName, attItemID, attOwnerID);
+ }
+
+ public GroupNoticeInfo GetGroupNotice(string RequestingAgentID, UUID noticeID)
+ {
+ GroupNoticeInfo notice = m_GroupsService.GetGroupNotice(RequestingAgentID, noticeID);
+
+ //if (notice != null && notice.noticeData.HasAttachment && notice.noticeData.AttachmentOwnerID != null)
+ //{
+ // UUID userID = UUID.Zero;
+ // string url = string.Empty, first = string.Empty, last = string.Empty, tmp = string.Empty;
+ // Util.ParseUniversalUserIdentifier(notice.noticeData.AttachmentOwnerID, out userID, out url, out first, out last, out tmp);
+ // if (url != string.Empty)
+ // m_UserManagement.AddUser(userID, first, last, url);
+ //}
+
+ return notice;
+ }
+
+ public List GetGroupNotices(string RequestingAgentID, UUID GroupID)
+ {
+ return m_GroupsService.GetGroupNotices(RequestingAgentID, GroupID);
+ }
+
+ #endregion
+ }
+}
diff --git a/OpenSim/Addons/Groups/Properties/AssemblyInfo.cs b/OpenSim/Addons/Groups/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..0a7fb5f754
--- /dev/null
+++ b/OpenSim/Addons/Groups/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using Mono.Addins;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("OpenSim.Addons.Groups")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("http://opensimulator.org")]
+[assembly: AssemblyProduct("OpenSim.Addons.Groups")]
+[assembly: AssemblyCopyright("Copyright (c) OpenSimulator.org Developers")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("313d4865-d179-4735-9b5a-fe74885878b2")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+[assembly: AssemblyVersion("0.8.2.*")]
+
+[assembly: Addin("OpenSim.Groups", OpenSim.VersionInfo.VersionNumber)]
+[assembly: AddinDependency("OpenSim.Region.Framework", OpenSim.VersionInfo.VersionNumber)]
diff --git a/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnector.cs b/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnector.cs
new file mode 100644
index 0000000000..7450c1442e
--- /dev/null
+++ b/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnector.cs
@@ -0,0 +1,696 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSimulator Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+
+using OpenSim.Framework;
+using OpenSim.Framework.ServiceAuth;
+using OpenSim.Server.Base;
+
+using OpenMetaverse;
+using log4net;
+using Nini.Config;
+
+namespace OpenSim.Groups
+{
+ public class GroupsServiceRemoteConnector
+ {
+ private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+ private string m_ServerURI;
+ private IServiceAuth m_Auth;
+ private object m_Lock = new object();
+
+ public GroupsServiceRemoteConnector(IConfigSource config)
+ {
+ IConfig groupsConfig = config.Configs["Groups"];
+ string url = groupsConfig.GetString("GroupsServerURI", string.Empty);
+ if (!Uri.IsWellFormedUriString(url, UriKind.Absolute))
+ throw new Exception(string.Format("[Groups.RemoteConnector]: Malformed groups server URL {0}. Fix it or disable the Groups feature.", url));
+
+ m_ServerURI = url;
+ if (!m_ServerURI.EndsWith("/"))
+ m_ServerURI += "/";
+
+ /// This is from BaseServiceConnector
+ string authType = Util.GetConfigVarFromSections(config, "AuthType", new string[] { "Network", "Groups" }, "None");
+
+ switch (authType)
+ {
+ case "BasicHttpAuthentication":
+ m_Auth = new BasicHttpAuthentication(config, "Groups");
+ break;
+ }
+ ///
+
+ m_log.DebugFormat("[Groups.RemoteConnector]: Groups server at {0}, authentication {1}",
+ m_ServerURI, (m_Auth == null ? "None" : m_Auth.GetType().ToString()));
+ }
+
+ public ExtendedGroupRecord CreateGroup(string RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment,
+ bool allowPublish, bool maturePublish, UUID founderID, out string reason)
+ {
+ reason = string.Empty;
+
+ ExtendedGroupRecord rec = new ExtendedGroupRecord();
+ rec.AllowPublish = allowPublish;
+ rec.Charter = charter;
+ rec.FounderID = founderID;
+ rec.GroupName = name;
+ rec.GroupPicture = insigniaID;
+ rec.MaturePublish = maturePublish;
+ rec.MembershipFee = membershipFee;
+ rec.OpenEnrollment = openEnrollment;
+ rec.ShowInList = showInList;
+
+ Dictionary sendData = GroupsDataUtils.GroupRecord(rec);
+ sendData["RequestingAgentID"] = RequestingAgentID;
+ sendData["OP"] = "ADD";
+ Dictionary ret = MakeRequest("PUTGROUP", sendData);
+
+ if (ret == null)
+ return null;
+
+ if (ret["RESULT"].ToString() == "NULL")
+ {
+ reason = ret["REASON"].ToString();
+ return null;
+ }
+
+ return GroupsDataUtils.GroupRecord((Dictionary)ret["RESULT"]);
+
+ }
+
+ public ExtendedGroupRecord UpdateGroup(string RequestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish)
+ {
+ ExtendedGroupRecord rec = new ExtendedGroupRecord();
+ rec.AllowPublish = allowPublish;
+ rec.Charter = charter;
+ rec.GroupPicture = insigniaID;
+ rec.MaturePublish = maturePublish;
+ rec.GroupID = groupID;
+ rec.MembershipFee = membershipFee;
+ rec.OpenEnrollment = openEnrollment;
+ rec.ShowInList = showInList;
+
+ Dictionary sendData = GroupsDataUtils.GroupRecord(rec);
+ sendData["RequestingAgentID"] = RequestingAgentID;
+ sendData["OP"] = "UPDATE";
+ Dictionary ret = MakeRequest("PUTGROUP", sendData);
+
+ if (ret == null || (ret != null && (!ret.ContainsKey("RESULT") || ret["RESULT"].ToString() == "NULL")))
+ return null;
+
+ return GroupsDataUtils.GroupRecord((Dictionary)ret["RESULT"]);
+ }
+
+ public ExtendedGroupRecord GetGroupRecord(string RequestingAgentID, UUID GroupID, string GroupName)
+ {
+ if (GroupID == UUID.Zero && (GroupName == null || (GroupName != null && GroupName == string.Empty)))
+ return null;
+
+ Dictionary sendData = new Dictionary();
+ if (GroupID != UUID.Zero)
+ sendData["GroupID"] = GroupID.ToString();
+ if (!string.IsNullOrEmpty(GroupName))
+ sendData["Name"] = GroupsDataUtils.Sanitize(GroupName);
+
+ sendData["RequestingAgentID"] = RequestingAgentID;
+
+ Dictionary ret = MakeRequest("GETGROUP", sendData);
+
+ if (ret == null || (ret != null && (!ret.ContainsKey("RESULT") || ret["RESULT"].ToString() == "NULL")))
+ return null;
+
+ return GroupsDataUtils.GroupRecord((Dictionary)ret["RESULT"]);
+ }
+
+ public List FindGroups(string RequestingAgentID, string query)
+ {
+ List hits = new List();
+ if (string.IsNullOrEmpty(query))
+ return hits;
+
+ Dictionary sendData = new Dictionary();
+ sendData["Query"] = query;
+ sendData["RequestingAgentID"] = RequestingAgentID;
+
+ Dictionary ret = MakeRequest("FINDGROUPS", sendData);
+
+ if (ret == null)
+ return hits;
+
+ if (!ret.ContainsKey("RESULT"))
+ return hits;
+
+ if (ret["RESULT"].ToString() == "NULL")
+ return hits;
+
+ foreach (object v in ((Dictionary)ret["RESULT"]).Values)
+ {
+ DirGroupsReplyData m = GroupsDataUtils.DirGroupsReplyData((Dictionary)v);
+ hits.Add(m);
+ }
+
+ return hits;
+ }
+
+ public GroupMembershipData AddAgentToGroup(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID, string token, out string reason)
+ {
+ reason = string.Empty;
+
+ Dictionary sendData = new Dictionary